#include "config.h"
#include <signal.h>
#include <setjmp.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include "lisp.h"
#ifdef HAVE_RANDOM
#if 0
extern long int random P_ ((void));
#endif
#if 0
extern void srandom P_ ((unsigned int));
#endif
#endif
#include "blockinput.h"
#undef NULL
#ifdef macintosh
#include <stdlib.h>
#ifndef subprocesses
static int delete_exited_processes;
#endif
#endif
#define min(x,y) ((x) > (y) ? (y) : (x))
#ifdef WINDOWSNT
#define read sys_read
#define write sys_write
#include <windows.h>
#ifndef NULL
#define NULL 0
#endif
#endif
#ifndef fwrite
#define sys_fwrite fwrite
#else
#undef fwrite
#endif
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#ifdef HAVE_SETPGID
#if !defined (USG) || defined (BSD_PGRPS)
#undef setpgrp
#define setpgrp setpgid
#endif
#endif
#ifdef HAVE_SYS_SYSTEMINFO_H
#include <sys/systeminfo.h>
#endif
#ifdef MSDOS
#include <dos.h>
#include "dosfns.h"
#include "msdos.h"
#include <sys/param.h>
#if __DJGPP__ > 1
extern int etext;
extern unsigned start __asm__ ("start");
#endif
#endif
#ifndef USE_CRT_DLL
#ifndef errno
extern int errno;
#endif
#endif
#ifdef VMS
#include <rms.h>
#include <ttdef.h>
#include <tt2def.h>
#include <iodef.h>
#include <ssdef.h>
#include <descrip.h>
#include <fibdef.h>
#include <atrdef.h>
#include <ctype.h>
#include <string.h>
#ifdef __GNUC__
#include <sys/file.h>
#else
#include <file.h>
#endif
#undef F_SETFL
#ifndef RAB$C_BID
#include <rab.h>
#endif
#define MAXIOSIZE (32 * PAGESIZE)
#endif
#ifndef BSD4_1
#ifdef BSD_SYSTEM
#include <fcntl.h>
#endif
#ifdef USG
#ifndef USG5
#include <fcntl.h>
#endif
#endif
#endif
#ifndef MSDOS
#include <sys/ioctl.h>
#endif
#include "systty.h"
#include "syswait.h"
#ifdef BROKEN_TIOCGWINSZ
#undef TIOCGWINSZ
#undef TIOCSWINSZ
#endif
#if defined (USG) || defined (DGUX)
#include <sys/utsname.h>
#ifndef MEMORY_IN_STRING_H
#include <memory.h>
#endif
#if defined (TIOCGWINSZ) || defined (ISC4_0)
#ifdef NEED_SIOCTL
#include <sys/sioctl.h>
#endif
#ifdef NEED_PTEM_H
#include <sys/stream.h>
#include <sys/ptem.h>
#endif
#endif
#endif
extern int quit_char;
#include "keyboard.h"
#include "frame.h"
#include "window.h"
#include "termhooks.h"
#include "termchar.h"
#include "termopts.h"
#include "dispextern.h"
#include "process.h"
#ifdef WINDOWSNT
#include <direct.h>
#define _P_WAIT 0
int _CRTAPI1 _spawnlp (int, const char *, const char *, ...);
int _CRTAPI1 _getpid (void);
#endif
#ifdef NONSYSTEM_DIR_LIBRARY
#include "ndir.h"
#endif
#include "syssignal.h"
#include "systime.h"
#ifdef HAVE_UTIME_H
#include <utime.h>
#endif
#ifndef HAVE_UTIMES
#ifndef HAVE_STRUCT_UTIMBUF
struct utimbuf {
long actime;
long modtime;
};
#endif
#endif
#ifndef LPASS8
#define LPASS8 0
#endif
#ifdef BSD4_1
#define LNOFLSH 0100000
#endif
static int baud_convert[] =
#ifdef BAUD_CONVERT
BAUD_CONVERT;
#else
{
0, 50, 75, 110, 135, 150, 200, 300, 600, 1200,
1800, 2400, 4800, 9600, 19200, 38400
};
#endif
#ifdef HAVE_SPEED_T
#include <termios.h>
#else
#if defined (HAVE_LIBNCURSES) && ! defined (NCURSES_OSPEED_T)
#else
#if defined (HAVE_TERMIOS_H) && defined (LINUX)
#include <termios.h>
#endif
#endif
#endif
int emacs_ospeed;
int input_fd;
void croak P_ ((char *));
#ifdef AIXHFT
void hft_init ();
void hft_reset ();
#endif
SIGMASKTYPE sigprocmask_set;
void
change_input_fd (fd)
int fd;
{
input_fd = fd;
}
void
discard_tty_input ()
{
#ifndef WINDOWSNT
struct emacs_tty buf;
if (noninteractive)
return;
if (read_socket_hook)
return;
#ifdef VMS
end_kbd_input ();
SYS$QIOW (0, input_fd, IO$_READVBLK|IO$M_PURGE, input_iosb, 0, 0,
&buf.main, 0, 0, terminator_mask, 0, 0);
queue_kbd_input ();
#else
#ifdef APOLLO
{
int zero = 0;
ioctl (input_fd, TIOCFLUSH, &zero);
}
#else
#ifdef MSDOS
while (dos_keyread () != -1)
;
#else
EMACS_GET_TTY (input_fd, &buf);
EMACS_SET_TTY (input_fd, &buf, 0);
#endif
#endif
#endif
#endif
}
#ifdef SIGTSTP
void
stuff_char (c)
char c;
{
if (read_socket_hook)
return;
#ifdef TIOCSTI
ioctl (input_fd, TIOCSTI, &c);
#else
error ("Cannot stuff terminal input characters in this version of Unix");
#endif
}
#endif
void
init_baud_rate ()
{
if (noninteractive)
emacs_ospeed = 0;
else
{
#ifdef INIT_BAUD_RATE
INIT_BAUD_RATE ();
#else
#ifdef DOS_NT
emacs_ospeed = 15;
#else
#ifdef VMS
struct sensemode sg;
SYS$QIOW (0, input_fd, IO$_SENSEMODE, &sg, 0, 0,
&sg.class, 12, 0, 0, 0, 0 );
emacs_ospeed = sg.xmit_baud;
#else
#ifdef HAVE_TERMIOS
struct termios sg;
sg.c_cflag = B9600;
tcgetattr (input_fd, &sg);
emacs_ospeed = cfgetospeed (&sg);
#if defined (USE_GETOBAUD) && defined (getobaud)
if (emacs_ospeed == 0)
emacs_ospeed = getobaud (sg.c_cflag);
#endif
#else
#ifdef HAVE_TERMIO
struct termio sg;
sg.c_cflag = B9600;
#ifdef HAVE_TCATTR
tcgetattr (input_fd, &sg);
#else
ioctl (input_fd, TCGETA, &sg);
#endif
emacs_ospeed = sg.c_cflag & CBAUD;
#else
struct sgttyb sg;
sg.sg_ospeed = B9600;
if (ioctl (input_fd, TIOCGETP, &sg) < 0)
abort ();
emacs_ospeed = sg.sg_ospeed;
#endif
#endif
#endif
#endif
#endif
}
baud_rate = (emacs_ospeed < sizeof baud_convert / sizeof baud_convert[0]
? baud_convert[emacs_ospeed] : 9600);
if (baud_rate == 0)
baud_rate = 1200;
}
void
set_exclusive_use (fd)
int fd;
{
#ifdef FIOCLEX
ioctl (fd, FIOCLEX, 0);
#endif
}
#ifndef subprocesses
wait_without_blocking ()
{
#ifdef BSD_SYSTEM
wait3 (0, WNOHANG | WUNTRACED, 0);
#else
croak ("wait_without_blocking");
#endif
synch_process_alive = 0;
}
#endif
int wait_debugging;
SIGTYPE
wait_for_termination_signal ()
{}
void
wait_for_termination (pid)
int pid;
{
while (1)
{
#ifdef subprocesses
#ifdef VMS
int status;
status = SYS$FORCEX (&pid, 0, 0);
break;
#else
#if defined (BSD_SYSTEM) || (defined (HPUX) && !defined (HPUX_5))
sigsetmask (sigmask (SIGCHLD));
if (0 > kill (pid, 0))
{
sigsetmask (SIGEMPTYMASK);
kill (getpid (), SIGCHLD);
break;
}
if (wait_debugging)
sleep (1);
else
sigpause (SIGEMPTYMASK);
#else
#if defined (UNIPLUS)
if (0 > kill (pid, 0))
break;
wait (0);
#else
#ifdef POSIX_SIGNALS
sigblock (sigmask (SIGCHLD));
errno = 0;
if (kill (pid, 0) == -1 && errno == ESRCH)
{
sigunblock (sigmask (SIGCHLD));
break;
}
sigpause (SIGEMPTYMASK);
#else
#ifdef HAVE_SYSV_SIGPAUSE
sighold (SIGCHLD);
if (0 > kill (pid, 0))
{
sigrelse (SIGCHLD);
break;
}
sigpause (SIGCHLD);
#else
#ifdef WINDOWSNT
wait (0);
break;
#else
if (0 > kill (pid, 0))
break;
sleep (1);
#endif
#endif
#endif
#endif
#endif
#endif
#else
#if __DJGPP__ > 1
break;
#else
#ifndef BSD4_1
if (kill (pid, 0) < 0)
break;
wait (0);
#else
int status;
status = wait (0);
if (status == pid || status == -1)
break;
#endif
#endif
#endif
}
}
#ifdef subprocesses
void
flush_pending_output (channel)
int channel;
{
#ifdef HAVE_TERMIOS
#else
#ifdef TCFLSH
ioctl (channel, TCFLSH, 1);
#else
#ifdef TIOCFLUSH
int zero = 0;
ioctl (channel, TIOCFLUSH, &zero);
#endif
#endif
#endif
}
#ifndef VMS
void
child_setup_tty (out)
int out;
{
#ifndef DOS_NT
struct emacs_tty s;
EMACS_GET_TTY (out, &s);
#if defined (HAVE_TERMIO) || defined (HAVE_TERMIOS)
s.main.c_oflag |= OPOST;
s.main.c_oflag &= ~ONLCR;
#ifdef NLDLY
s.main.c_oflag &= ~(NLDLY|CRDLY|TABDLY|BSDLY|VTDLY|FFDLY);
#endif
s.main.c_lflag &= ~ECHO;
s.main.c_lflag |= ISIG;
#if 0
s.main.c_iflag &= ~ICRNL;
#ifdef INLCR
s.main.c_iflag &= ~INLCR;
#endif
#endif
#ifdef IUCLC
s.main.c_iflag &= ~IUCLC;
#endif
#ifdef ISTRIP
s.main.c_iflag &= ~ISTRIP;
#endif
#ifdef OLCUC
s.main.c_oflag &= ~OLCUC;
#endif
s.main.c_oflag &= ~TAB3;
s.main.c_cflag = (s.main.c_cflag & ~CSIZE) | CS8;
#if 0
s.main.c_cc[VMIN] = 1;
s.main.c_cc[VTIME] = 0;
#endif
s.main.c_lflag |= ICANON;
s.main.c_cc[VEOF] = 04;
s.main.c_cc[VERASE] = CDISABLE;
s.main.c_cc[VKILL] = CDISABLE;
#ifdef HPUX
s.main.c_cflag = (s.main.c_cflag & ~CBAUD) | B9600;
#endif
#ifdef AIX
#ifndef IBMR2AIX
s.main.c_line = 0;
s.main.c_iflag &= ~ASCEDIT;
#endif
s.main.c_iflag &= ~IGNBRK;
s.main.c_iflag &= ~BRKINT;
s.main.c_cc[VINTR] = 0377;
#ifdef SIGNALS_VIA_CHARACTERS
if (s.main.c_cc[VQUIT] == 0377)
s.main.c_cc[VQUIT] = '\\'&037;
if (s.main.c_cc[VINTR] == 0377)
s.main.c_cc[VINTR] = 'C'&037;
#else
s.main.c_cc[VQUIT] = 0377;
s.main.c_cc[VINTR] = 0377;
s.main.c_lflag &= ~ISIG;
#endif
s.main.c_cc[VEOL] = 0377;
s.main.c_cflag = (s.main.c_cflag & ~CBAUD) | B9600;
#endif
#else
s.main.sg_flags &= ~(ECHO | CRMOD | ANYP | ALLDELAY | RAW | LCASE
| CBREAK | TANDEM);
s.main.sg_flags |= LPASS8;
s.main.sg_erase = 0377;
s.main.sg_kill = 0377;
s.lmode = LLITOUT | s.lmode;
#endif
EMACS_SET_TTY (out, &s, 0);
#ifdef BSD4_1
if (interrupt_input)
reset_sigio ();
#endif
#ifdef RTU
{
int zero = 0;
ioctl (out, FIOASYNC, &zero);
}
#endif
#endif
}
#endif
#endif
struct save_signal
{
int code;
SIGTYPE (*handler) P_ ((int));
};
static void save_signal_handlers P_ ((struct save_signal *));
static void restore_signal_handlers P_ ((struct save_signal *));
void
sys_suspend ()
{
#ifdef VMS
unsigned long parent_id, foster_parent_id;
char *fpid_string;
fpid_string = getenv ("EMACS_PARENT_PID");
if (fpid_string != NULL)
{
sscanf (fpid_string, "%x", &foster_parent_id);
if (foster_parent_id != 0)
parent_id = foster_parent_id;
else
parent_id = getppid ();
}
else
parent_id = getppid ();
xfree (fpid_string);
if (parent_id && parent_id != 0xffffffff)
{
SIGTYPE (*oldsig)() = (int) signal (SIGINT, SIG_IGN);
int status = LIB$ATTACH (&parent_id) & 1;
signal (SIGINT, oldsig);
return status;
}
else
{
struct {
int l;
char *a;
} d_prompt;
d_prompt.l = sizeof ("Emacs: ");
d_prompt.a = "Emacs: ";
LIB$SPAWN (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &d_prompt, 0);
return 1;
}
return -1;
#else
#if defined (SIGTSTP) && !defined (MSDOS)
{
int pgrp = EMACS_GETPGRP (0);
EMACS_KILLPG (pgrp, SIGTSTP);
}
#else
#ifdef USG_JOBCTRL
ptrace (0, 0, 0, 0);
kill (getpid (), SIGQUIT);
#else
sys_subshell ();
#endif
#endif
#endif
}
#ifndef macintosh
void
sys_subshell ()
{
#ifndef VMS
#ifdef DOS_NT
int st;
char oldwd[MAXPATHLEN+1];
#endif
int pid;
struct save_signal saved_handlers[5];
Lisp_Object dir;
unsigned char *str = 0;
int len;
saved_handlers[0].code = SIGINT;
saved_handlers[1].code = SIGQUIT;
saved_handlers[2].code = SIGTERM;
#ifdef SIGIO
saved_handlers[3].code = SIGIO;
saved_handlers[4].code = 0;
#else
saved_handlers[3].code = 0;
#endif
dir = intern ("default-directory");
if (NILP (Fboundp (dir)))
goto xyzzy;
dir = Fsymbol_value (dir);
if (!STRINGP (dir))
goto xyzzy;
dir = expand_and_dir_to_file (Funhandled_file_name_directory (dir), Qnil);
str = (unsigned char *) alloca (XSTRING (dir)->size + 2);
len = XSTRING (dir)->size;
bcopy (XSTRING (dir)->data, str, len);
if (str[len - 1] != '/') str[len++] = '/';
str[len] = 0;
xyzzy:
#ifdef DOS_NT
pid = 0;
#if __DJGPP__ > 1
save_signal_handlers (saved_handlers);
synch_process_alive = 1;
#endif
#else
#ifndef PUMA_VFORK_ISSUES_CLEARED_UP
pid = fork ();
#else
pid = vfork ();
#endif
if (pid == -1)
error ("Can't spawn subshell");
#endif
if (pid == 0)
{
char *sh = 0;
#ifdef DOS_NT
getwd (oldwd);
if (sh == 0)
sh = (char *) egetenv ("SUSPEND");
#endif
if (sh == 0)
sh = (char *) egetenv ("SHELL");
if (sh == 0)
sh = "sh";
if (str)
chdir ((char *) str);
#ifdef subprocesses
close_process_descs ();
#endif
#ifdef SET_EMACS_PRIORITY
{
extern int emacs_priority;
if (emacs_priority < 0)
nice (-emacs_priority);
}
#endif
#ifdef MSDOS
st = system (sh);
chdir (oldwd);
#if 0
if (st)
report_file_error ("Can't execute subshell", Fcons (build_string (sh), Qnil));
#endif
#else
#ifdef WINDOWSNT
pid = _spawnlp (_P_WAIT, sh, sh, NULL);
chdir (oldwd);
if (pid == -1)
write (1, "Can't execute subshell", 22);
#else
execlp (sh, sh, 0);
write (1, "Can't execute subshell", 22);
_exit (1);
#endif
#endif
}
#if !defined (MSDOS) || __DJGPP__ == 1
save_signal_handlers (saved_handlers);
synch_process_alive = 1;
#endif
#ifndef DOS_NT
wait_for_termination (pid);
#endif
restore_signal_handlers (saved_handlers);
synch_process_alive = 0;
#endif
}
#endif
static void
save_signal_handlers (saved_handlers)
struct save_signal *saved_handlers;
{
while (saved_handlers->code)
{
saved_handlers->handler
= (SIGTYPE (*) P_ ((int))) signal (saved_handlers->code, SIG_IGN);
saved_handlers++;
}
}
static void
restore_signal_handlers (saved_handlers)
struct save_signal *saved_handlers;
{
while (saved_handlers->code)
{
signal (saved_handlers->code, saved_handlers->handler);
saved_handlers++;
}
}
#ifdef F_SETFL
int old_fcntl_flags;
void
init_sigio (fd)
int fd;
{
#ifdef FASYNC
old_fcntl_flags = fcntl (fd, F_GETFL, 0) & ~FASYNC;
fcntl (fd, F_SETFL, old_fcntl_flags | FASYNC);
#endif
interrupts_deferred = 0;
}
void
reset_sigio ()
{
unrequest_sigio ();
}
#ifdef FASYNC
void
request_sigio ()
{
if (read_socket_hook)
return;
#ifdef SIGWINCH
sigunblock (sigmask (SIGWINCH));
#endif
fcntl (input_fd, F_SETFL, old_fcntl_flags | FASYNC);
interrupts_deferred = 0;
}
void
unrequest_sigio ()
{
if (read_socket_hook)
return;
#ifdef SIGWINCH
sigblock (sigmask (SIGWINCH));
#endif
fcntl (input_fd, F_SETFL, old_fcntl_flags);
interrupts_deferred = 1;
}
#else
#ifdef STRIDE
void
request_sigio ()
{
int on = 1;
if (read_socket_hook)
return;
ioctl (input_fd, FIOASYNC, &on);
interrupts_deferred = 0;
}
void
unrequest_sigio ()
{
int off = 0;
if (read_socket_hook)
return;
ioctl (input_fd, FIOASYNC, &off);
interrupts_deferred = 1;
}
#else
#ifdef _CX_UX
#include <termios.h>
void
request_sigio ()
{
int on = 1;
sigset_t st;
if (read_socket_hook)
return;
sigemptyset (&st);
sigaddset (&st, SIGIO);
ioctl (input_fd, FIOASYNC, &on);
interrupts_deferred = 0;
sigprocmask (SIG_UNBLOCK, &st, (sigset_t *)0);
}
void
unrequest_sigio ()
{
int off = 0;
if (read_socket_hook)
return;
ioctl (input_fd, FIOASYNC, &off);
interrupts_deferred = 1;
}
#else
void
request_sigio ()
{
if (read_socket_hook)
return;
croak ("request_sigio");
}
void
unrequest_sigio ()
{
if (read_socket_hook)
return;
croak ("unrequest_sigio");
}
#endif
#endif
#endif
#endif
#ifdef BSD_PGRPS
int inherited_pgroup;
void
narrow_foreground_group ()
{
int me = getpid ();
setpgrp (0, inherited_pgroup);
if (inherited_pgroup != me)
EMACS_SET_TTY_PGRP (input_fd, &me);
setpgrp (0, me);
}
void
widen_foreground_group ()
{
if (inherited_pgroup != getpid ())
EMACS_SET_TTY_PGRP (input_fd, &inherited_pgroup);
setpgrp (0, inherited_pgroup);
}
#endif
int
emacs_get_tty (fd, settings)
int fd;
struct emacs_tty *settings;
{
#ifdef HAVE_TCATTR
bzero (&settings->main, sizeof (settings->main));
if (tcgetattr (fd, &settings->main) < 0)
return -1;
#else
#ifdef HAVE_TERMIO
if (ioctl (fd, TCGETA, &settings->main) < 0)
return -1;
#else
#ifdef VMS
if (! (SYS$QIOW (0, fd, IO$_SENSEMODE, settings, 0, 0,
&settings->main.class, 12, 0, 0, 0, 0)
& 1))
return -1;
#else
#ifndef DOS_NT
if (ioctl (fd, TIOCGETP, &settings->main) < 0)
return -1;
#endif
#endif
#endif
#endif
#ifdef HAVE_LTCHARS
if (ioctl (fd, TIOCGLTC, &settings->ltchars) < 0)
return -1;
#endif
#ifdef HAVE_TCHARS
if (ioctl (fd, TIOCGETC, &settings->tchars) < 0
|| ioctl (fd, TIOCLGET, &settings->lmode) < 0)
return -1;
#endif
return 0;
}
int
emacs_set_tty (fd, settings, flushp)
int fd;
struct emacs_tty *settings;
int flushp;
{
#ifdef HAVE_TCATTR
int i;
for (i = 0 ; i < 10 ; i++)
if (tcsetattr (fd, flushp ? TCSAFLUSH : TCSADRAIN, &settings->main) < 0)
{
if (errno == EINTR)
continue;
else
return -1;
}
else
{
struct termios new;
bzero (&new, sizeof (new));
tcgetattr (fd, &new);
if ( new.c_iflag == settings->main.c_iflag
&& new.c_oflag == settings->main.c_oflag
&& new.c_cflag == settings->main.c_cflag
&& new.c_lflag == settings->main.c_lflag
&& memcmp (new.c_cc, settings->main.c_cc, NCCS) == 0)
break;
else
continue;
}
#else
#ifdef HAVE_TERMIO
if (ioctl (fd, flushp ? TCSETAF : TCSETAW, &settings->main) < 0)
return -1;
#else
#ifdef VMS
if (! (SYS$QIOW (0, fd, IO$_SETMODE, &input_iosb, 0, 0,
&settings->main.class, 12, 0, 0, 0, 0)
& 1))
return -1;
#else
#ifndef DOS_NT
if (ioctl (fd, (flushp) ? TIOCSETP : TIOCSETN, &settings->main) < 0)
return -1;
#endif
#endif
#endif
#endif
#ifdef HAVE_LTCHARS
if (ioctl (fd, TIOCSLTC, &settings->ltchars) < 0)
return -1;
#endif
#ifdef HAVE_TCHARS
if (ioctl (fd, TIOCSETC, &settings->tchars) < 0
|| ioctl (fd, TIOCLSET, &settings->lmode) < 0)
return -1;
#endif
return 0;
}
struct emacs_tty old_tty;
int term_initted;
int old_tty_valid;
#ifdef BSD4_1
int lmode;
#endif
#ifndef F_SETOWN_BUG
#ifdef F_SETOWN
int old_fcntl_owner;
#endif
#endif
#ifdef nec_ews_svr4
extern char *_sobuf ;
#else
#if defined (USG) || defined (DGUX)
unsigned char _sobuf[BUFSIZ+8];
#else
char _sobuf[BUFSIZ];
#endif
#endif
#ifdef HAVE_LTCHARS
static struct ltchars new_ltchars = {-1,-1,-1,-1,-1,-1};
#endif
#ifdef HAVE_TCHARS
static struct tchars new_tchars = {-1,-1,-1,-1,-1,-1};
#endif
void
init_sys_modes ()
{
struct emacs_tty tty;
#ifdef macintosh
#ifndef subprocesses
DEFVAR_BOOL ("delete-exited-processes", &delete_exited_processes,
"*Non-nil means delete processes immediately when they exit.\n\
nil means don't delete them until `list-processes' is run.");
delete_exited_processes = 0;
#endif
#endif
#ifdef VMS
#if 0
static int oob_chars[2] = {0, 1 << 7};
extern int (*interrupt_signal) ();
#endif
#endif
Vtty_erase_char = Qnil;
if (noninteractive)
return;
#ifdef VMS
if (!input_ef)
input_ef = get_kbd_event_flag ();
SYS$CLREF (input_ef);
waiting_for_ast = 0;
if (!timer_ef)
timer_ef = get_timer_event_flag ();
SYS$CLREF (timer_ef);
#if 0
if (!process_ef)
{
LIB$GET_EF (&process_ef);
SYS$CLREF (process_ef);
}
if (input_ef / 32 != process_ef / 32)
croak ("Input and process event flags in different clusters.");
#endif
if (input_ef / 32 != timer_ef / 32)
croak ("Input and timer event flags in different clusters.");
#if 0
input_eflist = ((unsigned) 1 << (input_ef % 32)) |
((unsigned) 1 << (process_ef % 32));
#endif
timer_eflist = ((unsigned) 1 << (input_ef % 32)) |
((unsigned) 1 << (timer_ef % 32));
#ifndef VMS4_4
sys_access_reinit ();
#endif
#endif
#ifdef BSD_PGRPS
if (! read_socket_hook && EQ (Vwindow_system, Qnil))
narrow_foreground_group ();
#endif
#ifdef HAVE_WINDOW_SYSTEM
if (!read_socket_hook && EQ (Vwindow_system, Qnil))
#endif
{
EMACS_GET_TTY (input_fd, &old_tty);
old_tty_valid = 1;
tty = old_tty;
#if defined (HAVE_TERMIO) || defined (HAVE_TERMIOS)
XSETINT (Vtty_erase_char, old_tty.main.c_cc[VERASE]);
#ifdef DGUX
tty.main.c_iflag &= ~INPCK;
#endif
tty.main.c_iflag |= (IGNBRK);
tty.main.c_iflag &= ~ICRNL;
#ifdef INLCR
tty.main.c_iflag &= ~INLCR;
#endif
#ifdef ISTRIP
tty.main.c_iflag &= ~ISTRIP;
#endif
tty.main.c_lflag &= ~ECHO;
tty.main.c_lflag &= ~ICANON;
#ifdef IEXTEN
tty.main.c_lflag &= ~IEXTEN;
#endif
tty.main.c_lflag |= ISIG;
if (flow_control)
{
tty.main.c_iflag |= IXON;
#ifdef IXANY
tty.main.c_iflag &= ~IXANY;
#endif
}
else
tty.main.c_iflag &= ~IXON;
tty.main.c_oflag &= ~ONLCR;
tty.main.c_oflag &= ~TAB3;
#ifdef CS8
if (meta_key)
{
tty.main.c_cflag |= CS8;
tty.main.c_cflag &= ~PARENB;
}
#endif
tty.main.c_cc[VINTR] = quit_char;
tty.main.c_cc[VQUIT] = quit_char;
tty.main.c_cc[VMIN] = 1;
tty.main.c_cc[VTIME] = 0;
#ifdef VSWTCH
tty.main.c_cc[VSWTCH] = CDISABLE;
#endif
#if defined (mips) || defined (HAVE_TCATTR)
#ifdef VSUSP
tty.main.c_cc[VSUSP] = CDISABLE;
#endif
#ifdef V_DSUSP
tty.main.c_cc[V_DSUSP] = CDISABLE;
#endif
#ifdef VDSUSP
tty.main.c_cc[VDSUSP] = CDISABLE;
#endif
#ifdef VLNEXT
tty.main.c_cc[VLNEXT] = CDISABLE;
#endif
#ifdef VREPRINT
tty.main.c_cc[VREPRINT] = CDISABLE;
#endif
#ifdef VWERASE
tty.main.c_cc[VWERASE] = CDISABLE;
#endif
#ifdef VDISCARD
tty.main.c_cc[VDISCARD] = CDISABLE;
#endif
if (flow_control)
{
#ifdef VSTART
tty.main.c_cc[VSTART] = '\021';
#endif
#ifdef VSTOP
tty.main.c_cc[VSTOP] = '\023';
#endif
}
else
{
#ifdef VSTART
tty.main.c_cc[VSTART] = CDISABLE;
#endif
#ifdef VSTOP
tty.main.c_cc[VSTOP] = CDISABLE;
#endif
}
#endif
#ifdef SET_LINE_DISCIPLINE
tty.main.c_line = SET_LINE_DISCIPLINE;
#endif
#ifdef AIX
#ifndef IBMR2AIX
tty.main.c_line = 0;
tty.main.c_iflag &= ~ASCEDIT;
#else
tty.main.c_cc[VSTRT] = 255;
tty.main.c_cc[VSTOP] = 255;
tty.main.c_cc[VSUSP] = 255;
tty.main.c_cc[VDSUSP] = 255;
#endif
if (flow_control)
{
#ifdef VSTART
tty.main.c_cc[VSTART] = '\021';
#endif
#ifdef VSTOP
tty.main.c_cc[VSTOP] = '\023';
#endif
}
tty.main.c_iflag &= ~IGNBRK;
tty.main.c_iflag &= ~BRKINT;
#endif
#else
#ifdef VMS
tty.main.tt_char |= TT$M_NOECHO;
if (meta_key)
tty.main.tt_char |= TT$M_EIGHTBIT;
if (flow_control)
tty.main.tt_char |= TT$M_TTSYNC;
else
tty.main.tt_char &= ~TT$M_TTSYNC;
tty.main.tt2_char |= TT2$M_PASTHRU | TT2$M_XON;
#else
#ifndef DOS_NT
XSETINT (Vtty_erase_char, tty.main.sg_erase);
tty.main.sg_flags &= ~(ECHO | CRMOD | XTABS);
if (meta_key)
tty.main.sg_flags |= ANYP;
tty.main.sg_flags |= interrupt_input ? RAW : CBREAK;
#endif
#endif
#endif
#ifndef HAVE_TERMIO
#ifdef HAVE_TCHARS
tty.tchars = new_tchars;
tty.tchars.t_intrc = quit_char;
if (flow_control)
{
tty.tchars.t_startc = '\021';
tty.tchars.t_stopc = '\023';
}
tty.lmode = LDECCTQ | LLITOUT | LPASS8 | LNOFLSH | old_tty.lmode;
#ifdef ultrix
tty.lmode &= ~LLITOUT;
#endif
#ifdef BSD4_1
lmode = tty.lmode;
#endif
#endif
#endif
#ifdef HAVE_LTCHARS
tty.ltchars = new_ltchars;
#endif
#ifdef MSDOS
if (!term_initted)
internal_terminal_init ();
dos_ttraw ();
#endif
EMACS_SET_TTY (input_fd, &tty, 0);
#ifdef TCXONC
if (!flow_control) ioctl (input_fd, TCXONC, 1);
#endif
#ifndef APOLLO
#ifdef TIOCSTART
if (!flow_control) ioctl (input_fd, TIOCSTART, 0);
#endif
#endif
#if defined (HAVE_TERMIOS) || defined (HPUX9)
#ifdef TCOON
if (!flow_control) tcflow (input_fd, TCOON);
#endif
#endif
#ifdef AIXHFT
hft_init ();
#ifdef IBMR2AIX
{
struct termio tty;
if (ioctl (1, HFTGETID, &tty) != -1)
write (1, "\033[20l", 5);
}
#endif
#endif
#ifdef VMS
queue_kbd_input (0);
#endif
}
#ifdef F_SETFL
#ifndef F_SETOWN_BUG
#ifdef F_GETOWN
if (interrupt_input
&& ! read_socket_hook && EQ (Vwindow_system, Qnil))
{
old_fcntl_owner = fcntl (input_fd, F_GETOWN, 0);
fcntl (input_fd, F_SETOWN, getpid ());
init_sigio (input_fd);
}
#endif
#endif
#endif
#ifdef BSD4_1
if (interrupt_input)
init_sigio (input_fd);
#endif
#ifdef VMS
#undef _IOFBF
#endif
#ifdef _IOFBF
setvbuf (stdout, (char *) _sobuf, _IOFBF, sizeof _sobuf);
#else
setbuf (stdout, (char *) _sobuf);
#endif
#ifdef HAVE_WINDOW_SYSTEM
if (EQ (Vwindow_system, Qnil)
#ifndef WINDOWSNT
&& (! read_socket_hook)
#endif
)
#endif
set_terminal_modes ();
if (!term_initted
&& FRAMEP (Vterminal_frame)
&& FRAME_TERMCAP_P (XFRAME (Vterminal_frame)))
init_frame_faces (XFRAME (Vterminal_frame));
if (term_initted && no_redraw_on_reenter)
{
if (display_completed)
direct_output_forward_char (0);
}
else
{
frame_garbaged = 1;
if (FRAMEP (Vterminal_frame))
FRAME_GARBAGED_P (XFRAME (Vterminal_frame)) = 1;
}
term_initted = 1;
}
int
tabs_safe_p ()
{
struct emacs_tty tty;
EMACS_GET_TTY (input_fd, &tty);
return EMACS_TTY_TABS_OK (&tty);
}
void
get_frame_size (widthp, heightp)
int *widthp, *heightp;
{
#ifdef TIOCGWINSZ
struct winsize size;
if (ioctl (input_fd, TIOCGWINSZ, &size) == -1)
*widthp = *heightp = 0;
else
{
*widthp = size.ws_col;
*heightp = size.ws_row;
}
#else
#ifdef TIOCGSIZE
struct ttysize size;
if (ioctl (input_fd, TIOCGSIZE, &size) == -1)
*widthp = *heightp = 0;
else
{
*widthp = size.ts_cols;
*heightp = size.ts_lines;
}
#else
#ifdef VMS
struct sensemode tty;
SYS$QIOW (0, input_fd, IO$_SENSEMODE, &tty, 0, 0,
&tty.class, 12, 0, 0, 0, 0);
*widthp = tty.scr_wid;
*heightp = tty.scr_len;
#else
#ifdef MSDOS
*widthp = ScreenCols ();
*heightp = ScreenRows ();
#else
*widthp = 0;
*heightp = 0;
#endif
#endif
#endif
#endif
}
int
set_window_size (fd, height, width)
int fd, height, width;
{
#ifdef TIOCSWINSZ
struct winsize size;
size.ws_row = height;
size.ws_col = width;
if (ioctl (fd, TIOCSWINSZ, &size) == -1)
return 0;
else
return 1;
#else
#ifdef TIOCSSIZE
struct ttysize size;
size.ts_lines = height;
size.ts_cols = width;
if (ioctl (fd, TIOCGSIZE, &size) == -1)
return 0;
else
return 1;
#else
return -1;
#endif
#endif
}
void
reset_sys_modes ()
{
struct frame *sf;
if (noninteractive)
{
fflush (stdout);
return;
}
if (!term_initted)
return;
#ifdef HAVE_WINDOW_SYSTEM
if (!EQ (Vwindow_system, Qnil)
#ifndef WINDOWSNT
|| read_socket_hook
#endif
)
return;
#endif
sf = SELECTED_FRAME ();
cursor_to (FRAME_HEIGHT (sf) - 1, 0);
clear_end_of_line (FRAME_WIDTH (sf));
cursor_to (FRAME_HEIGHT (sf) - 1, 0);
#if defined (IBMR2AIX) && defined (AIXHFT)
{
struct termio tty;
if (ioctl (1, HFTGETID, &tty) != -1)
write (1, "\033[20h", 5);
}
#endif
reset_terminal_modes ();
fflush (stdout);
#ifdef BSD_SYSTEM
#ifndef BSD4_1
fsync (fileno (stdout));
#endif
#endif
#ifdef F_SETFL
#ifndef F_SETOWN_BUG
#ifdef F_SETOWN
if (interrupt_input)
{
reset_sigio ();
fcntl (input_fd, F_SETOWN, old_fcntl_owner);
}
#endif
#endif
#ifdef O_NDELAY
fcntl (input_fd, F_SETFL, fcntl (input_fd, F_GETFL, 0) & ~O_NDELAY);
#endif
#endif
#ifdef BSD4_1
if (interrupt_input)
reset_sigio ();
#endif
if (old_tty_valid)
while (EMACS_SET_TTY (input_fd, &old_tty, 0) < 0 && errno == EINTR)
;
#ifdef MSDOS
dos_ttcooked ();
#endif
#ifdef SET_LINE_DISCIPLINE
ioctl (0, TIOCSETD, &old_tty.main.c_line);
#endif
#ifdef AIXHFT
hft_reset ();
#endif
#ifdef BSD_PGRPS
widen_foreground_group ();
#endif
}
#ifdef HAVE_PTYS
void
setup_pty (fd)
int fd;
{
#ifdef FIONBIO
#if defined(SYSV_PTYS) || defined(UNIX98_PTYS)
{
int on = 1;
ioctl (fd, FIONBIO, &on);
}
#endif
#endif
#ifdef IBMRTAIX
signal (SIGHUP, SIG_IGN);
#endif
}
#endif
#ifdef VMS
void
init_vms_input ()
{
int status;
if (input_fd == 0)
{
status = SYS$ASSIGN (&input_dsc, &input_fd, 0, 0);
if (! (status & 1))
LIB$STOP (status);
}
}
void
stop_vms_input ()
{
return SYS$DASSGN (input_fd);
}
short input_buffer;
void
queue_kbd_input ()
{
int status;
extern kbd_input_ast ();
waiting_for_ast = 0;
stop_input = 0;
status = SYS$QIO (0, input_fd, IO$_READVBLK,
&input_iosb, kbd_input_ast, 1,
&input_buffer, 1, 0, terminator_mask, 0, 0);
}
int input_count;
void
kbd_input_ast ()
{
register int c = -1;
int old_errno = errno;
extern EMACS_TIME *input_available_clear_time;
if (waiting_for_ast)
SYS$SETEF (input_ef);
waiting_for_ast = 0;
input_count++;
#ifdef ASTDEBUG
if (input_count == 25)
exit (1);
printf ("Ast # %d,", input_count);
printf (" iosb = %x, %x, %x, %x",
input_iosb.offset, input_iosb.status, input_iosb.termlen,
input_iosb.term);
#endif
if (input_iosb.offset)
{
c = input_buffer;
#ifdef ASTDEBUG
printf (", char = 0%o", c);
#endif
}
#ifdef ASTDEBUG
printf ("\n");
fflush (stdout);
sleep (1);
#endif
if (! stop_input)
queue_kbd_input ();
if (c >= 0)
{
struct input_event e;
e.kind = ascii_keystroke;
XSETINT (e.code, c);
e.frame_or_window = selected_frame;
kbd_buffer_store_event (&e);
}
if (input_available_clear_time)
EMACS_SET_SECS_USECS (*input_available_clear_time, 0, 0);
errno = old_errno;
}
void
wait_for_kbd_input ()
{
extern int have_process_input, process_exited;
if (detect_input_pending ())
{
return;
}
SYS$CLREF (input_ef);
waiting_for_ast = 1;
if (!detect_input_pending ())
{
set_waiting_for_input (0);
SYS$WFLOR (input_ef, input_eflist);
clear_waiting_for_input (0);
if (!detect_input_pending ())
{
int dsp = have_process_input || process_exited;
SYS$CLREF (process_ef);
if (have_process_input)
process_command_input ();
if (process_exited)
process_exit ();
if (dsp)
{
update_mode_lines++;
prepare_menu_bars ();
redisplay_preserve_echo_area (18);
}
}
}
waiting_for_ast = 0;
}
void
end_kbd_input ()
{
#ifdef ASTDEBUG
printf ("At end_kbd_input.\n");
fflush (stdout);
sleep (1);
#endif
if (LIB$AST_IN_PROG ())
{
SYS$CANCEL (input_fd);
return;
}
SYS$SETAST (0);
SYS$CLREF (input_ef);
waiting_for_ast = 1;
stop_input = 1;
SYS$CANCEL (input_fd);
SYS$SETAST (1);
SYS$WAITFR (input_ef);
waiting_for_ast = 0;
}
void
input_wait_timeout (timeval)
int timeval;
{
int time [2];
static int zero = 0;
static int large = -10000000;
LIB$EMUL (&timeval, &large, &zero, time);
if (detect_input_pending ())
{
return;
}
SYS$CLREF (input_ef);
waiting_for_ast = 1;
if (!detect_input_pending ())
{
SYS$CANTIM (1, 0);
if (SYS$SETIMR (timer_ef, time, 0, 1) & 1)
SYS$WFLOR (timer_ef, timer_eflist);
}
waiting_for_ast = 0;
}
sys_sleep (timeval)
int timeval;
{
int time [2];
static int zero = 0;
static int large = -10000000;
LIB$EMUL (&timeval, &large, &zero, time);
SYS$CANTIM (1, 0);
if (SYS$SETIMR (timer_ef, time, 0, 1) & 1)
SYS$WAITFR (timer_ef);
}
void
init_sigio (fd)
int fd;
{
request_sigio ();
}
reset_sigio ()
{
unrequest_sigio ();
}
void
request_sigio ()
{
croak ("request sigio");
}
void
unrequest_sigio ()
{
croak ("unrequest sigio");
}
#endif
#ifndef CANNOT_DUMP
#define NEED_STARTS
#endif
#ifndef SYSTEM_MALLOC
#ifndef NEED_STARTS
#define NEED_STARTS
#endif
#endif
#ifdef NEED_STARTS
#if !(defined (__NetBSD__) && defined (__ELF__))
#ifndef HAVE_TEXT_START
char *
start_of_text ()
{
#ifdef TEXT_START
return ((char *) TEXT_START);
#else
#ifdef GOULD
extern csrt ();
return ((char *) csrt);
#else
extern int _start ();
return ((char *) _start);
#endif
#endif
}
#endif
#endif
char *
start_of_data ()
{
#ifdef DATA_START
return ((char *) DATA_START);
#else
#ifdef ORDINARY_LINK
extern char **environ;
return ((char *) &environ);
#else
extern int data_start;
return ((char *) &data_start);
#endif
#endif
}
#endif
#ifndef CANNOT_DUMP
char *
end_of_text ()
{
#ifdef TEXT_END
return ((char *) TEXT_END);
#else
extern int etext;
return ((char *) &etext);
#endif
}
char *
end_of_data ()
{
#ifdef DATA_END
return ((char *) DATA_END);
#else
extern int edata;
return ((char *) &edata);
#endif
}
#endif
#ifdef BSD4_1
#include <whoami.h>
#endif
extern Lisp_Object Vsystem_name;
#ifndef BSD4_1
#ifndef VMS
#ifdef HAVE_SOCKETS
#include <sys/socket.h>
#include <netdb.h>
#endif
#endif
#endif
#ifdef TRY_AGAIN
#ifndef HAVE_H_ERRNO
extern int h_errno;
#endif
#endif
void
init_system_name ()
{
#ifdef BSD4_1
Vsystem_name = build_string (sysname);
#else
#ifdef VMS
char *sp, *end;
if ((sp = egetenv ("SYS$NODE")) == 0)
Vsystem_name = build_string ("vax-vms");
else if ((end = index (sp, ':')) == 0)
Vsystem_name = build_string (sp);
else
Vsystem_name = make_string (sp, end - sp);
#else
#ifndef HAVE_GETHOSTNAME
struct utsname uts;
uname (&uts);
Vsystem_name = build_string (uts.nodename);
#else
unsigned int hostname_size = 256;
char *hostname = (char *) alloca (hostname_size);
for (;;)
{
gethostname (hostname, hostname_size - 1);
hostname[hostname_size - 1] = '\0';
if (strlen (hostname) < hostname_size - 1)
break;
hostname_size <<= 1;
hostname = (char *) alloca (hostname_size);
}
#ifdef HAVE_SOCKETS
#ifndef CANNOT_DUMP
if (initialized)
#endif
if (! index (hostname, '.'))
{
struct hostent *hp;
int count;
for (count = 0;; count++)
{
#ifdef TRY_AGAIN
h_errno = 0;
#endif
hp = gethostbyname (hostname);
#ifdef TRY_AGAIN
if (! (hp == 0 && h_errno == TRY_AGAIN))
#endif
break;
if (count >= 5)
break;
Fsleep_for (make_number (1), Qnil);
}
if (hp)
{
char *fqdn = (char *) hp->h_name;
char *p;
if (!index (fqdn, '.'))
{
char **alias = hp->h_aliases;
while (*alias && !index (*alias, '.'))
alias++;
if (*alias)
fqdn = *alias;
}
hostname = fqdn;
#if 0
p = hostname;
while (*p)
{
if (*p >= 'A' && *p <= 'Z')
*p += 'a' - 'A';
p++;
}
#endif
}
}
#endif
#if 0
#if (HAVE_SYSINFO && defined (SI_SRPC_DOMAIN))
if (! index (hostname, '.'))
{
int hostlen = strlen (hostname);
int domain_size = 256;
for (;;)
{
char *domain = (char *) alloca (domain_size + 1);
char *fqdn = (char *) alloca (hostlen + 1 + domain_size + 1);
int sys_domain_size = sysinfo (SI_SRPC_DOMAIN, domain, domain_size);
if (sys_domain_size <= 0)
break;
if (domain_size < sys_domain_size)
{
domain_size = sys_domain_size;
continue;
}
strcpy (fqdn, hostname);
if (domain[0] == '.')
strcpy (fqdn + hostlen, domain);
else if (domain[0] != 0)
{
fqdn[hostlen] = '.';
strcpy (fqdn + hostlen + 1, domain);
}
hostname = fqdn;
break;
}
}
#endif
#endif
Vsystem_name = build_string (hostname);
#endif
#endif
#endif
{
unsigned char *p;
for (p = XSTRING (Vsystem_name)->data; *p; p++)
if (*p == ' ' || *p == '\t')
*p = '-';
}
}
#ifndef MSDOS
#ifndef VMS
#if !defined (HAVE_SELECT) || defined (BROKEN_SELECT_NON_X)
#include "sysselect.h"
#undef select
#if defined (HAVE_X_WINDOWS) && !defined (HAVE_SELECT)
int *x = &x_windows_lose_if_no_select_system_call;
#endif
#define SELECT_PAUSE 1
int select_alarmed;
jmp_buf read_alarm_throw;
int read_alarm_should_throw;
SIGTYPE
select_alarm ()
{
select_alarmed = 1;
#ifdef BSD4_1
sigrelse (SIGALRM);
#else
signal (SIGALRM, SIG_IGN);
#endif
if (read_alarm_should_throw)
longjmp (read_alarm_throw, 1);
}
#ifndef WINDOWSNT
int
sys_select (nfds, rfds, wfds, efds, timeout)
int nfds;
SELECT_TYPE *rfds, *wfds, *efds;
EMACS_TIME *timeout;
{
int ravail = 0;
SELECT_TYPE orfds;
int timeoutval;
int *local_timeout;
extern int proc_buffered_char[];
#ifndef subprocesses
int process_tick = 0, update_tick = 0;
#else
extern int process_tick, update_tick;
#endif
unsigned char buf;
#if defined (HAVE_SELECT) && defined (HAVE_X_WINDOWS)
if (!NILP (Vwindow_system))
return select (nfds, rfds, wfds, efds, timeout);
#endif
timeoutval = timeout ? EMACS_SECS (*timeout) : 100000;
local_timeout = &timeoutval;
FD_ZERO (&orfds);
if (rfds)
{
orfds = *rfds;
FD_ZERO (rfds);
}
if (wfds)
FD_ZERO (wfds);
if (efds)
FD_ZERO (efds);
if (*local_timeout == 100000 && process_tick == update_tick
&& FD_ISSET (0, &orfds))
{
int fd;
for (fd = 1; fd < nfds; ++fd)
if (FD_ISSET (fd, &orfds))
goto hardway;
if (! detect_input_pending ())
read_input_waiting ();
FD_SET (0, rfds);
return 1;
}
hardway:
while (1)
{
register int to_check, fd;
if (rfds)
{
for (to_check = nfds, fd = 0; --to_check >= 0; fd++)
{
if (FD_ISSET (fd, &orfds))
{
int avail = 0, status = 0;
if (fd == 0)
avail = detect_input_pending ();
else
{
#ifdef FIONREAD
status = ioctl (fd, FIONREAD, &avail);
#else
if (proc_buffered_char[fd] >= 0)
avail = 1;
else
{
avail = read (fd, &buf, 1);
if (avail > 0)
proc_buffered_char[fd] = buf;
}
#endif
}
if (status >= 0 && avail > 0)
{
FD_SET (fd, rfds);
ravail++;
}
}
}
}
if (*local_timeout == 0 || ravail != 0 || process_tick != update_tick)
break;
turn_on_atimers (0);
signal (SIGALRM, select_alarm);
select_alarmed = 0;
alarm (SELECT_PAUSE);
while (select_alarmed == 0 && *local_timeout != 0
&& process_tick == update_tick)
{
if (FD_ISSET (0, &orfds))
{
read_input_waiting ();
if (detect_input_pending ())
select_alarmed = 1;
}
else
pause ();
}
(*local_timeout) -= SELECT_PAUSE;
turn_on_atimers (1);
if (*local_timeout == 0)
break;
}
return ravail;
}
#endif
#ifdef HAVE_WINDOW_SYSTEM
#define BUFFER_SIZE_FACTOR 16
#else
#define BUFFER_SIZE_FACTOR 1
#endif
void
read_input_waiting ()
{
struct input_event e;
int nread, i;
extern int quit_char;
if (read_socket_hook)
{
struct input_event buf[256];
read_alarm_should_throw = 0;
if (! setjmp (read_alarm_throw))
nread = (*read_socket_hook) (0, buf, 256, 1);
else
nread = -1;
for (i = 0; i < nread; i++)
{
kbd_buffer_store_event (&buf[i]);
if (buf[i].kind == ascii_keystroke
&& buf[i].code == quit_char)
break;
}
}
else
{
char buf[3];
nread = read (fileno (stdin), buf, 1);
e.kind = ascii_keystroke;
e.frame_or_window = selected_frame;
e.modifiers = 0;
for (i = 0; i < nread; i++)
{
if (read_socket_hook == 0)
{
if (meta_key == 1 && (buf[i] & 0x80))
e.modifiers = meta_modifier;
if (meta_key != 2)
buf[i] &= ~0x80;
}
XSETINT (e.code, buf[i]);
kbd_buffer_store_event (&e);
if (buf[i] == quit_char)
break;
}
}
}
#endif
#endif
#endif
#ifdef BSD4_1
void
init_sigio (fd)
int fd;
{
if (noninteractive)
return;
lmode = LINTRUP | lmode;
ioctl (fd, TIOCLSET, &lmode);
}
void
reset_sigio ()
{
if (noninteractive)
return;
lmode = ~LINTRUP & lmode;
ioctl (0, TIOCLSET, &lmode);
}
void
request_sigio ()
{
sigrelse (SIGTINT);
interrupts_deferred = 0;
}
void
unrequest_sigio ()
{
sighold (SIGTINT);
interrupts_deferred = 1;
}
#ifdef subprocesses
int sigheld;
void
sigholdx (signum)
int signum;
{
sigheld |= sigbit (signum);
sighold (signum);
}
void
sigisheld (signum)
int signum;
{
sigheld |= sigbit (signum);
}
void
sigunhold (signum)
int signum;
{
sigheld &= ~sigbit (signum);
sigrelse (signum);
}
void
sigfree ()
{
int i;
for (i = 0; i < NSIG; i++)
if (sigheld & sigbit (i))
sigrelse (i);
sigheld = 0;
}
int
sigbit (i)
{
return 1 << (i - 1);
}
#endif
#endif
#ifdef POSIX_SIGNALS
sigset_t empty_mask, full_mask;
signal_handler_t
sys_signal (int signal_number, signal_handler_t action)
{
struct sigaction new_action, old_action;
sigemptyset (&new_action.sa_mask);
new_action.sa_handler = action;
#ifdef SA_RESTART
new_action.sa_flags = SA_RESTART;
#else
new_action.sa_flags = 0;
#endif
sigaction (signal_number, &new_action, &old_action);
return (old_action.sa_handler);
}
#ifndef __GNUC__
sigset_t
sys_sigmask (int sig)
{
sigset_t mask;
sigemptyset (&mask);
sigaddset (&mask, sig);
return mask;
}
#endif
sigset_t
sys_sigblock (sigset_t new_mask)
{
sigset_t old_mask;
sigprocmask (SIG_BLOCK, &new_mask, &old_mask);
return (old_mask);
}
sigset_t
sys_sigunblock (sigset_t new_mask)
{
sigset_t old_mask;
sigprocmask (SIG_UNBLOCK, &new_mask, &old_mask);
return (old_mask);
}
sigset_t
sys_sigsetmask (sigset_t new_mask)
{
sigset_t old_mask;
sigprocmask (SIG_SETMASK, &new_mask, &old_mask);
return (old_mask);
}
#endif
#if !defined HAVE_STRSIGNAL && !defined SYS_SIGLIST_DECLARED
static char *my_sys_siglist[NSIG];
# ifdef sys_siglist
# undef sys_siglist
# endif
# define sys_siglist my_sys_siglist
#endif
void
init_signals ()
{
#ifdef POSIX_SIGNALS
sigemptyset (&empty_mask);
sigfillset (&full_mask);
#endif
#if !defined HAVE_STRSIGNAL && !defined SYS_SIGLIST_DECLARED
if (! initialized)
{
# ifdef SIGABRT
sys_siglist[SIGABRT] = "Aborted";
# endif
# ifdef SIGAIO
sys_siglist[SIGAIO] = "LAN I/O interrupt";
# endif
# ifdef SIGALRM
sys_siglist[SIGALRM] = "Alarm clock";
# endif
# ifdef SIGBUS
sys_siglist[SIGBUS] = "Bus error";
# endif
# ifdef SIGCLD
sys_siglist[SIGCLD] = "Child status changed";
# endif
# ifdef SIGCHLD
sys_siglist[SIGCHLD] = "Child status changed";
# endif
# ifdef SIGCONT
sys_siglist[SIGCONT] = "Continued";
# endif
# ifdef SIGDANGER
sys_siglist[SIGDANGER] = "Swap space dangerously low";
# endif
# ifdef SIGDGNOTIFY
sys_siglist[SIGDGNOTIFY] = "Notification message in queue";
# endif
# ifdef SIGEMT
sys_siglist[SIGEMT] = "Emulation trap";
# endif
# ifdef SIGFPE
sys_siglist[SIGFPE] = "Arithmetic exception";
# endif
# ifdef SIGFREEZE
sys_siglist[SIGFREEZE] = "SIGFREEZE";
# endif
# ifdef SIGGRANT
sys_siglist[SIGGRANT] = "Monitor mode granted";
# endif
# ifdef SIGHUP
sys_siglist[SIGHUP] = "Hangup";
# endif
# ifdef SIGILL
sys_siglist[SIGILL] = "Illegal instruction";
# endif
# ifdef SIGINT
sys_siglist[SIGINT] = "Interrupt";
# endif
# ifdef SIGIO
sys_siglist[SIGIO] = "I/O possible";
# endif
# ifdef SIGIOINT
sys_siglist[SIGIOINT] = "I/O intervention required";
# endif
# ifdef SIGIOT
sys_siglist[SIGIOT] = "IOT trap";
# endif
# ifdef SIGKILL
sys_siglist[SIGKILL] = "Killed";
# endif
# ifdef SIGLOST
sys_siglist[SIGLOST] = "Resource lost";
# endif
# ifdef SIGLWP
sys_siglist[SIGLWP] = "SIGLWP";
# endif
# ifdef SIGMSG
sys_siglist[SIGMSG] = "Monitor mode data available";
# endif
# ifdef SIGPHONE
sys_siglist[SIGWIND] = "SIGPHONE";
# endif
# ifdef SIGPIPE
sys_siglist[SIGPIPE] = "Broken pipe";
# endif
# ifdef SIGPOLL
sys_siglist[SIGPOLL] = "Pollable event occurred";
# endif
# ifdef SIGPROF
sys_siglist[SIGPROF] = "Profiling timer expired";
# endif
# ifdef SIGPTY
sys_siglist[SIGPTY] = "PTY I/O interrupt";
# endif
# ifdef SIGPWR
sys_siglist[SIGPWR] = "Power-fail restart";
# endif
# ifdef SIGQUIT
sys_siglist[SIGQUIT] = "Quit";
# endif
# ifdef SIGRETRACT
sys_siglist[SIGRETRACT] = "Need to relinguish monitor mode";
# endif
# ifdef SIGSAK
sys_siglist[SIGSAK] = "Secure attention";
# endif
# ifdef SIGSEGV
sys_siglist[SIGSEGV] = "Segmentation violation";
# endif
# ifdef SIGSOUND
sys_siglist[SIGSOUND] = "Sound completed";
# endif
# ifdef SIGSTOP
sys_siglist[SIGSTOP] = "Stopped (signal)";
# endif
# ifdef SIGSTP
sys_siglist[SIGSTP] = "Stopped (user)";
# endif
# ifdef SIGSYS
sys_siglist[SIGSYS] = "Bad argument to system call";
# endif
# ifdef SIGTERM
sys_siglist[SIGTERM] = "Terminated";
# endif
# ifdef SIGTHAW
sys_siglist[SIGTHAW] = "SIGTHAW";
# endif
# ifdef SIGTRAP
sys_siglist[SIGTRAP] = "Trace/breakpoint trap";
# endif
# ifdef SIGTSTP
sys_siglist[SIGTSTP] = "Stopped (user)";
# endif
# ifdef SIGTTIN
sys_siglist[SIGTTIN] = "Stopped (tty input)";
# endif
# ifdef SIGTTOU
sys_siglist[SIGTTOU] = "Stopped (tty output)";
# endif
# ifdef SIGURG
sys_siglist[SIGURG] = "Urgent I/O condition";
# endif
# ifdef SIGUSR1
sys_siglist[SIGUSR1] = "User defined signal 1";
# endif
# ifdef SIGUSR2
sys_siglist[SIGUSR2] = "User defined signal 2";
# endif
# ifdef SIGVTALRM
sys_siglist[SIGVTALRM] = "Virtual timer expired";
# endif
# ifdef SIGWAITING
sys_siglist[SIGWAITING] = "Process's LWPs are blocked";
# endif
# ifdef SIGWINCH
sys_siglist[SIGWINCH] = "Window size changed";
# endif
# ifdef SIGWIND
sys_siglist[SIGWIND] = "SIGWIND";
# endif
# ifdef SIGXCPU
sys_siglist[SIGXCPU] = "CPU time limit exceeded";
# endif
# ifdef SIGXFSZ
sys_siglist[SIGXFSZ] = "File size limit exceeded";
# endif
}
#endif
}
#ifndef HAVE_RANDOM
#ifdef random
#define HAVE_RANDOM
#endif
#endif
#ifndef RAND_BITS
# ifdef HAVE_RANDOM
# define RAND_BITS 31
# else
# ifdef HAVE_LRAND48
# define RAND_BITS 31
# define random lrand48
# else
# define RAND_BITS 15
# if RAND_MAX == 32767
# define random rand
# else
# if RAND_MAX == 2147483647
# define random() (rand () >> 16)
# else
# ifdef USG
# define random rand
# else
# define random() (rand () >> 16)
# endif
# endif
# endif
# endif
# endif
#endif
void
seed_random (arg)
long arg;
{
#ifdef HAVE_RANDOM
srandom ((unsigned int)arg);
#else
# ifdef HAVE_LRAND48
srand48 (arg);
# else
srand ((unsigned int)arg);
# endif
#endif
}
long
get_random ()
{
long val = random ();
#if VALBITS > RAND_BITS
val = (val << RAND_BITS) ^ random ();
#if VALBITS > 2*RAND_BITS
val = (val << RAND_BITS) ^ random ();
#if VALBITS > 3*RAND_BITS
val = (val << RAND_BITS) ^ random ();
#if VALBITS > 4*RAND_BITS
val = (val << RAND_BITS) ^ random ();
#endif
#endif
#endif
#endif
return val & ((1L << VALBITS) - 1);
}
#ifdef WRONG_NAME_INSQUE
insque (q,p)
caddr_t q,p;
{
_insque (q,p);
}
#endif
#ifdef VMS
#ifdef getenv
#undef getenv
char *
sys_getenv (name)
char *name;
{
register char *val;
static char buf[256];
static struct dsc$descriptor_s equiv
= {sizeof (buf), DSC$K_DTYPE_T, DSC$K_CLASS_S, buf};
static struct dsc$descriptor_s d_name
= {0, DSC$K_DTYPE_T, DSC$K_CLASS_S, 0};
short eqlen;
if (!strcmp (name, "TERM"))
{
val = (char *) getenv ("EMACS_TERM");
if (val)
return val;
}
d_name.dsc$w_length = strlen (name);
d_name.dsc$a_pointer = name;
if (LIB$SYS_TRNLOG (&d_name, &eqlen, &equiv) == 1)
{
char *str = (char *) xmalloc (eqlen + 1);
bcopy (buf, str, eqlen);
str[eqlen] = '\0';
return str;
}
return (char *) getenv (name);
}
#endif
#ifdef abort
#undef abort
sys_abort ()
{
reset_sys_modes ();
LIB$SIGNAL (SS$_DEBUG);
}
#endif
#endif
#ifdef VMS
#ifdef LINK_CRTL_SHARE
#ifdef SHARABLE_LIB_BUG
int sys_nerr = 35;
char *sys_errlist[] =
{
"error 0",
"not owner",
"no such file or directory",
"no such process",
"interrupted system call",
"i/o error",
"no such device or address",
"argument list too long",
"exec format error",
"bad file number",
"no child process",
"no more processes",
"not enough memory",
"permission denied",
"bad address",
"block device required",
"mount devices busy",
"file exists",
"cross-device link",
"no such device",
"not a directory",
"is a directory",
"invalid argument",
"file table overflow",
"too many open files",
"not a typewriter",
"text file busy",
"file too big",
"no space left on device",
"illegal seek",
"read-only file system",
"too many links",
"broken pipe",
"math argument",
"result too large",
"I/O stream empty",
"vax/vms specific error code nontranslatable error"
};
#endif
#endif
#endif
#ifndef HAVE_STRERROR
#ifndef WINDOWSNT
char *
strerror (errnum)
int errnum;
{
extern char *sys_errlist[];
extern int sys_nerr;
if (errnum >= 0 && errnum < sys_nerr)
return sys_errlist[errnum];
return (char *) "Unknown error";
}
#endif
#endif
int
emacs_open (path, oflag, mode)
char *path;
int oflag, mode;
{
register int rtnval;
#ifdef BSD4_1
if (oflag & O_CREAT)
return creat (path, mode);
#endif
while ((rtnval = open (path, oflag, mode)) == -1
&& (errno == EINTR));
return (rtnval);
}
int
emacs_close (fd)
int fd;
{
int did_retry = 0;
register int rtnval;
while ((rtnval = close (fd)) == -1
&& (errno == EINTR))
did_retry = 1;
if (rtnval == -1 && did_retry && errno == EBADF)
return 0;
return rtnval;
}
int
emacs_read (fildes, buf, nbyte)
int fildes;
char *buf;
unsigned int nbyte;
{
register int rtnval;
while ((rtnval = read (fildes, buf, nbyte)) == -1
&& (errno == EINTR));
return (rtnval);
}
int
emacs_write (fildes, buf, nbyte)
int fildes;
char *buf;
unsigned int nbyte;
{
register int rtnval, bytes_written;
bytes_written = 0;
while (nbyte > 0)
{
rtnval = write (fildes, buf, nbyte);
if (rtnval == -1)
{
if (errno == EINTR)
continue;
else
return (bytes_written ? bytes_written : -1);
}
buf += rtnval;
nbyte -= rtnval;
bytes_written += rtnval;
}
return (bytes_written);
}
#ifdef USG
#ifndef MAXPATHLEN
#define MAXPATHLEN 1024
#endif
#ifndef HAVE_GETWD
char *
getwd (pathname)
char *pathname;
{
char *npath, *spath;
extern char *getcwd ();
BLOCK_INPUT;
spath = npath = getcwd ((char *) 0, MAXPATHLEN);
if (spath == 0)
{
UNBLOCK_INPUT;
return spath;
}
while (*npath && *npath != '/')
npath++;
strcpy (pathname, npath);
free (spath);
UNBLOCK_INPUT;
return pathname;
}
#endif
#ifndef HAVE_RENAME
rename (from, to)
const char *from;
const char *to;
{
if (access (from, 0) == 0)
{
unlink (to);
if (link (from, to) == 0)
if (unlink (from) == 0)
return (0);
}
return (-1);
}
#endif
#ifdef HPUX
#ifndef HAVE_PERROR
perror ()
{
}
#endif
#endif
#ifndef HAVE_DUP2
dup2 (oldd, newd)
int oldd;
int newd;
{
register int fd, ret;
emacs_close (newd);
#ifdef F_DUPFD
return fcntl (oldd, F_DUPFD, newd);
#else
fd = dup (old);
if (fd == -1)
return -1;
if (fd == new)
return new;
ret = dup2 (old,new);
emacs_close (fd);
return ret;
#endif
}
#endif
#ifdef subprocesses
#ifndef VMS
#ifndef HAVE_GETTIMEOFDAY
#ifdef HAVE_TIMEVAL
int
gettimeofday (tp, tzp)
struct timeval *tp;
struct timezone *tzp;
{
extern long time ();
tp->tv_sec = time ((long *)0);
tp->tv_usec = 0;
if (tzp != 0)
tzp->tz_minuteswest = -1;
return 0;
}
#endif
#endif
#endif
#endif
void
croak (badfunc)
char *badfunc;
{
printf ("%s not yet implemented\r\n", badfunc);
reset_sys_modes ();
exit (1);
}
#endif
#ifdef SYSV_SYSTEM_DIR
#include <dirent.h>
#if defined (BROKEN_CLOSEDIR) || !defined (HAVE_CLOSEDIR)
int
closedir (dirp)
register DIR *dirp;
{
int rtnval;
rtnval = emacs_close (dirp->dd_fd);
#if ! (defined (sun) && defined (USG5_4))
xfree ((char *) dirp->dd_buf);
#endif
xfree ((char *) dirp);
return rtnval;
}
#endif
#endif
#ifdef NONSYSTEM_DIR_LIBRARY
DIR *
opendir (filename)
char *filename;
{
register DIR *dirp;
register int fd;
struct stat sbuf;
fd = emacs_open (filename, O_RDONLY, 0);
if (fd < 0)
return 0;
BLOCK_INPUT;
if (fstat (fd, &sbuf) < 0
|| (sbuf.st_mode & S_IFMT) != S_IFDIR
|| (dirp = (DIR *) xmalloc (sizeof (DIR))) == 0)
{
emacs_close (fd);
UNBLOCK_INPUT;
return 0;
}
UNBLOCK_INPUT;
dirp->dd_fd = fd;
dirp->dd_loc = dirp->dd_size = 0;
return dirp;
}
void
closedir (dirp)
register DIR *dirp;
{
emacs_close (dirp->dd_fd);
xfree ((char *) dirp);
}
#ifndef VMS
#define DIRSIZ 14
struct olddir
{
ino_t od_ino;
char od_name[DIRSIZ];
};
#endif
struct direct dir_static;
struct direct *
readdir (dirp)
register DIR *dirp;
{
#ifndef VMS
register struct olddir *dp;
#else
register struct dir$_name *dp;
register struct dir$_version *dv;
#endif
for (; ;)
{
if (dirp->dd_loc >= dirp->dd_size)
dirp->dd_loc = dirp->dd_size = 0;
if (dirp->dd_size == 0
&& (dirp->dd_size = emacs_read (dirp->dd_fd, dirp->dd_buf, DIRBLKSIZ)) <= 0)
return 0;
#ifndef VMS
dp = (struct olddir *) &dirp->dd_buf[dirp->dd_loc];
dirp->dd_loc += sizeof (struct olddir);
if (dp->od_ino != 0)
{
dir_static.d_ino = dp->od_ino;
strncpy (dir_static.d_name, dp->od_name, DIRSIZ);
dir_static.d_name[DIRSIZ] = '\0';
dir_static.d_namlen = strlen (dir_static.d_name);
dir_static.d_reclen = sizeof (struct direct)
- MAXNAMLEN + 3
+ dir_static.d_namlen - dir_static.d_namlen % 4;
return &dir_static;
}
#else
dp = (struct dir$_name *) dirp->dd_buf;
if (dirp->dd_loc == 0)
dirp->dd_loc = (dp->dir$b_namecount&1) ? dp->dir$b_namecount + 1
: dp->dir$b_namecount;
dv = (struct dir$_version *)&dp->dir$t_name[dirp->dd_loc];
dir_static.d_ino = dv->dir$w_fid_num;
dir_static.d_namlen = dp->dir$b_namecount;
dir_static.d_reclen = sizeof (struct direct)
- MAXNAMLEN + 3
+ dir_static.d_namlen - dir_static.d_namlen % 4;
strncpy (dir_static.d_name, dp->dir$t_name, dp->dir$b_namecount);
dir_static.d_name[dir_static.d_namlen] = '\0';
dirp->dd_loc = dirp->dd_size;
return &dir_static;
#endif
}
}
#ifdef VMS
struct direct *
readdirver (dirp)
register DIR *dirp;
{
register struct dir$_name *dp;
register struct dir$_version *dv;
if (dirp->dd_loc >= dirp->dd_size - sizeof (struct dir$_name))
dirp->dd_loc = dirp->dd_size = 0;
if (dirp->dd_size == 0
&& (dirp->dd_size = sys_read (dirp->dd_fd, dirp->dd_buf, DIRBLKSIZ)) <= 0)
return 0;
dp = (struct dir$_name *) dirp->dd_buf;
if (dirp->dd_loc == 0)
dirp->dd_loc = (dp->dir$b_namecount & 1) ? dp->dir$b_namecount + 1
: dp->dir$b_namecount;
dv = (struct dir$_version *) &dp->dir$t_name[dirp->dd_loc];
strncpy (dir_static.d_name, dp->dir$t_name, dp->dir$b_namecount);
sprintf (&dir_static.d_name[dp->dir$b_namecount], ";%d", dv->dir$w_version);
dir_static.d_namlen = strlen (dir_static.d_name);
dir_static.d_ino = dv->dir$w_fid_num;
dir_static.d_reclen = sizeof (struct direct) - MAXNAMLEN + 3
+ dir_static.d_namlen - dir_static.d_namlen % 4;
dirp->dd_loc = ((char *) (++dv) - dp->dir$t_name);
return &dir_static;
}
#endif
#endif
int
set_file_times (filename, atime, mtime)
char *filename;
EMACS_TIME atime, mtime;
{
#ifdef HAVE_UTIMES
struct timeval tv[2];
tv[0] = atime;
tv[1] = mtime;
return utimes (filename, tv);
#else
struct utimbuf utb;
utb.actime = EMACS_SECS (atime);
utb.modtime = EMACS_SECS (mtime);
return utime (filename, &utb);
#endif
}
#ifndef HAVE_MKDIR
#ifdef MKDIR_PROTOTYPE
MKDIR_PROTOTYPE
#else
int
mkdir (dpath, dmode)
char *dpath;
int dmode;
#endif
{
int cpid, status, fd;
struct stat statbuf;
if (stat (dpath, &statbuf) == 0)
{
errno = EEXIST;
return -1;
}
if (errno != ENOENT)
return -1;
synch_process_alive = 1;
switch (cpid = fork ())
{
case -1:
return (-1);
case 0:
status = umask (0);
status = umask (status | (0777 & ~dmode));
fd = emacs_open ("/dev/null", O_RDWR, 0);
if (fd >= 0)
{
dup2 (fd, 0);
dup2 (fd, 1);
dup2 (fd, 2);
}
execl ("/bin/mkdir", "mkdir", dpath, (char *) 0);
_exit (-1);
default:
wait_for_termination (cpid);
}
if (synch_process_death != 0 || synch_process_retcode != 0)
{
errno = EIO;
return -1;
}
return 0;
}
#endif
#ifndef HAVE_RMDIR
int
rmdir (dpath)
char *dpath;
{
int cpid, status, fd;
struct stat statbuf;
if (stat (dpath, &statbuf) != 0)
{
return -1;
}
synch_process_alive = 1;
switch (cpid = fork ())
{
case -1:
return (-1);
case 0:
fd = emacs_open ("/dev/null", O_RDWR, 0);
if (fd >= 0)
{
dup2 (fd, 0);
dup2 (fd, 1);
dup2 (fd, 2);
}
execl ("/bin/rmdir", "rmdir", dpath, (char *) 0);
_exit (-1);
default:
wait_for_termination (cpid);
}
if (synch_process_death != 0 || synch_process_retcode != 0)
{
errno = EIO;
return -1;
}
return 0;
}
#endif
#ifdef VMS
#include "vms-pwd.h"
#include <acldef.h>
#include <chpdef.h>
#include <jpidef.h>
char *
vmserrstr (status)
int status;
{
int bufadr[2];
short len;
static char buf[257];
bufadr[0] = sizeof buf - 1;
bufadr[1] = (int) buf;
if (! (SYS$GETMSG (status, &len, bufadr, 0x1, 0) & 1))
return "untranslatable VMS error status";
buf[len] = '\0';
return buf;
}
#ifdef access
#undef access
#ifdef VMS4_4
#define DESCRIPTOR(name,string) struct dsc$descriptor_s name = \
{ strlen (string), DSC$K_DTYPE_T, DSC$K_CLASS_S, string }
typedef union {
struct {
unsigned short s_buflen;
unsigned short s_code;
char *s_bufadr;
unsigned short *s_retlenadr;
} s;
int end;
} item;
#define buflen s.s_buflen
#define code s.s_code
#define bufadr s.s_bufadr
#define retlenadr s.s_retlenadr
#define R_OK 4
#define W_OK 2
#define X_OK 1
#define F_OK 0
int
sys_access (path, mode)
char *path;
int mode;
{
static char *user = NULL;
char dir_fn[512];
if (directory_file_name (path, dir_fn))
path = dir_fn;
if (mode == F_OK)
return access (path, mode);
if (user == NULL && (user = (char *) getenv ("USER")) == NULL)
return -1;
{
int stat;
int flags;
int acces;
unsigned short int dummy;
item itemlst[3];
static int constant = ACL$C_FILE;
DESCRIPTOR (path_desc, path);
DESCRIPTOR (user_desc, user);
flags = 0;
acces = 0;
if ((mode & X_OK) && ((stat = access (path, mode)) < 0 || mode == X_OK))
return stat;
if (mode & R_OK)
acces |= CHP$M_READ;
if (mode & W_OK)
acces |= CHP$M_WRITE;
itemlst[0].buflen = sizeof (int);
itemlst[0].code = CHP$_FLAGS;
itemlst[0].bufadr = (char *) &flags;
itemlst[0].retlenadr = &dummy;
itemlst[1].buflen = sizeof (int);
itemlst[1].code = CHP$_ACCESS;
itemlst[1].bufadr = (char *) &acces;
itemlst[1].retlenadr = &dummy;
itemlst[2].end = CHP$_END;
stat = SYS$CHECK_ACCESS (&constant, &path_desc, &user_desc, itemlst);
return stat == SS$_NORMAL ? 0 : -1;
}
}
#else
#include <prvdef.h>
#define ACE$M_WRITE 2
#define ACE$C_KEYID 1
static unsigned short memid, grpid;
static unsigned int uic;
void
sys_access_reinit ()
{
uic = 0;
}
int
sys_access (filename, type)
char * filename;
int type;
{
struct FAB fab;
struct XABPRO xab;
int status, size, i, typecode, acl_controlled;
unsigned int *aclptr, *aclend, aclbuf[60];
union prvdef prvmask;
if (uic == 0)
{
status = LIB$GETJPI (&JPI$_UIC, 0, 0, &uic, 0, 0);
if (! (status & 1))
return -1;
memid = uic & 0xFFFF;
grpid = uic >> 16;
}
if (type != 2)
return access (filename, type);
#define CHECKPRIV(bit) (prvmask.bit)
#define WRITABLE(field) (! ((xab.xab$w_pro >> field) & XAB$M_NOWRITE))
status = SYS$SETPRV (0, 0, 0, prvmask);
if (! (status & 1))
error ("Unable to find privileges: %s", vmserrstr (status));
if (CHECKPRIV (PRV$V_BYPASS))
return 0;
fab = cc$rms_fab;
fab.fab$b_fac = FAB$M_GET;
fab.fab$l_fna = filename;
fab.fab$b_fns = strlen (filename);
fab.fab$l_xab = &xab;
xab = cc$rms_xabpro;
xab.xab$l_aclbuf = aclbuf;
xab.xab$w_aclsiz = sizeof (aclbuf);
status = SYS$OPEN (&fab, 0, 0);
if (! (status & 1))
return -1;
SYS$CLOSE (&fab, 0, 0);
if (CHECKPRIV (PRV$V_SYSPRV) && WRITABLE (XAB$V_SYS))
return 0;
acl_controlled = 0;
if (xab.xab$w_acllen > 0)
{
aclptr = aclbuf;
aclend = &aclbuf[xab.xab$w_acllen / 4];
while (*aclptr && aclptr < aclend)
{
size = (*aclptr & 0xff) / 4;
typecode = (*aclptr >> 8) & 0xff;
if (typecode == ACE$C_KEYID)
for (i = size - 1; i > 1; i--)
if (aclptr[i] == uic)
{
acl_controlled = 1;
if (aclptr[1] & ACE$M_WRITE)
return 0;
}
aclptr = &aclptr[size];
}
if (acl_controlled)
return -1;
}
if (WRITABLE (XAB$V_WLD))
return 0;
if (WRITABLE (XAB$V_GRP) &&
(unsigned short) (xab.xab$l_uic >> 16) == grpid)
return 0;
if (WRITABLE (XAB$V_OWN) &&
(xab.xab$l_uic & 0xFFFF) == memid)
return 0;
return -1;
}
#endif
#endif
static char vtbuf[NAM$C_MAXRSS+1];
char *
sys_translate_vms (vfile)
char * vfile;
{
char * p;
char * targ;
if (!vfile)
return 0;
targ = vtbuf;
if (p = strchr (vfile, ':'))
{
*targ++ = '/';
while (vfile < p)
*targ++ = *vfile++;
vfile++;
*targ++ = '/';
}
p = vfile;
if (*p == '[' || *p == '<')
{
while (*++vfile != *p + 2)
switch (*vfile)
{
case '.':
if (vfile[-1] == *p)
*targ++ = '.';
*targ++ = '/';
break;
case '-':
*targ++ = '.';
*targ++ = '.';
break;
default:
*targ++ = *vfile;
break;
}
vfile++;
*targ++ = '/';
}
while (*vfile)
*targ++ = *vfile++;
return vtbuf;
}
static char utbuf[NAM$C_MAXRSS+1];
char *
sys_translate_unix (ufile)
char * ufile;
{
int slash_seen = 0;
char *p;
char * targ;
if (!ufile)
return 0;
targ = utbuf;
if (*ufile == '/')
{
ufile++;
}
while (*ufile)
{
switch (*ufile)
{
case '/':
if (slash_seen)
if (index (&ufile[1], '/'))
*targ++ = '.';
else
*targ++ = ']';
else
{
*targ++ = ':';
if (index (&ufile[1], '/'))
*targ++ = '[';
slash_seen = 1;
}
break;
case '.':
if (strncmp (ufile, "./", 2) == 0)
{
if (!slash_seen)
{
*targ++ = '[';
slash_seen = 1;
}
ufile++;
if (index (&ufile[1], '/'))
*targ++ = '.';
else
*targ++ = ']';
}
else if (strncmp (ufile, "../", 3) == 0)
{
if (!slash_seen)
{
*targ++ = '[';
slash_seen = 1;
}
*targ++ = '-';
ufile += 2;
if (index (&ufile[1], '/'))
*targ++ = '.';
else
*targ++ = ']';
}
else
*targ++ = *ufile;
break;
default:
*targ++ = *ufile;
break;
}
ufile++;
}
*targ = '\0';
return utbuf;
}
char *
getwd (pathname)
char *pathname;
{
char *ptr, *val;
extern char *getcwd ();
#define MAXPATHLEN 1024
ptr = xmalloc (MAXPATHLEN);
val = getcwd (ptr, MAXPATHLEN);
if (val == 0)
{
xfree (ptr);
return val;
}
strcpy (pathname, ptr);
xfree (ptr);
return pathname;
}
int
getppid ()
{
long item_code = JPI$_OWNER;
unsigned long parent_id;
int status;
if (((status = LIB$GETJPI (&item_code, 0, 0, &parent_id)) & 1) == 0)
{
errno = EVMSERR;
vaxc$errno = status;
return -1;
}
return parent_id;
}
#undef getuid
unsigned
sys_getuid ()
{
return (getgid () << 16) | getuid ();
}
#undef read
int
sys_read (fildes, buf, nbyte)
int fildes;
char *buf;
unsigned int nbyte;
{
return read (fildes, buf, (nbyte < MAXIOSIZE ? nbyte : MAXIOSIZE));
}
#if 0
int
sys_write (fildes, buf, nbyte)
int fildes;
char *buf;
unsigned int nbyte;
{
register int nwrote, rtnval = 0;
while (nbyte > MAXIOSIZE && (nwrote = write (fildes, buf, MAXIOSIZE)) > 0) {
nbyte -= nwrote;
buf += nwrote;
rtnval += nwrote;
}
if (nwrote < 0)
return rtnval ? rtnval : -1;
if ((nwrote = write (fildes, buf, nbyte)) < 0)
return rtnval ? rtnval : -1;
return (rtnval + nwrote);
}
#endif
#undef write
int
sys_write (fildes, buf, nbytes)
int fildes;
char *buf;
unsigned int nbytes;
{
register char *p;
register char *e;
int sum = 0;
struct stat st;
fstat (fildes, &st);
p = buf;
while (nbytes > 0)
{
int len, retval;
if (st.st_fab_rfm == FAB$C_FIX
&& ((st.st_fab_rat & (FAB$M_FTN | FAB$M_CR)) != 0))
{
len = st.st_fab_mrs;
retval = write (fildes, p, min (len, nbytes));
if (retval != len)
return -1;
retval++;
}
else
{
e = p + min (MAXIOSIZE, nbytes) - 1;
while (*e != '\n' && e > p) e--;
if (p == e)
e = p + min (MAXIOSIZE, nbytes) - 1;
len = e + 1 - p;
retval = write (fildes, p, len);
if (retval != len)
return -1;
}
p += retval;
sum += retval;
nbytes -= retval;
}
return sum;
}
static unsigned short int fab_final_pro;
int
creat_copy_attrs (old, new)
char *old, *new;
{
struct FAB fab = cc$rms_fab;
struct XABPRO xabpro;
char aclbuf[256];
extern int vms_stmlf_recfm;
if (old)
{
fab.fab$b_fac = FAB$M_GET;
fab.fab$l_fna = old;
fab.fab$b_fns = strlen (old);
fab.fab$l_xab = (char *) &xabpro;
xabpro = cc$rms_xabpro;
xabpro.xab$l_aclbuf = aclbuf;
xabpro.xab$w_aclsiz = sizeof aclbuf;
if (SYS$OPEN (&fab, 0, 0) & 1)
{
SYS$CLOSE (&fab, 0, 0);
fab.fab$l_alq = 0;
if (xabpro.xab$w_acllen > 0)
{
if (xabpro.xab$w_acllen > sizeof aclbuf)
{
xabpro.xab$l_aclbuf = (char *) alloca (xabpro.xab$w_acllen);
xabpro.xab$w_aclsiz = xabpro.xab$w_acllen;
if (SYS$OPEN (&fab, 0, 0) & 1)
SYS$CLOSE (&fab, 0, 0);
else
old = 0;
}
}
else
xabpro.xab$l_aclbuf = 0;
}
else
old = 0;
}
fab.fab$l_fna = new;
fab.fab$b_fns = strlen (new);
if (!old)
{
fab.fab$l_xab = 0;
fab.fab$b_rfm = vms_stmlf_recfm ? FAB$C_STMLF : FAB$C_VAR;
fab.fab$b_rat = FAB$M_CR;
}
if (old)
fab_final_pro = xabpro.xab$w_pro;
else
SYS$SETDFPROT (0, &fab_final_pro);
xabpro.xab$w_pro &= 0xff0f;
if (!(SYS$CREATE (&fab, 0, 0) & 1))
return -1;
SYS$CLOSE (&fab, 0, 0);
return open (new, O_WRONLY);
}
#ifdef creat
#undef creat
#include <varargs.h>
#ifdef __GNUC__
#ifndef va_count
#define va_count(X) ((X) = *(((int *) &(va_alist)) - 1))
#endif
#endif
int
sys_creat (va_alist)
va_dcl
{
va_list list_incrementer;
char *name;
int mode;
int rfd;
int fd;
int count;
struct stat st_buf;
char rfm[12];
char rat[15];
char mrs[13];
char fsz[13];
extern int vms_stmlf_recfm;
va_count (count);
va_start (list_incrementer);
name = va_arg (list_incrementer, char *);
mode = va_arg (list_incrementer, int);
if (count > 2)
rfd = va_arg (list_incrementer, int);
va_end (list_incrementer);
if (count > 2)
{
fstat (rfd, &st_buf);
switch (st_buf.st_fab_rfm)
{
case FAB$C_FIX:
strcpy (rfm, "rfm = fix");
sprintf (mrs, "mrs = %d", st_buf.st_fab_mrs);
strcpy (rat, "rat = ");
if (st_buf.st_fab_rat & FAB$M_CR)
strcat (rat, "cr");
else if (st_buf.st_fab_rat & FAB$M_FTN)
strcat (rat, "ftn");
else if (st_buf.st_fab_rat & FAB$M_PRN)
strcat (rat, "prn");
if (st_buf.st_fab_rat & FAB$M_BLK)
if (st_buf.st_fab_rat & (FAB$M_CR|FAB$M_FTN|FAB$M_PRN))
strcat (rat, ", blk");
else
strcat (rat, "blk");
return creat (name, 0, rfm, rat, mrs);
case FAB$C_VFC:
strcpy (rfm, "rfm = vfc");
sprintf (fsz, "fsz = %d", st_buf.st_fab_fsz);
strcpy (rat, "rat = ");
if (st_buf.st_fab_rat & FAB$M_CR)
strcat (rat, "cr");
else if (st_buf.st_fab_rat & FAB$M_FTN)
strcat (rat, "ftn");
else if (st_buf.st_fab_rat & FAB$M_PRN)
strcat (rat, "prn");
if (st_buf.st_fab_rat & FAB$M_BLK)
if (st_buf.st_fab_rat & (FAB$M_CR|FAB$M_FTN|FAB$M_PRN))
strcat (rat, ", blk");
else
strcat (rat, "blk");
return creat (name, 0, rfm, rat, fsz);
case FAB$C_STM:
strcpy (rfm, "rfm = stm");
break;
case FAB$C_STMCR:
strcpy (rfm, "rfm = stmcr");
break;
case FAB$C_STMLF:
strcpy (rfm, "rfm = stmlf");
break;
case FAB$C_UDF:
strcpy (rfm, "rfm = udf");
break;
case FAB$C_VAR:
strcpy (rfm, "rfm = var");
break;
}
strcpy (rat, "rat = ");
if (st_buf.st_fab_rat & FAB$M_CR)
strcat (rat, "cr");
else if (st_buf.st_fab_rat & FAB$M_FTN)
strcat (rat, "ftn");
else if (st_buf.st_fab_rat & FAB$M_PRN)
strcat (rat, "prn");
if (st_buf.st_fab_rat & FAB$M_BLK)
if (st_buf.st_fab_rat & (FAB$M_CR|FAB$M_FTN|FAB$M_PRN))
strcat (rat, ", blk");
else
strcat (rat, "blk");
}
else
{
strcpy (rfm, vms_stmlf_recfm ? "rfm = stmlf" : "rfm=var");
strcpy (rat, "rat=cr");
}
fd = creat (name, 0, rfm, rat);
if (fd < 0 && errno == EEXIST)
{
if (unlink (name) < 0)
report_file_error ("delete", build_string (name));
fd = creat (name, 0, rfm, rat);
}
return fd;
}
#endif
int
sys_fwrite (ptr, size, num, fp)
register char * ptr;
FILE * fp;
{
register int tot = num * size;
while (tot--)
fputc (*ptr++, fp);
return num;
}
int
vms_truncate (fn)
char *fn;
{
struct FAB xfab = cc$rms_fab;
struct RAB xrab = cc$rms_rab;
int status;
xfab.fab$l_fop = FAB$M_TEF;
xfab.fab$b_fac = FAB$M_TRN | FAB$M_GET;
xfab.fab$b_shr = FAB$M_NIL;
xfab.fab$l_fna = fn;
xfab.fab$b_fns = strlen (fn);
xfab.fab$l_dna = ";0";
xfab.fab$b_dns = 2;
xrab.rab$l_fab = &xfab;
if ((SYS$OPEN (&xfab) & 01) == 01)
{
if ((SYS$CONNECT (&xrab) & 01) == 01 &&
(SYS$FIND (&xrab) & 01) == 01 &&
(SYS$TRUNCATE (&xrab) & 01) == 01)
status = 0;
else
status = -1;
}
else
status = -1;
SYS$CLOSE (&xfab);
return status;
}
#ifdef READ_SYSUAF
static struct UAF retuaf;
struct UAF *
get_uaf_name (uname)
char * uname;
{
register status;
struct FAB uaf_fab;
struct RAB uaf_rab;
uaf_fab = cc$rms_fab;
uaf_rab = cc$rms_rab;
uaf_fab.fab$l_fna = "SYS$SYSTEM:SYSUAF.DAT";
uaf_fab.fab$b_fns = 21;
uaf_fab.fab$b_fac = FAB$M_GET;
uaf_fab.fab$b_org = FAB$C_IDX;
uaf_fab.fab$b_shr = FAB$M_GET|FAB$M_PUT|FAB$M_UPD|FAB$M_DEL;
uaf_rab.rab$l_fab = &uaf_fab;
status = SYS$OPEN (&uaf_fab);
if (!(status&1))
{
errno = EVMSERR;
vaxc$errno = status;
return 0;
}
status = SYS$CONNECT (&uaf_rab);
if (!(status&1))
{
errno = EVMSERR;
vaxc$errno = status;
return 0;
}
uaf_rab.rab$l_kbf = uname;
uaf_rab.rab$b_ksz = strlen (uname);
uaf_rab.rab$b_rac = RAB$C_KEY;
uaf_rab.rab$l_ubf = (char *)&retuaf;
uaf_rab.rab$w_usz = sizeof retuaf;
status = SYS$GET (&uaf_rab);
if (!(status&1))
{
errno = EVMSERR;
vaxc$errno = status;
return 0;
}
status = SYS$DISCONNECT (&uaf_rab);
if (!(status&1))
{
errno = EVMSERR;
vaxc$errno = status;
return 0;
}
status = SYS$CLOSE (&uaf_fab);
if (!(status&1))
{
errno = EVMSERR;
vaxc$errno = status;
return 0;
}
return &retuaf;
}
struct UAF *
get_uaf_uic (uic)
unsigned long uic;
{
register status;
struct FAB uaf_fab;
struct RAB uaf_rab;
uaf_fab = cc$rms_fab;
uaf_rab = cc$rms_rab;
uaf_fab.fab$l_fna = "SYS$SYSTEM:SYSUAF.DAT";
uaf_fab.fab$b_fns = 21;
uaf_fab.fab$b_fac = FAB$M_GET;
uaf_fab.fab$b_org = FAB$C_IDX;
uaf_fab.fab$b_shr = FAB$M_GET|FAB$M_PUT|FAB$M_UPD|FAB$M_DEL;
uaf_rab.rab$l_fab = &uaf_fab;
status = SYS$OPEN (&uaf_fab);
if (!(status&1))
{
errno = EVMSERR;
vaxc$errno = status;
return 0;
}
status = SYS$CONNECT (&uaf_rab);
if (!(status&1))
{
errno = EVMSERR;
vaxc$errno = status;
return 0;
}
uaf_rab.rab$b_krf = 1;
uaf_rab.rab$l_kbf = (char *) &uic;
uaf_rab.rab$b_ksz = sizeof uic;
uaf_rab.rab$b_rac = RAB$C_KEY;
uaf_rab.rab$l_ubf = (char *)&retuaf;
uaf_rab.rab$w_usz = sizeof retuaf;
status = SYS$GET (&uaf_rab);
if (!(status&1))
{
errno = EVMSERR;
vaxc$errno = status;
return 0;
}
status = SYS$DISCONNECT (&uaf_rab);
if (!(status&1))
{
errno = EVMSERR;
vaxc$errno = status;
return 0;
}
status = SYS$CLOSE (&uaf_fab);
if (!(status&1))
{
errno = EVMSERR;
vaxc$errno = status;
return 0;
}
return &retuaf;
}
static struct passwd retpw;
struct passwd *
cnv_uaf_pw (up)
struct UAF * up;
{
char * ptr;
retpw.pw_uid = up->uaf$w_mem;
retpw.pw_gid = up->uaf$w_grp;
ptr = &up->uaf$t_username[UAF$S_USERNAME];
while (ptr[-1] == ' ')
ptr--;
*ptr = '\0';
strcpy (retpw.pw_name, up->uaf$t_username);
strncpy (retpw.pw_gecos, &up->uaf$t_owner[1], up->uaf$t_owner[0]);
retpw.pw_gecos[up->uaf$t_owner[0]] = '\0';
strncpy (retpw.pw_dir, &up->uaf$t_defdev[1], up->uaf$t_defdev[0]);
retpw.pw_dir[up->uaf$t_defdev[0]] = '\0';
strncat (retpw.pw_dir, &up->uaf$t_defdir[1], up->uaf$t_defdir[0]);
retpw.pw_dir[up->uaf$t_defdev[0] + up->uaf$t_defdir[0]] = '\0';
strncpy (retpw.pw_shell, &up->uaf$t_defcli[1], up->uaf$t_defcli[0]);
retpw.pw_shell[up->uaf$t_defcli[0]] = '\0';
return &retpw;
}
#else
static struct passwd retpw;
#endif
struct passwd *
getpwnam (name)
char * name;
{
#ifdef READ_SYSUAF
struct UAF *up;
#else
char * user;
char * dir;
unsigned char * full;
#endif
char *ptr = name;
while (*ptr)
{
if ('a' <= *ptr && *ptr <= 'z')
*ptr -= 040;
ptr++;
}
#ifdef READ_SYSUAF
if (!(up = get_uaf_name (name)))
return 0;
return cnv_uaf_pw (up);
#else
if (strcmp (name, getenv ("USER")) == 0)
{
retpw.pw_uid = getuid ();
retpw.pw_gid = getgid ();
strcpy (retpw.pw_name, name);
if (full = egetenv ("FULLNAME"))
strcpy (retpw.pw_gecos, full);
else
*retpw.pw_gecos = '\0';
strcpy (retpw.pw_dir, egetenv ("HOME"));
*retpw.pw_shell = '\0';
return &retpw;
}
else
return 0;
#endif
}
struct passwd *
getpwuid (uid)
unsigned long uid;
{
#ifdef READ_SYSUAF
struct UAF * up;
if (!(up = get_uaf_uic (uid)))
return 0;
return cnv_uaf_pw (up);
#else
if (uid == sys_getuid ())
return getpwnam (egetenv ("USER"));
else
return 0;
#endif
}
int
vlimit ()
{
int item_code;
unsigned long free_pages;
unsigned long frep0va;
unsigned long frep1va;
register status;
item_code = JPI$_FREPTECNT;
if (((status = LIB$GETJPI (&item_code, 0, 0, &free_pages)) & 1) == 0)
{
errno = EVMSERR;
vaxc$errno = status;
return -1;
}
free_pages *= 512;
item_code = JPI$_FREP0VA;
if (((status = LIB$GETJPI (&item_code, 0, 0, &frep0va)) & 1) == 0)
{
errno = EVMSERR;
vaxc$errno = status;
return -1;
}
item_code = JPI$_FREP1VA;
if (((status = LIB$GETJPI (&item_code, 0, 0, &frep1va)) & 1) == 0)
{
errno = EVMSERR;
vaxc$errno = status;
return -1;
}
return free_pages + frep0va + (0x7fffffff - frep1va);
}
int
define_logical_name (varname, string)
char *varname;
char *string;
{
struct dsc$descriptor_s strdsc =
{strlen (string), DSC$K_DTYPE_T, DSC$K_CLASS_S, string};
struct dsc$descriptor_s envdsc =
{strlen (varname), DSC$K_DTYPE_T, DSC$K_CLASS_S, varname};
struct dsc$descriptor_s lnmdsc =
{7, DSC$K_DTYPE_T, DSC$K_CLASS_S, "LNM$JOB"};
return LIB$SET_LOGICAL (&envdsc, &strdsc, &lnmdsc, 0, 0);
}
int
delete_logical_name (varname)
char *varname;
{
struct dsc$descriptor_s envdsc =
{strlen (varname), DSC$K_DTYPE_T, DSC$K_CLASS_S, varname};
struct dsc$descriptor_s lnmdsc =
{7, DSC$K_DTYPE_T, DSC$K_CLASS_S, "LNM$JOB"};
return LIB$DELETE_LOGICAL (&envdsc, &lnmdsc);
}
int
ulimit ()
{
return 0;
}
int
setpgrp ()
{
return 0;
}
int
execvp ()
{
error ("execvp system call not implemented");
return -1;
}
int
rename (from, to)
char *from, *to;
{
int status;
struct FAB from_fab = cc$rms_fab, to_fab = cc$rms_fab;
struct NAM from_nam = cc$rms_nam, to_nam = cc$rms_nam;
char from_esn[NAM$C_MAXRSS];
char to_esn[NAM$C_MAXRSS];
from_fab.fab$l_fna = from;
from_fab.fab$b_fns = strlen (from);
from_fab.fab$l_nam = &from_nam;
from_fab.fab$l_fop = FAB$M_NAM;
from_nam.nam$l_esa = from_esn;
from_nam.nam$b_ess = sizeof from_esn;
to_fab.fab$l_fna = to;
to_fab.fab$b_fns = strlen (to);
to_fab.fab$l_nam = &to_nam;
to_fab.fab$l_fop = FAB$M_NAM;
to_nam.nam$l_esa = to_esn;
to_nam.nam$b_ess = sizeof to_esn;
status = SYS$RENAME (&from_fab, 0, 0, &to_fab);
if (status & 1)
return 0;
else
{
if (status == RMS$_DEV)
errno = EXDEV;
else
errno = EVMSERR;
vaxc$errno = status;
return -1;
}
}
static struct fibdef fib;
char vms_file_written[NAM$C_MAXRSS];
int
rename_sans_version (from,to)
char *from, *to;
{
short int chan;
int stat;
short int iosb[4];
int status;
struct FAB to_fab = cc$rms_fab;
struct NAM to_nam = cc$rms_nam;
struct dsc$descriptor fib_d ={sizeof (fib),0,0,(char*) &fib};
struct dsc$descriptor fib_attr[2]
= {{sizeof (fab_final_pro),ATR$C_FPRO,0,(char*) &fab_final_pro},{0,0,0,0}};
char to_esn[NAM$C_MAXRSS];
$DESCRIPTOR (disk,to_esn);
to_fab.fab$l_fna = to;
to_fab.fab$b_fns = strlen (to);
to_fab.fab$l_nam = &to_nam;
to_fab.fab$l_fop = FAB$M_NAM;
to_nam.nam$l_esa = to_esn;
to_nam.nam$b_ess = sizeof to_esn;
status = SYS$PARSE (&to_fab, 0, 0);
if (to_nam.nam$l_fnb && NAM$M_EXP_VER)
*(to_nam.nam$l_ver) = '\0';
stat = rename (from, to_esn);
if (stat < 0)
return stat;
strcpy (vms_file_written, to_esn);
to_fab.fab$l_fna = vms_file_written;
to_fab.fab$b_fns = strlen (vms_file_written);
SYS$OPEN (&to_fab, 0, 0);
fib.fib$r_fid_overlay.fib$w_fid[0] = to_nam.nam$w_fid[0];
fib.fib$r_fid_overlay.fib$w_fid[1] = to_nam.nam$w_fid[1];
fib.fib$r_fid_overlay.fib$w_fid[2] = to_nam.nam$w_fid[2];
SYS$CLOSE (&to_fab, 0, 0);
stat = SYS$ASSIGN (&disk, &chan, 0, 0);
if (!stat)
LIB$SIGNAL (stat);
stat = SYS$QIOW (0, chan, IO$_MODIFY, iosb, 0, 0, &fib_d,
0, 0, 0, &fib_attr, 0);
if (!stat)
LIB$SIGNAL (stat);
stat = SYS$DASSGN (chan);
if (!stat)
LIB$SIGNAL (stat);
strcpy (vms_file_written, to_esn);
return 0;
}
int
link (file, new)
char * file, * new;
{
register status;
struct FAB fab;
struct NAM nam;
unsigned short fid[3];
char esa[NAM$C_MAXRSS];
fab = cc$rms_fab;
fab.fab$l_fop = FAB$M_OFP;
fab.fab$l_fna = file;
fab.fab$b_fns = strlen (file);
fab.fab$l_nam = &nam;
nam = cc$rms_nam;
nam.nam$l_esa = esa;
nam.nam$b_ess = NAM$C_MAXRSS;
status = SYS$PARSE (&fab);
if ((status & 1) == 0)
{
errno = EVMSERR;
vaxc$errno = status;
return -1;
}
status = SYS$SEARCH (&fab);
if ((status & 1) == 0)
{
errno = EVMSERR;
vaxc$errno = status;
return -1;
}
fid[0] = nam.nam$w_fid[0];
fid[1] = nam.nam$w_fid[1];
fid[2] = nam.nam$w_fid[2];
fab.fab$l_fna = new;
fab.fab$b_fns = strlen (new);
status = SYS$PARSE (&fab);
if ((status & 1) == 0)
{
errno = EVMSERR;
vaxc$errno = status;
return -1;
}
nam.nam$w_fid[0] = fid[0];
nam.nam$w_fid[1] = fid[1];
nam.nam$w_fid[2] = fid[2];
nam.nam$l_esa = nam.nam$l_name;
nam.nam$b_esl = nam.nam$b_name + nam.nam$b_type + nam.nam$b_ver;
status = SYS$ENTER (&fab);
if ((status & 1) == 0)
{
errno = EVMSERR;
vaxc$errno = status;
return -1;
}
return 0;
}
void
croak (badfunc)
char *badfunc;
{
printf ("%s not yet implemented\r\n", badfunc);
reset_sys_modes ();
exit (1);
}
long
random ()
{
return rand () - (1 << 30);
}
void
srandom (seed)
{
srand (seed);
}
#endif
#ifdef AIXHFT
void
hft_init ()
{
int junk;
#ifdef IBMR2AIX
if (ioctl (0, HFQERROR, &junk) < 0)
return;
#else
if (ioctl (0, HFQEIO, 0) < 0)
return;
#endif
{
struct hfbuf buf;
struct hfkeymap keymap;
buf.hf_bufp = (char *)&keymap;
buf.hf_buflen = sizeof (keymap);
keymap.hf_nkeys = 2;
keymap.hfkey[0].hf_kpos = 15;
keymap.hfkey[0].hf_kstate = HFMAPCHAR | HFSHFNONE;
#ifdef IBMR2AIX
keymap.hfkey[0].hf_keyidh = '<';
#else
keymap.hfkey[0].hf_page = '<';
#endif
keymap.hfkey[0].hf_char = 127;
keymap.hfkey[1].hf_kpos = 15;
keymap.hfkey[1].hf_kstate = HFMAPCHAR | HFSHFSHFT;
#ifdef IBMR2AIX
keymap.hfkey[1].hf_keyidh = '<';
#else
keymap.hfkey[1].hf_page = '<';
#endif
keymap.hfkey[1].hf_char = 127;
hftctl (0, HFSKBD, &buf);
}
line_ins_del_ok = char_ins_del_ok = 0;
}
void
hft_reset ()
{
struct hfbuf buf;
struct hfkeymap keymap;
int junk;
#ifdef IBMR2AIX
if (ioctl (0, HFQERROR, &junk) < 0)
return;
#else
if (ioctl (0, HFQEIO, 0) < 0)
return;
#endif
buf.hf_bufp = (char *)&keymap;
buf.hf_buflen = sizeof (keymap);
keymap.hf_nkeys = 2;
keymap.hfkey[0].hf_kpos = 15;
keymap.hfkey[0].hf_kstate = HFMAPCHAR | HFSHFNONE;
#ifdef IBMR2AIX
keymap.hfkey[0].hf_keyidh = '<';
#else
keymap.hfkey[0].hf_page = '<';
#endif
keymap.hfkey[0].hf_char = 8;
keymap.hfkey[1].hf_kpos = 15;
keymap.hfkey[1].hf_kstate = HFMAPCHAR | HFSHFSHFT;
#ifdef IBMR2AIX
keymap.hfkey[1].hf_keyidh = '<';
#else
keymap.hfkey[1].hf_page = '<';
#endif
keymap.hfkey[1].hf_char = 8;
hftctl (0, HFSKBD, &buf);
}
#endif
#ifdef USE_DL_STUBS
void *
dlopen ()
{
return 0;
}
void *
dlsym ()
{
return 0;
}
int
dlclose ()
{
return -1;
}
#endif
#ifndef BSTRING
#ifndef bzero
void
bzero (b, length)
register char *b;
register int length;
{
#ifdef VMS
short zero = 0;
long max_str = 65535;
while (length > max_str) {
(void) LIB$MOVC5 (&zero, &zero, &zero, &max_str, b);
length -= max_str;
b += max_str;
}
max_str = length;
(void) LIB$MOVC5 (&zero, &zero, &zero, &max_str, b);
#else
while (length-- > 0)
*b++ = 0;
#endif
}
#endif
#endif
#if (!defined (BSTRING) && !defined (bcopy)) || defined (NEED_BCOPY)
#undef bcopy
bcopy (b1, b2, length)
register char *b1;
register char *b2;
register int length;
{
#ifdef VMS
long max_str = 65535;
while (length > max_str) {
(void) LIB$MOVC3 (&max_str, b1, b2);
length -= max_str;
b1 += max_str;
b2 += max_str;
}
max_str = length;
(void) LIB$MOVC3 (&length, b1, b2);
#else
while (length-- > 0)
*b2++ = *b1++;
#endif
}
#endif
#ifndef BSTRING
#ifndef bcmp
int
bcmp (b1, b2, length)
register char *b1;
register char *b2;
register int length;
{
#ifdef VMS
struct dsc$descriptor_s src1 = {length, DSC$K_DTYPE_T, DSC$K_CLASS_S, b1};
struct dsc$descriptor_s src2 = {length, DSC$K_DTYPE_T, DSC$K_CLASS_S, b2};
return STR$COMPARE (&src1, &src2);
#else
while (length-- > 0)
if (*b1++ != *b2++)
return 1;
return 0;
#endif
}
#endif
#endif
#ifndef HAVE_STRSIGNAL
char *
strsignal (code)
int code;
{
char *signame = 0;
if (0 <= code && code < NSIG)
{
#ifdef VMS
signame = sys_errlist[code];
#else
signame = (char *) sys_siglist[code];
#endif
}
return signame;
}
#endif