X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/86a5659e6c48c4bd3213cbc626fb3ac6176c2793..9ab714c7b06a04e38d5d26b3beef45f138365b40:/src/sysdep.c diff --git a/src/sysdep.c b/src/sysdep.c index 01b9b07c07..167b9c398a 100644 --- a/src/sysdep.c +++ b/src/sysdep.c @@ -1,5 +1,5 @@ /* Interfaces to system-dependent kernel and library entries. - Copyright (C) 1985, 1986, 1987, 1988 Free Software Foundation, Inc. + Copyright (C) 1985, 1986, 1987, 1988, 1993 Free Software Foundation, Inc. This file is part of GNU Emacs. @@ -23,6 +23,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "config.h" #include "lisp.h" +#include "blockinput.h" #undef NULL #define min(x,y) ((x) > (y) ? (y) : (x)) @@ -51,6 +52,13 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #undef open #endif /* `open' is a macro */ +/* Does anyone other than VMS need this? */ +#ifndef fwrite +#define sys_fwrite fwrite +#else +#undef fwrite +#endif + #include #include #include @@ -90,8 +98,10 @@ extern char *sys_errlist[]; #include #endif #ifdef USG +#ifndef USG5 #include #endif +#endif #endif /* not 4.1 bsd */ /* Get DGUX definition for FASYNC - DJB */ @@ -100,10 +110,7 @@ extern char *sys_errlist[]; #endif /* DGUX */ #include - -#ifdef APOLLO -#undef TIOCSTART -#endif +#include "systty.h" #ifdef BSD #ifdef BSD4_1 @@ -113,76 +120,10 @@ extern char *sys_errlist[]; #endif /* not 4.1 */ #endif /* BSD */ -#ifdef AIX -/* Get files for keyboard remapping */ -#define HFNKEYS 2 -#include -#include -#endif - -/* Get rid of LLITOUT in 4.1, since it is said to stimulate kernel bugs. */ -#ifdef BSD4_1 -#undef LLITOUT -#define LLITOUT 0 -#endif /* 4.1 */ - -#ifdef HAVE_TERMIOS -#include -#include -#ifdef TIOCGETP -#undef TIOCGETP -#endif -#define TIOCGETP TCGETS -#undef TIOCSETN -#define TIOCSETN TCSETSW -#undef TIOCSETP -#define TIOCSETP TCSETSF -#undef TCSETAW -#define TCSETAW TCSETS -#define TERMINAL struct termios -#define OSPEED(str) (str.c_cflag & CBAUD) -#define SETOSPEED(str,new) (str.c_cflag = (str.c_cflag & ~CBAUD) | (new)) -#define TABS_OK(str) ((str.c_oflag & TABDLY) != TAB3) -#else -#define tcgetattr(fd, addr) ioctl (fd, TIOCGETP, addr) -#endif /* HAVE_TERMIOS */ - -#ifdef HAVE_TERMIO -#include -#undef TIOCGETP -#define TIOCGETP TCGETA -#undef TIOCSETN -/* Wait for output to finish before switching modes. - Otherwise screen can be garbaged. */ -#define TIOCSETN TCSETAW -#undef TIOCSETP -#define TIOCSETP TCSETAF -#define TERMINAL struct termio -#define OSPEED(str) (str.c_cflag & CBAUD) -#define SETOSPEED(str,new) (str.c_cflag = (str.c_cflag & ~CBAUD) | (new)) -#define TABS_OK(str) ((str.c_oflag & TABDLY) != TAB3) -#endif /* HAVE_TERMIO */ - -#ifdef BROKEN_TIOCGETC -#undef TIOCGETC /* Avoid confusing some conditionals that test this. */ -#endif - #ifdef BROKEN_TIOCGWINSZ #undef TIOCGWINSZ #endif -#ifndef HAVE_TERMIO -#ifndef VMS -#include -#define TERMINAL struct sgttyb -#define OSPEED(str) str.sg_ospeed -#define SETOSPEED(str,new) (str.sg_ospeed = (new)) -#define TABS_OK(str) ((str.sg_flags & XTABS) != XTABS) -#undef TCSETAW -#define TCSETAW TIOCSETN -#endif /* not VMS */ -#endif /* not HAVE_TERMIO */ - #ifdef USG #include #include @@ -198,41 +139,11 @@ extern char *sys_errlist[]; #include #endif #endif /* TIOCGWINSZ */ -#ifdef NEED_TIME_H -#include -#else /* not NEED_TIME_H */ -#ifdef HAVE_TIMEVAL -#include -#endif /* HAVE_TIMEVAL */ -#endif /* not NEED_TIME_H */ #endif /* USG */ -#ifdef NEED_BSDTTY -#include -#endif - -#if defined (HPUX) && defined (HAVE_PTYS) -#include -#endif - -#ifdef AIX -#include -#include -#endif /* AIX */ - -#ifdef SYSV_PTYS -#include -#include -#endif - -#ifdef BROKEN_FIONREAD -#undef FIONREAD -#undef FASYNC -#endif - extern int quit_char; -#include "screen.h" +#include "frame.h" #include "window.h" #include "termhooks.h" #include "termchar.h" @@ -244,23 +155,8 @@ extern int quit_char; #include "ndir.h" #endif /* NONSYSTEM_DIR_LIBRARY */ -#include "emacssignal.h" - -#ifndef sigunblock -#define sigunblock(SIG) \ -{ SIGMASKTYPE omask = sigblock (SIGEMPTYMASK); sigsetmask (omask & ~SIG); } -#endif - -/* Define SIGCHLD as an alias for SIGCLD. There are many conditionals - testing SIGCHLD. */ - -#ifndef VMS -#ifdef SIGCLD -#ifndef SIGCHLD -#define SIGCHLD SIGCLD -#endif /* not SIGCHLD */ -#endif /* SIGCLD */ -#endif /* not VMS */ +#include "syssignal.h" +#include "systime.h" static int baud_convert[] = #ifdef BAUD_CONVERT @@ -274,51 +170,15 @@ static int baud_convert[] = extern short ospeed; -#ifdef VMS -static struct iosb -{ - short status; - short offset; - short termlen; - short term; -} input_iosb; - -int kbd_input_ast (); - -int waiting_for_ast; -int stop_input; -int input_ef = 0; -int timer_ef = 0; -int process_ef = 0; -int input_eflist; -int timer_eflist; - -static int input_chan; -static $DESCRIPTOR (input_dsc, "TT"); -static int terminator_mask[2] = { 0, 0 }; - -static struct sensemode { - short status; - unsigned char xmit_baud; - unsigned char rcv_baud; - unsigned char crfill; - unsigned char lffill; - unsigned char parity; - unsigned char unused; - char class; - char type; - short scr_wid; - unsigned long tt_char : 24, scr_len : 8; - unsigned long tt2_char; -} sensemode_iosb; -#define TERMINAL struct sensemode -#define OSPEED(str) (str.xmit_baud) -#define TABS_OK(str) ((str.tt_char & TT$M_MECHTAB) != 0) -#endif /* VMS */ +/* The file descriptor for Emacs's input terminal. + Under Unix, this is always left zero; + under VMS, we place the input channel number here. + This allows us to write more code that works for both VMS and Unix. */ +static int input_fd; discard_tty_input () { - TERMINAL buf; + struct emacs_tty buf; if (noninteractive) return; @@ -330,8 +190,8 @@ discard_tty_input () #ifdef VMS end_kbd_input (); - SYS$QIOW (0, input_chan, IO$_READVBLK|IO$M_PURGE, input_iosb, 0, 0, - &buf, 0, 0, terminator_mask, 0, 0); + 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 /* not VMS */ #ifdef APOLLO @@ -340,12 +200,8 @@ discard_tty_input () ioctl (0, TIOCFLUSH, &zero); } #else /* not Apollo */ - tcgetattr (0, &buf); -#ifndef HAVE_TCATTR - ioctl (0, TIOCSETP, &buf); -#else - tcsetattr (0, TCSAFLUSH, &buf); -#endif + EMACS_GET_TTY (input_fd, &buf); + EMACS_SET_TTY (input_fd, &buf, 0); #endif /* not Apollo */ #endif /* not VMS */ } @@ -367,20 +223,43 @@ stuff_char (c) init_baud_rate () { - TERMINAL sg; - if (noninteractive) ospeed = 0; else { #ifdef VMS - SYS$QIOW (0, input_chan, IO$_SENSEMODE, &sg, 0, 0, + struct sensemode sg; + + SYS$QIOW (0, input_fd, IO$_SENSEMODE, &sg, 0, 0, &sg.class, 12, 0, 0, 0, 0 ); -#else - SETOSPEED (sg, B9600); + ospeed = sg.xmit_baud; +#else /* not VMS */ +#ifdef HAVE_TERMIOS + struct termios sg; + + sg.c_cflag = (sg.c_cflag & ~CBAUD) | B9600; + tcgetattr (0, &sg); + ospeed = sg.c_cflag & CBAUD; +#else /* neither VMS nor TERMIOS */ +#ifdef HAVE_TERMIO + struct termio sg; + + sg.c_cflag = (sg.c_cflag & ~CBAUD) | B9600; +#ifdef HAVE_TCATTR tcgetattr (0, &sg); +#else + ioctl (input_fd, TCGETA, &sg); +#endif + ospeed = sg.c_cflag & CBAUD; +#else /* neither VMS nor TERMIOS nor TERMIO */ + struct sgttyb sg; + + sg.sg_ospeed = B9600; + ioctl (0, TIOCGETP, &sg); + ospeed = sg.sg_ospeed; +#endif /* not HAVE_TERMIO */ +#endif /* not HAVE_TERMIOS */ #endif /* not VMS */ - ospeed = OSPEED (sg); } baud_rate = (ospeed < sizeof baud_convert / sizeof baud_convert[0] @@ -432,19 +311,62 @@ wait_for_termination (pid) #ifdef VMS int status; - status = sys$forcex (&pid, 0, 0); + status = SYS$FORCEX (&pid, 0, 0); break; #else /* not VMS */ - - /* Exit if the process has terminated. */ - if (!synch_process_alive) +#if (defined (BSD) && !defined (LINUX)) || (defined (HPUX) && !defined (HPUX_5)) + /* Note that kill returns -1 even if the process is just a zombie now. + But inevitably a SIGCHLD interrupt should be generated + and child_sig will do wait3 and make the process go away. */ + /* There is some indication that there is a bug involved with + termination of subprocesses, perhaps involving a kernel bug too, + but no idea what it is. Just as a hunch we signal SIGCHLD to see + if that causes the problem to go away or get worse. */ + sigsetmask (sigmask (SIGCHLD)); + if (0 > kill (pid, 0)) + { + sigsetmask (SIGEMPTYMASK); + kill (getpid (), SIGCHLD); + break; + } + if (wait_debugging) + sleep (1); + else + sigpause (SIGEMPTYMASK); +#else /* not BSD, not LINUX, and not HPUX version >= 6 */ +#if defined (UNIPLUS) || defined (LINUX) + if (0 > kill (pid, 0)) break; - /* Otherwise wait 1 second or until a signal comes in. */ - signal (SIGALRM, wait_for_termination_signal); - alarm (1); - pause (); - alarm (0); - signal (SIGALRM, SIG_IGN); + wait (0); +#else /* neither BSD nor UNIPLUS nor LINUX: random sysV */ +#ifdef POSIX_SIGNALS /* would this work for LINUX as well? */ + sigblock (sigmask (SIGCHLD)); + if (0 > kill (pid, 0)) + { + sigunblock (sigmask (SIGCHLD)); + break; + } + sigpause (sigmask (SIGCHLD)); +#else /* not POSIX_SIGNALS */ +#ifdef HAVE_SYSV_SIGPAUSE + sighold (SIGCHLD); + if (0 > kill (pid, 0)) + { + sigrelse (SIGCHLD); + break; + } + sigpause (SIGCHLD); +#else /* not HAVE_SYSV_SIGPAUSE */ + if (0 > kill (pid, 0)) + break; + /* Using sleep instead of pause avoids timing error. + If the inferior dies just before the sleep, + we lose just one second. */ + sleep (1); +#endif /* not HAVE_SYSV_SIGPAUSE */ +#endif /* not POSIX_SIGNALS */ +#endif /* not UNIPLUS */ +#endif /* not BSD, and not HPUX version >= 6 */ #endif /* not VMS */ #else /* not subprocesses */ #ifndef BSD4_1 @@ -498,57 +420,64 @@ flush_pending_output (channel) child_setup_tty (out) int out; { - TERMINAL s; + struct emacs_tty s; + + EMACS_GET_TTY (out, &s); + +#if defined (HAVE_TERMIO) || defined (HAVE_TERMIOS) + s.main.c_oflag |= OPOST; /* Enable output postprocessing */ + s.main.c_oflag &= ~ONLCR; /* Disable map of NL to CR-NL on output */ + s.main.c_oflag &= ~(NLDLY|CRDLY|TABDLY|BSDLY|VTDLY|FFDLY); + /* No output delays */ + s.main.c_lflag &= ~ECHO; /* Disable echo */ + s.main.c_lflag |= ISIG; /* Enable signals */ + s.main.c_iflag &= ~IUCLC; /* Disable map of upper case to lower on + input */ + s.main.c_oflag &= ~OLCUC; /* Disable map of lower case to upper on + output */ +#if 0 + /* Said to be unnecesary: */ + s.main.c_cc[VMIN] = 1; /* minimum number of characters to accept */ + s.main.c_cc[VTIME] = 0; /* wait forever for at least 1 character */ +#endif + + s.main.c_lflag |= ICANON; /* Enable erase/kill and eof processing */ + s.main.c_cc[VEOF] = 04; /* insure that EOF is Control-D */ + s.main.c_cc[VERASE] = 0377; /* disable erase processing */ + s.main.c_cc[VKILL] = 0377; /* disable kill processing */ - tcgetattr (out, &s); -#ifdef HAVE_TERMIO - s.c_oflag |= OPOST; /* Enable output postprocessing */ - s.c_oflag &= ~ONLCR; /* Disable map of NL to CR-NL on output */ - s.c_oflag &= ~(NLDLY|CRDLY|TABDLY|BSDLY|VTDLY|FFDLY); /* No output delays */ - s.c_lflag &= ~ECHO; /* Disable echo */ - s.c_lflag |= ISIG; /* Enable signals */ - s.c_iflag &= ~IUCLC; /* Disable map of upper case to lower on input */ - s.c_oflag &= ~OLCUC; /* Disable map of lower case to upper on output */ -/* said to be unnecesary - s.c_cc[VMIN] = 1; /* minimum number of characters to accept - s.c_cc[VTIME] = 0; /* wait forever for at least 1 character -*/ - s.c_lflag |= ICANON; /* Enable erase/kill and eof processing */ - s.c_cc[VEOF] = 04; /* insure that EOF is Control-D */ - s.c_cc[VERASE] = 0377; /* disable erase processing */ - s.c_cc[VKILL] = 0377; /* disable kill processing */ #ifdef HPUX - s.c_cflag = (s.c_cflag & ~CBAUD) | B9600; /* baud rate sanity */ + s.main.c_cflag = (s.main.c_cflag & ~CBAUD) | B9600; /* baud rate sanity */ #endif /* HPUX */ + #ifdef AIX /* AIX enhanced edit loses NULs, so disable it */ #ifndef IBMR2AIX - s.c_line = 0; - s.c_iflag &= ~ASCEDIT; + s.main.c_line = 0; + s.main.c_iflag &= ~ASCEDIT; #endif /* Also, PTY overloads NUL and BREAK. don't ignore break, but don't signal either, so it looks like NUL. */ - s.c_iflag &= ~IGNBRK; - s.c_iflag &= ~BRKINT; -/* QUIT and INTR work better as signals, so disable character forms */ - s.c_cc[VQUIT] = 0377; - s.c_cc[VINTR] = 0377; - s.c_cc[VEOL] = 0377; - s.c_lflag &= ~ISIG; - s.c_cflag = (s.c_cflag & ~CBAUD) | B9600; /* baud rate sanity */ + s.main.c_iflag &= ~IGNBRK; + s.main.c_iflag &= ~BRKINT; + /* QUIT and INTR work better as signals, so disable character forms */ + s.main.c_cc[VQUIT] = 0377; + s.main.c_cc[VINTR] = 0377; + s.main.c_cc[VEOL] = 0377; + s.main.c_lflag &= ~ISIG; + s.main.c_cflag = (s.main.c_cflag & ~CBAUD) | B9600; /* baud rate sanity */ #endif /* AIX */ #else /* not HAVE_TERMIO */ - s.sg_flags &= ~(ECHO | CRMOD | ANYP | ALLDELAY | RAW | LCASE | CBREAK | TANDEM); - s.sg_erase = 0377; - s.sg_kill = 0377; + + s.main.sg_flags &= ~(ECHO | CRMOD | ANYP | ALLDELAY | RAW | LCASE + | CBREAK | TANDEM); + s.main.sg_erase = 0377; + s.main.sg_kill = 0377; + #endif /* not HAVE_TERMIO */ -#ifndef HAVE_TCATTR - ioctl (out, TIOCSETN, &s); -#else - tcsetattr (out, TCSADRAIN, &s); -#endif + EMACS_SET_TTY (out, &s, 0); #ifdef BSD4_1 if (interrupt_input) @@ -569,15 +498,7 @@ child_setup_tty (out) setpgrp_of_tty (pid) int pid; { -#ifdef IBMR2AIX - tcsetpgrp ( 0, pid); -#else -#ifdef TIOCSPGRP - ioctl (0, TIOCSPGRP, &pid); -#else - /* Just ignore this for now and hope for the best */ -#endif -#endif + EMACS_SET_TTY_PGRP (input_fd, &pid); } /* Record a signal code and the handler for it. */ @@ -592,9 +513,26 @@ struct save_signal sys_suspend () { #ifdef VMS - unsigned long parent_id; + /* "Foster" parentage allows emacs to return to a subprocess that attached + to the current emacs as a cheaper than starting a whole new process. This + is set up by KEPTEDITOR.COM. */ + 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); /* On VMS, this was malloc'd */ - parent_id = getppid (); if (parent_id && parent_id != 0xffffffff) { SIGTYPE (*oldsig)() = (int) signal (SIGINT, SIG_IGN); @@ -610,18 +548,14 @@ sys_suspend () } d_prompt; d_prompt.l = sizeof ("Emacs: "); /* Our special prompt */ d_prompt.a = "Emacs: "; /* Just a reminder */ - lib$spawn (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &d_prompt, 0); + LIB$SPAWN (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &d_prompt, 0); return 1; } return -1; #else #ifdef SIGTSTP -#ifdef BSD - killpg (getpgrp (0), SIGTSTP); -#else - kill (-getpgrp (0), SIGTSTP); -#endif + EMACS_KILLPG (getpgrp (0), SIGTSTP); #else /* No SIGTSTP */ #ifdef USG_JOBCTRL /* If you don't know what this is don't mess with it */ @@ -683,13 +617,23 @@ sys_suspend () #ifdef subprocesses close_process_descs (); /* Close Emacs's pipes/ptys */ #endif - nice (-nice (0)); /* Give the new shell the default piority */ + +#ifdef PRIO_PROCESS + { + extern int emacs_priority; + + if (emacs_priority) + nice (-emacs_priority); + } +#endif + execlp (sh, sh, 0); write (1, "Can't execute subshell", 22); _exit (1); } save_signal_handlers (saved_handlers); + synch_process_alive = 1; wait_for_termination (pid); restore_signal_handlers (saved_handlers); @@ -703,7 +647,8 @@ save_signal_handlers (saved_handlers) { while (saved_handlers->code) { - saved_handlers->handler = signal (saved_handlers->code, SIG_IGN); + saved_handlers->handler + = (SIGTYPE (*) ()) signal (saved_handlers->code, SIG_IGN); saved_handlers++; } } @@ -790,26 +735,159 @@ unrequest_sigio () #endif /* FASYNC */ #endif /* F_SETFL */ -TERMINAL old_gtty; /* The initial tty mode bits */ +/* Getting and setting emacs_tty structures. */ + +/* Set *TC to the parameters associated with the terminal FD. + Return zero if all's well, or -1 if we ran into an error we + couldn't deal with. */ +int +emacs_get_tty (fd, settings) + int fd; + struct emacs_tty *settings; +{ + /* Retrieve the primary parameters - baud rate, character size, etcetera. */ +#ifdef HAVE_TCATTR + /* We have those nifty POSIX tcmumbleattr functions. */ + if (tcgetattr (fd, &settings->main) < 0) + return -1; + +#else +#ifdef HAVE_TERMIO + /* The SYSV-style interface? */ + if (ioctl (fd, TCGETA, &settings->main) < 0) + return -1; + +#else +#ifdef VMS + /* Vehemently Monstrous System? :-) */ + if (! (SYS$QIOW (0, fd, IO$_SENSEMODE, settings, 0, 0, + &settings->main.class, 12, 0, 0, 0, 0) + & 1)) + return -1; + +#else + /* I give up - I hope you have the BSD ioctls. */ + if (ioctl (fd, TIOCGETP, &settings->main) < 0) + return -1; + +#endif +#endif +#endif + + /* Suivant - Do we have to get struct ltchars data? */ +#ifdef HAVE_LTCHARS + if (ioctl (fd, TIOCGLTC, &settings->ltchars) < 0) + return -1; +#endif + + /* How about a struct tchars and a wordful of lmode bits? */ +#ifdef HAVE_TCHARS + if (ioctl (fd, TIOCGETC, &settings->tchars) < 0 + || ioctl (fd, TIOCLGET, &settings->lmode) < 0) + return -1; +#endif + + /* We have survived the tempest. */ + return 0; +} + + +/* Set the parameters of the tty on FD according to the contents of + *SETTINGS. If WAITP is non-zero, we wait for all queued output to + be written before making the change; otherwise, we forget any + queued input and make the change immediately. + Return 0 if all went well, and -1 if anything failed. */ +int +emacs_set_tty (fd, settings, waitp) + int fd; + struct emacs_tty *settings; + int waitp; +{ + /* Set the primary parameters - baud rate, character size, etcetera. */ +#ifdef HAVE_TCATTR + /* We have those nifty POSIX tcmumbleattr functions. + William J. Smith writes: + "POSIX 1003.1 defines tcsetattr() to return success if it was + able to perform any of the requested actions, even if some + of the requested actions could not be performed. + We must read settings back to ensure tty setup properly. + AIX requires this to keep tty from hanging occasionally." */ + for (;;) + if (tcsetattr (fd, waitp ? TCSAFLUSH : TCSADRAIN, &settings->main) < 0) + { + if (errno == EINTR) + continue; + else + return -1; + } + else + { + struct termios new; + + /* Get the current settings, and see if they're what we asked for. */ + tcgetattr (fd, &new); + if (memcmp (&new, &settings->main, sizeof (new))) + continue; + else + break; + } + +#else +#ifdef HAVE_TERMIO + /* The SYSV-style interface? */ + if (ioctl (fd, waitp ? TCSETAW : TCSETAF, &settings->main) < 0) + return -1; + +#else +#ifdef VMS + /* Vehemently Monstrous System? :-) */ + if (! (SYS$QIOW (0, fd, IO$_SETMODE, &input_iosb, 0, 0, + &settings->main.class, 12, 0, 0, 0, 0) + & 1)) + return -1; + +#else + /* I give up - I hope you have the BSD ioctls. */ + if (ioctl (fd, (waitp) ? TIOCSETP : TIOCSETN, &settings->main) < 0) + return -1; + +#endif +#endif +#endif + + /* Suivant - Do we have to get struct ltchars data? */ +#ifdef HAVE_LTCHARS + if (ioctl (fd, TIOCSLTC, &settings->ltchars) < 0) + return -1; +#endif + + /* How about a struct tchars and a wordful of lmode bits? */ +#ifdef HAVE_TCHARS + if (ioctl (fd, TIOCSETC, &settings->tchars) < 0 + || ioctl (fd, TIOCLSET, &settings->lmode) < 0) + return -1; +#endif + + /* We have survived the tempest. */ + return 0; +} + + +/* The initial tty mode bits */ +struct emacs_tty old_tty; int term_initted; /* 1 if outer tty status has been recorded */ +#ifdef BSD4_1 +/* BSD 4.1 needs to keep track of the lmode bits in order to start + sigio. */ +int lmode; +#endif + #ifdef F_SETOWN int old_fcntl_owner; #endif /* F_SETOWN */ -#ifdef TIOCGLTC -struct ltchars old_ltchars; -#endif /* TIOCGLTC */ - -#ifdef TIOCGETC -struct tchars old_tchars; -int old_lmode; - -int lmode; /* Current lmode value. */ - /* Needed as global for 4.1 */ -#endif /* TIOCGETC */ - /* This may also be defined in stdio, but if so, this does no harm, and using the same name avoids wasting the other one's space. */ @@ -820,19 +898,17 @@ unsigned char _sobuf[BUFSIZ+8]; char _sobuf[BUFSIZ]; #endif -#ifdef TIOCGLTC +#ifdef HAVE_LTCHARS static struct ltchars new_ltchars = {-1,-1,-1,-1,-1,-1}; #endif -#ifdef TIOCGETC +#ifdef HAVE_TCHARS static struct tchars new_tchars = {-1,-1,-1,-1,-1,-1}; #endif init_sys_modes () { - TERMINAL tty; -#ifdef TIOCGETC - struct tchars tchars; -#endif + struct emacs_tty tty; + #ifdef VMS #if 0 static int oob_chars[2] = {0, 1 << 7}; /* catch C-g's */ @@ -853,6 +929,7 @@ init_sys_modes () timer_ef = get_timer_event_flag (); /* LIB$GET_EF (&timer_ef); */ SYS$CLREF (timer_ef); +#if 0 if (!process_ef) { LIB$GET_EF (&process_ef); @@ -860,121 +937,159 @@ init_sys_modes () } 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 process event flags in different clusters."); + 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)); - SYS$QIOW (0, input_chan, IO$_SENSEMODE, &old_gtty, 0, 0, - &old_gtty.class, 12, 0, 0, 0, 0); #ifndef VMS4_4 sys_access_reinit (); #endif -#else /* not VMS */ - tcgetattr (0, &old_gtty); #endif /* not VMS */ + + EMACS_GET_TTY (input_fd, &old_tty); + if (!read_socket_hook && EQ (Vwindow_system, Qnil)) { - tty = old_gtty; + tty = old_tty; -#ifdef HAVE_TERMIO - tty.c_iflag |= (IGNBRK); /* Ignore break condition */ - tty.c_iflag &= ~ICRNL; /* Disable map of CR to NL on input */ +#if defined (HAVE_TERMIO) || defined (HAVE_TERMIOS) + tty.main.c_iflag |= (IGNBRK); /* Ignore break condition */ + tty.main.c_iflag &= ~ICRNL; /* Disable map of CR to NL on input */ #ifdef ISTRIP - tty.c_iflag &= ~ISTRIP; /* don't strip 8th bit on input */ + tty.main.c_iflag &= ~ISTRIP; /* don't strip 8th bit on input */ #endif - tty.c_lflag &= ~ECHO; /* Disable echo */ - tty.c_lflag &= ~ICANON; /* Disable erase/kill processing */ - tty.c_lflag |= ISIG; /* Enable signals */ + tty.main.c_lflag &= ~ECHO; /* Disable echo */ + tty.main.c_lflag &= ~ICANON; /* Disable erase/kill processing */ +#ifdef IEXTEN + tty.main.c_iflag &= ~IEXTEN; /* Disable other editing characters. */ +#endif + tty.main.c_lflag |= ISIG; /* Enable signals */ if (flow_control) { - tty.c_iflag |= IXON; /* Enable start/stop output control */ + tty.main.c_iflag |= IXON; /* Enable start/stop output control */ #ifdef IXANY - tty.c_iflag &= ~IXANY; + tty.main.c_iflag &= ~IXANY; #endif /* IXANY */ } else - tty.c_iflag &= ~IXON; /* Disable start/stop output control */ - tty.c_oflag &= ~ONLCR; /* Disable map of NL to CR-NL on output */ - tty.c_oflag &= ~TAB3; /* Disable tab expansion */ + tty.main.c_iflag &= ~IXON; /* Disable start/stop output control */ + tty.main.c_oflag &= ~ONLCR; /* Disable map of NL to CR-NL + on output */ + tty.main.c_oflag &= ~TAB3; /* Disable tab expansion */ #ifdef CS8 if (meta_key) { - tty.c_cflag |= CS8; /* allow 8th bit on input */ - tty.c_cflag &= ~PARENB;/* Don't check parity */ + tty.main.c_cflag |= CS8; /* allow 8th bit on input */ + tty.main.c_cflag &= ~PARENB;/* Don't check parity */ } #endif - tty.c_cc[VINTR] = quit_char; /* C-g (usually) gives SIGINT */ + tty.main.c_cc[VINTR] = quit_char; /* C-g (usually) gives SIGINT */ /* Set up C-g for both SIGQUIT and SIGINT. We don't know which we will get, but we handle both alike so which one it really gives us does not matter. */ - tty.c_cc[VQUIT] = quit_char; - tty.c_cc[VMIN] = 1; /* Input should wait for at least 1 char */ - tty.c_cc[VTIME] = 0; /* no matter how long that takes. */ + tty.main.c_cc[VQUIT] = quit_char; + tty.main.c_cc[VMIN] = 1; /* Input should wait for at least 1 char */ + tty.main.c_cc[VTIME] = 0; /* no matter how long that takes. */ #ifdef VSWTCH - tty.c_cc[VSWTCH] = CDEL; /* Turn off shell layering use of C-z */ + tty.main.c_cc[VSWTCH] = CDISABLE; /* Turn off shell layering use + of C-z */ #endif /* VSWTCH */ #if defined (mips) || defined (HAVE_TCATTR) - /* The following code looks like the right thing in general, - but it is said to cause a crash on USG V.4. - Let's play safe by turning it on only for the MIPS. */ #ifdef VSUSP - tty.c_cc[VSUSP] = CDEL; /* Turn off mips handling of C-z. */ + tty.main.c_cc[VSUSP] = CDISABLE; /* Turn off mips handling of C-z. */ #endif /* VSUSP */ #ifdef V_DSUSP - tty.c_cc[V_DSUSP] = CDEL; /* Turn off mips handling of C-y. */ + tty.main.c_cc[V_DSUSP] = CDISABLE; /* Turn off mips handling of C-y. */ #endif /* V_DSUSP */ +#ifdef VDSUSP /* Some systems have VDSUSP, some have V_DSUSP. */ + tty.main.c_cc[VDSUSP] = CDISABLE; +#endif /* VDSUSP */ #endif /* mips or HAVE_TCATTR */ #ifdef AIX #ifndef IBMR2AIX /* AIX enhanced edit loses NULs, so disable it */ - tty.c_line = 0; - tty.c_iflag &= ~ASCEDIT; + tty.main.c_line = 0; + tty.main.c_iflag &= ~ASCEDIT; #else - tty.c_cc[VSTRT] = 255; - tty.c_cc[VSTOP] = 255; - tty.c_cc[VSUSP] = 255; - tty.c_cc[VDSUSP] = 255; + 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 /* IBMR2AIX */ /* Also, PTY overloads NUL and BREAK. don't ignore break, but don't signal either, so it looks like NUL. This really serves a purpose only if running in an XTERM window or via TELNET or the like, but does no harm elsewhere. */ - tty.c_iflag &= ~IGNBRK; - tty.c_iflag &= ~BRKINT; + tty.main.c_iflag &= ~IGNBRK; + tty.main.c_iflag &= ~BRKINT; #endif #else /* if not HAVE_TERMIO */ #ifdef VMS - tty.tt_char |= TT$M_NOECHO; + tty.main.tt_char |= TT$M_NOECHO; if (meta_key) - tty.tt_char |= TT$M_EIGHTBIT + tty.main.tt_char |= TT$M_EIGHTBIT; if (flow_control) - tty.tt_char |= TT$M_TTSYNC; + tty.main.tt_char |= TT$M_TTSYNC; else - tty.tt_char &= ~TT$M_TTSYNC; - tty.tt2_char |= TT2$M_PASTHRU | TT2$M_XON; + tty.main.tt_char &= ~TT$M_TTSYNC; + tty.main.tt2_char |= TT2$M_PASTHRU | TT2$M_XON; #else /* not VMS (BSD, that is) */ - tty.sg_flags &= ~(ECHO | CRMOD | XTABS); + tty.main.sg_flags &= ~(ECHO | CRMOD | XTABS); if (meta_key) - tty.sg_flags |= ANYP; - tty.sg_flags |= interrupt_input ? RAW : CBREAK; + tty.main.sg_flags |= ANYP; + tty.main.sg_flags |= interrupt_input ? RAW : CBREAK; #endif /* not VMS (BSD, that is) */ #endif /* not HAVE_TERMIO */ -#ifdef VMS - SYS$QIOW (0, input_chan, IO$_SETMODE, &input_iosb, 0, 0, - &tty.class, 12, 0, 0, 0, 0); -#else -#ifndef HAVE_TCATTR - ioctl (0, TIOCSETN, &tty); -#else - tcsetattr (0, TCSADRAIN, &tty); + /* If going to use CBREAK mode, we must request C-g to interrupt + and turn off start and stop chars, etc. If not going to use + CBREAK mode, do this anyway so as to turn off local flow + control for user coming over network on 4.2; in this case, + only t_stopc and t_startc really matter. */ +#ifndef HAVE_TERMIO +#ifdef HAVE_TCHARS + /* Note: if not using CBREAK mode, it makes no difference how we + set this */ + tty.tchars = new_tchars; + tty.tchars.t_intrc = quit_char; + if (flow_control) + { + tty.tchars.t_startc = '\021'; + tty.tchars.t_stopc = '\023'; + } + +/* LPASS8 is new in 4.3, and makes cbreak mode provide all 8 bits. */ +#ifndef LPASS8 +#define LPASS8 0 #endif -#endif /* not VMS */ + +#ifdef BSD4_1 +#define LNOFLSH 0100000 +#endif + + tty.lmode = LDECCTQ | LLITOUT | LPASS8 | LNOFLSH | old_tty.lmode; + +#ifdef BSD4_1 + lmode = tty.lmode; +#endif + +#endif /* HAVE_TCHARS */ +#endif /* not HAVE_TERMIO */ + +#ifdef HAVE_LTCHARS + tty.ltchars = new_ltchars; +#endif /* HAVE_LTCHARS */ + + EMACS_SET_TTY (input_fd, &tty, 0); /* This code added to insure that, if flow-control is not to be used, - we have an unlocked screen at the start. */ + we have an unlocked terminal at the start. */ + #ifdef TCXONC if (!flow_control) ioctl (0, TCXONC, 1); #endif @@ -998,49 +1113,9 @@ init_sys_modes () #endif #endif - /* If going to use CBREAK mode, we must request C-g to interrupt - and turn off start and stop chars, etc. If not going to use - CBREAK mode, do this anyway so as to turn off local flow - control for user coming over network on 4.2; in this case, - only t_stopc and t_startc really matter. */ -#ifdef TIOCGLTC - ioctl (0, TIOCGLTC, &old_ltchars); -#endif /* TIOCGLTC */ -#ifndef HAVE_TERMIO -#ifdef TIOCGETC - ioctl (0, TIOCGETC, &old_tchars); - ioctl (0, TIOCLGET, &old_lmode); - - /* Note: if not using CBREAK mode, it makes no difference how we set this */ - tchars = new_tchars; - tchars.t_intrc = quit_char; - if (flow_control) - { - tchars.t_startc = '\021'; - tchars.t_stopc = '\023'; - } -/* LPASS8 is new in 4.3, and makes cbreak mode provide all 8 bits. */ -#ifndef LPASS8 -#define LPASS8 0 -#endif - -#ifdef BSD4_1 -#define LNOFLSH 0100000 -#endif - - lmode = LDECCTQ | LLITOUT | LPASS8 | LNOFLSH | old_lmode; - - ioctl (0, TIOCSETC, &tchars); - ioctl (0, TIOCLSET, &lmode); -#endif /* TIOCGETC */ -#endif /* not HAVE_TERMIO */ -#ifdef TIOCGLTC - ioctl (0, TIOCSLTC, &new_ltchars); -#endif /* TIOCGLTC */ - #ifdef VMS /* Appears to do nothing when in PASTHRU mode. - SYS$QIOW (0, input_chan, IO$_SETMODE|IO$M_OUTBAND, 0, 0, 0, + SYS$QIOW (0, input_fd, IO$_SETMODE|IO$M_OUTBAND, 0, 0, 0, interrupt_signal, oob_chars, 0, 0, 0, 0); */ queue_kbd_input (0); @@ -1082,12 +1157,13 @@ init_sys_modes () } else { - screen_garbaged = 1; -#ifdef MULTI_SCREEN - if (SCREENP (Vterminal_screen)) - SCREEN_GARBAGED_P (XSCREEN (Vterminal_screen)) = 1; + frame_garbaged = 1; +#ifdef MULTI_FRAME + if (FRAMEP (Vterminal_frame)) + FRAME_GARBAGED_P (XFRAME (Vterminal_frame)) = 1; #endif } + term_initted = 1; } @@ -1096,59 +1172,70 @@ init_sys_modes () tabs_safe_p () { - TERMINAL tty; - if (noninteractive) - return 1; -#ifdef VMS - SYS$QIOW (0, input_chan, IO$_SENSEMODE, &tty, 0, 0, - &tty.class, 12, 0, 0, 0, 0); -#else - tcgetattr (0, &tty); -#endif /* not VMS */ - return (TABS_OK (tty)); + struct emacs_tty tty; + + EMACS_GET_TTY (input_fd, &tty); + return EMACS_TTY_TABS_OK (&tty); } /* Get terminal size from system. Store number of lines into *heightp and width into *widthp. If zero or a negative number is stored, the value is not valid. */ -get_screen_size (widthp, heightp) +get_frame_size (widthp, heightp) int *widthp, *heightp; { -/* Define the 4.3 names in terms of the Sun names - if the latter exist and the former do not. */ -#ifdef TIOCGSIZE -#ifndef TIOCGWINSZ -#define TIOCGWINSZ TIOCGSIZE -#define winsize ttysize -#define ws_row ts_lines -#define ws_col ts_cols -#endif -#endif /* Sun */ -/* Do it using the 4.3 names if possible. */ #ifdef TIOCGWINSZ + + /* BSD-style. */ struct winsize size; - *widthp = 0; - *heightp = 0; - if (ioctl (0, TIOCGWINSZ, &size) < 0) - return; - *widthp = size.ws_col; - *heightp = size.ws_row; -#else /* not TIOCGWNSIZ */ + + if (ioctl (input_fd, TIOCGWINSZ, &size) == -1) + *widthp = *heightp = 0; + else + { + *widthp = size.ws_col; + *heightp = size.ws_row; + } + +#else +#ifdef TIOCGSIZE + + /* SunOS - style. */ + 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 - TERMINAL tty; - SYS$QIOW (0, input_chan, IO$_SENSEMODE, &tty, 0, 0, + + 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 /* system doesn't know size */ + *widthp = 0; *heightp = 0; -#endif /* system does not know size */ -#endif /* not TIOCGWINSZ */ + +#endif /* not VMS */ +#endif /* not SunOS-style */ +#endif /* not BSD-style */ } + +/* Prepare the terminal for exiting Emacs; move the cursor to the + bottom of the frame, turn off interrupt-driven I/O, etc. */ reset_sys_modes () { if (noninteractive) @@ -1160,10 +1247,10 @@ reset_sys_modes () return; if (read_socket_hook || !EQ (Vwindow_system, Qnil)) return; - cursor_to (SCREEN_HEIGHT (selected_screen) - 1, 0); - clear_end_of_line (SCREEN_WIDTH (selected_screen)); + cursor_to (FRAME_HEIGHT (selected_frame) - 1, 0); + clear_end_of_line (FRAME_WIDTH (selected_frame)); /* clear_end_of_line may move the cursor */ - cursor_to (SCREEN_HEIGHT (selected_screen) - 1, 0); + cursor_to (FRAME_HEIGHT (selected_frame) - 1, 0); #ifdef IBMR2AIX { /* HFT devices normally use ^J as a LF/CR. We forced it to @@ -1183,15 +1270,7 @@ reset_sys_modes () fsync (fileno (stdout)); #endif #endif -#ifdef TIOCGLTC - ioctl (0, TIOCSLTC, &old_ltchars); -#endif /* TIOCGLTC */ -#ifndef HAVE_TERMIO -#ifdef TIOCGETC - ioctl (0, TIOCSETC, &old_tchars); - ioctl (0, TIOCLSET, &old_lmode); -#endif /* TIOCGETC */ -#endif /* not HAVE_TERMIO */ + #ifdef F_SETFL #ifdef F_SETOWN /* F_SETFL does not imply existance of F_SETOWN */ if (interrupt_input) @@ -1205,17 +1284,9 @@ reset_sys_modes () if (interrupt_input) reset_sigio (); #endif /* BSD4_1 */ -#ifdef VMS - end_kbd_input (); - SYS$QIOW (0, input_chan, IO$_SETMODE, &input_iosb, 0, 0, - &old_gtty.class, 12, 0, 0, 0, 0); -#else /* not VMS */ -#ifndef HAVE_TCATTR - while (ioctl (0, TCSETAW, &old_gtty) < 0 && errno == EINTR); -#else - while (tcsetattr (0, TCSADRAIN, &old_gtty) < 0 && errno == EINTR); -#endif -#endif /* not VMS */ + + while (EMACS_SET_TTY (input_fd, &old_tty, 0) < 0 && errno == EINTR) + ; #ifdef AIX hft_reset (); @@ -1281,9 +1352,9 @@ init_vms_input () { int status; - if (input_chan == 0) + if (input_fd == 0) { - status = SYS$ASSIGN (&input_dsc, &input_chan, 0, 0); + status = SYS$ASSIGN (&input_dsc, &input_fd, 0, 0); if (! (status & 1)) LIB$STOP (status); } @@ -1293,7 +1364,7 @@ init_vms_input () stop_vms_input () { - return SYS$DASSGN (input_chan); + return SYS$DASSGN (input_fd); } short input_buffer; @@ -1304,9 +1375,11 @@ short input_buffer; queue_kbd_input () { int status; + extern kbd_input_ast (); + waiting_for_ast = 0; stop_input = 0; - status = SYS$QIO (0, input_chan, IO$_READVBLK, + status = SYS$QIO (0, input_fd, IO$_READVBLK, &input_iosb, kbd_input_ast, 1, &input_buffer, 1, 0, terminator_mask, 0, 0); } @@ -1320,7 +1393,7 @@ kbd_input_ast () { register int c = -1; int old_errno = errno; - extern int *input_available_clear_word; + extern EMACS_TIME *input_available_clear_time; if (waiting_for_ast) SYS$SETEF (input_ef); @@ -1352,13 +1425,16 @@ kbd_input_ast () { struct input_event e; e.kind = ascii_keystroke; - XSET (buf[i].code, Lisp_Int, cbuf[i]); - e.screen = selected_screen; + XSET (e.code, Lisp_Int, c); +#ifdef MULTI_FRAME + XSET(e.frame_or_window, Lisp_Frame, selected_frame); +#else + e.frame_or_window = Qnil; +#endif kbd_buffer_store_event (&e); } - - if (input_available_clear_word) - *input_available_clear_word = 0; + if (input_available_clear_time) + EMACS_SET_SECS_USECS (*input_available_clear_time, 0, 0); errno = old_errno; } @@ -1418,7 +1494,7 @@ end_kbd_input () #endif if (LIB$AST_IN_PROG ()) /* Don't wait if suspending from kbd_buffer_store_event! */ { - SYS$CANCEL (input_chan); + SYS$CANCEL (input_fd); return; } @@ -1427,7 +1503,7 @@ end_kbd_input () SYS$CLREF (input_ef); waiting_for_ast = 1; stop_input = 1; - SYS$CANCEL (input_chan); + SYS$CANCEL (input_fd); SYS$SETAST (1); SYS$WAITFR (input_ef); waiting_for_ast = 0; @@ -1573,10 +1649,22 @@ start_of_data () { #ifdef DATA_START return ((char *) DATA_START); +#else +#ifdef ORDINARY_LINK + /* + * This is a hack. Since we're not linking crt0.c or pre_crt0.c, + * data_start isn't defined. We take the address of environ, which + * is known to live at or near the start of the system crt0.c, and + * we don't sweat the handful of bytes that might lose. + */ + extern char **environ; + + return((char *) &environ); #else extern int data_start; return ((char *) &data_start); -#endif +#endif /* ORDINARY_LINK */ +#endif /* DATA_START */ } #endif /* NEED_STARTS (not CANNOT_DUMP or not SYSTEM_MALLOC) */ @@ -1624,17 +1712,38 @@ end_of_data () #include #endif +/* Can't have this within the function since `static' is #defined to + nothing for some USG systems. */ #ifdef USG -/* Can't have this within the function since `static' is #defined to nothing */ +#ifdef HAVE_GETHOSTNAME +static char get_system_name_name[256]; +#else /* not HAVE_GETHOSTNAME */ static struct utsname get_system_name_name; -#endif +#endif /* not HAVE_GETHOSTNAME */ +#endif /* USG */ + +#ifndef BSD4_1 +#ifndef USG +#ifndef VMS +#ifdef HAVE_SOCKETS +#include +#include +#endif /* HAVE_SOCKETS */ +#endif /* not VMS */ +#endif /* not USG */ +#endif /* not BSD4_1 */ char * get_system_name () { #ifdef USG +#ifdef HAVE_GETHOSTNAME + gethostname (get_system_name_name, sizeof (get_system_name_name)); + return get_system_name_name; +#else /* not HAVE_GETHOSTNAME */ uname (&get_system_name_name); return (get_system_name_name.nodename); +#endif /* not HAVE_GETHOSTNAME */ #else /* Not USG */ #ifdef BSD4_1 return sysname; @@ -1654,11 +1763,44 @@ get_system_name () strcpy (system_name_saved, sp); #else /* not VMS */ gethostname (system_name_saved, sizeof (system_name_saved)); +#ifdef HAVE_SOCKETS + /* Turn the hostname into the official, fully-qualified hostname. + Don't do this if we're going to dump; this can confuse system + libraries on some machines and make the dumped emacs core dump. */ +#ifndef CANNOT_DUMP + if (initialized) +#endif /* not CANNOT_DUMP */ + { + struct hostent *hp; + hp = gethostbyname (system_name_saved); + if (hp && strlen (hp->h_name) < sizeof(system_name_saved)) + strcpy (system_name_saved, hp->h_name); + } +#endif /* HAVE_SOCKETS */ #endif /* not VMS */ return system_name_saved; #endif /* not USG, not 4.1 */ #endif /* not USG */ } + +#ifdef VMS +#ifndef HAVE_GETHOSTNAME +void gethostname(buf, len) + char *buf; + int len; +{ + char *s; + s = getenv ("SYS$NODE"); + if (s == NULL) + buf[0] = '\0'; + else { + strncpy (buf, s, len - 2); + buf[len - 1] = '\0'; + } /* else */ +} /* static void gethostname */ +#endif /* ! HAVE_GETHOSTNAME */ +#endif /* VMS */ + #ifndef VMS #ifndef HAVE_SELECT @@ -1782,7 +1924,7 @@ select (nfds, rfds, wfds, efds, timeout) if (*local_timeout == 0 || ravail != 0 || process_tick != update_tick) break; old_alarm = alarm (0); - old_trap = (int (*)()) signal (SIGALRM, select_alarm); + old_trap = signal (SIGALRM, select_alarm); select_alarmed = 0; alarm (SELECT_PAUSE); /* Wait for a SIGALRM (or maybe a SIGTINT) */ @@ -1834,7 +1976,8 @@ read_input_waiting () { char buf[256 * BUFFER_SIZE_FACTOR]; struct input_event e; - int nread; + int nread, i; + extern int quit_char; if (read_socket_hook) { @@ -1849,14 +1992,15 @@ read_input_waiting () /* Scan the chars for C-g and store them in kbd_buffer. */ e.kind = ascii_keystroke; - e.screen = selected_screen; + e.frame_or_window = selected_frame; + e.modifiers = 0; for (i = 0; i < nread; i++) { XSET (e.code, Lisp_Int, buf[i]); kbd_buffer_store_event (&e); /* Don't look at input that follows a C-g too closely. This reduces lossage due to autorepeat on C-g. */ - if (buf[i] == Ctl ('G')) + if (buf[i] == quit_char) break; } } @@ -1865,12 +2009,6 @@ read_input_waiting () #endif /* not VMS */ #ifdef BSD4_1 -/* VARARGS */ -setpriority () -{ - return 0; -} - /* * Partially emulate 4.2 open call. * open is defined as this in 4.1. @@ -1971,14 +2109,10 @@ static struct sigaction new_action, old_action; init_signals () { -#ifdef POSIX_SIGNALS - sigemptyset (&signal_empty_mask); - sigfillset (&signal_full_mask); -#endif + sigemptyset (&empty_mask); + sigfillset (&full_mask); } -int (*signal_handler_t) (); - signal_handler_t sys_signal (int signal_number, signal_handler_t action) { @@ -1989,12 +2123,25 @@ sys_signal (int signal_number, signal_handler_t action) #else sigemptyset (&new_action.sa_mask); new_action.sa_handler = action; - new_action.sa_flags = NULL; - new_action (signal_number, &new_action, &old_action); + new_action.sa_flags = 0; + sigaction (signal_number, &new_action, &old_action); return (old_action.sa_handler); #endif /* DGUX */ } +#ifndef __GNUC__ +/* If we're compiling with GCC, we don't need this function, since it + can be written as a macro. */ +sigset_t +sys_sigmask (int sig) +{ + sigset_t mask; + sigemptyset (&mask); + sigaddset (&mask, sig); + return mask; +} +#endif + int sys_sigpause (sigset_t new_mask) { @@ -2103,6 +2250,7 @@ bcmp (b1, b2, length) /* This could be a macro! */ } #endif /* not BSTRING */ +#ifndef HAVE_RANDOM #ifdef USG /* * The BSD random returns numbers in the range of @@ -2139,6 +2287,7 @@ srandom (arg) srand (arg); } #endif /* BSD4_1 */ +#endif #ifdef WRONG_NAME_INSQUE @@ -2179,7 +2328,7 @@ sys_getenv (name) d_name.dsc$w_length = strlen (name); d_name.dsc$a_pointer = name; - if (lib$sys_trnlog (&d_name, &eqlen, &equiv) == 1) + if (LIB$SYS_TRNLOG (&d_name, &eqlen, &equiv) == 1) { char *str = (char *) xmalloc (eqlen + 1); bcopy (buf, str, eqlen); @@ -2333,6 +2482,7 @@ sys_write (fildes, buf, nbyte) * always negligible. Fred Fish, Unisoft Systems Inc. */ +#ifndef HAVE_SYS_SIGLIST char *sys_siglist[NSIG + 1] = { #ifdef AIX @@ -2393,6 +2543,7 @@ char *sys_siglist[NSIG + 1] = #endif /* not AIX */ 0 }; +#endif /* HAVE_SYS_SIGLIST */ /* * Warning, this function may not duplicate 4.2 action properly @@ -2413,6 +2564,7 @@ getwd (pathname) char *npath, *spath; extern char *getcwd (); + BLOCK_INPUT; /* getcwd uses malloc */ spath = npath = getcwd ((char *) 0, MAXPATHLEN); /* On Altos 3068, getcwd can return @hostname/dir, so discard up to first slash. Should be harmless on other systems. */ @@ -2420,6 +2572,7 @@ getwd (pathname) npath++; strcpy (pathname, npath); free (spath); /* getcwd uses malloc */ + UNBLOCK_INPUT; return pathname; } @@ -2431,6 +2584,8 @@ getwd (pathname) * that files be of same type (regular->regular, dir->dir, etc). */ +#ifndef HAVE_RENAME + rename (from, to) char *from; char *to; @@ -2445,17 +2600,7 @@ rename (from, to) return (-1); } -/* Set priority value to PRIO. */ - -void -setpriority (which, who, prio) - int which, who, prio; -{ - int nice (); - - nice (prio - nice (0)); - return (0); -} +#endif #ifndef HAVE_VFORK @@ -2569,7 +2714,8 @@ gettimeofday (tp, tzp) tp->tv_sec = time ((long *)0); tp->tv_usec = 0; - tzp->tz_minuteswest = -1; + if (tzp != 0) + tzp->tz_minuteswest = -1; } #endif @@ -2677,8 +2823,8 @@ closedir (dirp) register DIR *dirp; /* stream from opendir */ { sys_close (dirp->dd_fd); - free ((char *) dirp->dd_buf); /* directory block defined in */ - free ((char *) dirp); + xfree ((char *) dirp->dd_buf); /* directory block defined in */ + xfree ((char *) dirp); } #endif /* not AIX */ #endif /* SYSV_SYSTEM_DIR */ @@ -2697,13 +2843,16 @@ opendir (filename) if (fd < 0) return 0; + BLOCK_INPUT; if (fstat (fd, &sbuf) < 0 || (sbuf.st_mode & S_IFMT) != S_IFDIR || (dirp = (DIR *) malloc (sizeof (DIR))) == 0) { sys_close (fd); + UNBLOCK_INPUT; return 0; /* bad luck today */ } + UNBLOCK_INPUT; dirp->dd_fd = fd; dirp->dd_loc = dirp->dd_size = 0; /* refill needed */ @@ -2716,7 +2865,7 @@ closedir (dirp) register DIR *dirp; /* stream from opendir */ { sys_close (dirp->dd_fd); - free ((char *) dirp); + xfree ((char *) dirp); } @@ -2826,7 +2975,7 @@ readdirver (dirp) /* Functions for VMS */ #ifdef VMS -#include "pwd.h" +#include "vms-pwd.h" #include #include #include @@ -2976,7 +3125,7 @@ sys_access (filename, type) #define WRITEABLE(field) (! ((xab.xab$w_pro >> field) & XAB$M_NOWRITE)) /* Find privilege bits */ - status = sys$setprv (0, 0, 0, prvmask); + status = SYS$SETPRV (0, 0, 0, prvmask); if (! (status & 1)) error ("Unable to find privileges: %s", vmserrstr (status)); if (CHECKPRIV (PRV$V_BYPASS)) @@ -2989,10 +3138,10 @@ sys_access (filename, type) xab = cc$rms_xabpro; xab.xab$l_aclbuf = aclbuf; xab.xab$w_aclsiz = sizeof (aclbuf); - status = sys$open (&fab, 0, 0); + status = SYS$OPEN (&fab, 0, 0); if (! (status & 1)) return -1; - sys$close (&fab, 0, 0); + SYS$CLOSE (&fab, 0, 0); /* Check system access */ if (CHECKPRIV (PRV$V_SYSPRV) && WRITEABLE (XAB$V_SYS)) return 0; @@ -3176,16 +3325,16 @@ getwd (pathname) char *pathname; { char *ptr; - strcpy (pathname, egetenv ("PATH")); + extern char *getcwd (); - ptr = pathname; - while (*ptr) - { - if ('a' <= *ptr && *ptr <= 'z') - *ptr -= 040; - ptr++; - } - return pathname; +#define MAXPATHLEN 1024 + + ptr = xmalloc (MAXPATHLEN); + getcwd (ptr, MAXPATHLEN); + strcpy (pathname, ptr); + xfree (ptr); + + return pathname; } getppid () @@ -3257,19 +3406,38 @@ sys_write (fildes, buf, nbytes) { register char *p; register char *e; - int retval, sum; + int sum = 0; + struct stat st; + + fstat (fildes, &st); p = buf; - sum = 0; while (nbytes > 0) { - e = p + min (MAXIOSIZE, nbytes) - 1; - while (*e != '\n' && e > p) e--; - if (p == e) /* Ok.. so here we add a newline... sigh. */ - e = p + min (MAXIOSIZE, nbytes) - 1; - retval = write (fildes, p, e - p + 1); - if (retval != e - p + 1) return -1; - p = e + 1; - sum = sum + retval; + int len, retval; + + /* Handle fixed-length files with carriage control. */ + 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++; /* This skips the implied carriage control */ + } + else + { + e = p + min (MAXIOSIZE, nbytes) - 1; + while (*e != '\n' && e > p) e--; + if (p == e) /* Ok.. so here we add a newline... sigh. */ + 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; @@ -3302,9 +3470,9 @@ creat_copy_attrs (old, new) xabpro.xab$l_aclbuf = aclbuf; xabpro.xab$w_aclsiz = sizeof aclbuf; /* Call $OPEN to fill in the fab & xabpro fields. */ - if (sys$open (&fab, 0, 0) & 1) + if (SYS$OPEN (&fab, 0, 0) & 1) { - sys$close (&fab, 0, 0); + SYS$CLOSE (&fab, 0, 0); fab.fab$l_alq = 0; /* zero the allocation quantity */ if (xabpro.xab$w_acllen > 0) { @@ -3315,8 +3483,8 @@ creat_copy_attrs (old, new) { 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); + if (SYS$OPEN (&fab, 0, 0) & 1) + SYS$CLOSE (&fab, 0, 0); else old = 0; } @@ -3342,14 +3510,14 @@ creat_copy_attrs (old, new) if (old) fab_final_pro = xabpro.xab$w_pro; else - sys$setdfprot (0, &fab_final_pro); + SYS$SETDFPROT (0, &fab_final_pro); xabpro.xab$w_pro &= 0xff0f; /* set O:rewd for now. This is set back later. */ /* Create the new file with either default attrs or attrs copied from old file. */ if (!(SYS$CREATE (&fab, 0, 0) & 1)) return -1; - sys$close (&fab, 0, 0); + SYS$CLOSE (&fab, 0, 0); /* As this is a "replacement" for creat, return a file descriptor opened for writing. */ return open (new, O_WRONLY); @@ -3518,18 +3686,18 @@ vms_truncate (fn) /* This gibberish opens the file, positions to the first record, and deletes all records from there until the end of file. */ - if ((sys$open (&xfab) & 01) == 01) + if ((SYS$OPEN (&xfab) & 01) == 01) { - if ((sys$connect (&xrab) & 01) == 01 && - (sys$find (&xrab) & 01) == 01 && - (sys$truncate (&xrab) & 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); + SYS$CLOSE (&xfab); return status; } @@ -3565,14 +3733,14 @@ get_uaf_name (uname) /* initialize rab fields */ uaf_rab.rab$l_fab = &uaf_fab; /* open the User Authorization File */ - status = sys$open (&uaf_fab); + status = SYS$OPEN (&uaf_fab); if (!(status&1)) { errno = EVMSERR; vaxc$errno = status; return 0; } - status = sys$connect (&uaf_rab); + status = SYS$CONNECT (&uaf_rab); if (!(status&1)) { errno = EVMSERR; @@ -3585,7 +3753,7 @@ get_uaf_name (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); + status = SYS$GET (&uaf_rab); if (!(status&1)) { errno = EVMSERR; @@ -3593,14 +3761,14 @@ get_uaf_name (uname) return 0; } /* close the User Authorization File */ - status = sys$disconnect (&uaf_rab); + status = SYS$DISCONNECT (&uaf_rab); if (!(status&1)) { errno = EVMSERR; vaxc$errno = status; return 0; } - status = sys$close (&uaf_fab); + status = SYS$CLOSE (&uaf_fab); if (!(status&1)) { errno = EVMSERR; @@ -3629,14 +3797,14 @@ get_uaf_uic (uic) /* initialize rab fields */ uaf_rab.rab$l_fab = &uaf_fab; /* open the User Authorization File */ - status = sys$open (&uaf_fab); + status = SYS$OPEN (&uaf_fab); if (!(status&1)) { errno = EVMSERR; vaxc$errno = status; return 0; } - status = sys$connect (&uaf_rab); + status = SYS$CONNECT (&uaf_rab); if (!(status&1)) { errno = EVMSERR; @@ -3650,7 +3818,7 @@ get_uaf_uic (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); + status = SYS$GET (&uaf_rab); if (!(status&1)) { errno = EVMSERR; @@ -3658,14 +3826,14 @@ get_uaf_uic (uic) return 0; } /* close the User Authorization File */ - status = sys$disconnect (&uaf_rab); + status = SYS$DISCONNECT (&uaf_rab); if (!(status&1)) { errno = EVMSERR; vaxc$errno = status; return 0; } - status = sys$close (&uaf_fab); + status = SYS$CLOSE (&uaf_fab); if (!(status&1)) { errno = EVMSERR; @@ -3838,9 +4006,6 @@ delete_logical_name (varname) ulimit () {} -setpriority () -{} - setpgrp () {} @@ -3946,26 +4111,26 @@ rename_sans_version (from,to) to_fab.fab$b_fns = strlen (vms_file_written); /* Now set the file protection to the correct value */ - sys$open (&to_fab, 0, 0); /* This fills in the nam$w_fid fields */ + SYS$OPEN (&to_fab, 0, 0); /* This fills in the nam$w_fid fields */ /* Copy these fields into the fib */ 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); + SYS$CLOSE (&to_fab, 0, 0); - stat = sys$assign (&disk, &chan, 0, 0); /* open a channel to the disk */ + stat = SYS$ASSIGN (&disk, &chan, 0, 0); /* open a channel to the disk */ if (!stat) - lib$signal (stat); - stat = sys$qiow (0, chan, IO$_MODIFY, iosb, 0, 0, &fib_d, + 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); + LIB$SIGNAL (stat); + stat = SYS$DASSGN (chan); if (!stat) - lib$signal (stat); - strcpy (vms_file_written, to_esn); /* We will write this to the screen*/ + LIB$SIGNAL (stat); + strcpy (vms_file_written, to_esn); /* We will write this to the terminal*/ return 0; }