/* 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.
#include "config.h"
#include "lisp.h"
+#include "blockinput.h"
#undef NULL
#define min(x,y) ((x) > (y) ? (y) : (x))
#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 <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#endif
#ifdef USG
+#ifndef USG5
#include <fcntl.h>
#endif
+#endif
#endif /* not 4.1 bsd */
-/* Get DGUX definition for FASYNC - DJB */
-#ifdef DGUX
-#include <sys/file.h>
-#endif /* DGUX */
+#ifdef BROKEN_FASYNC
+/* On some systems (DGUX comes to mind real fast) FASYNC causes
+ background writes to the terminal to stop all processes in the
+ process group when invoked under the csh (and probably any shell
+ with job control). This stops Emacs dead in its tracks when coming
+ up under X11. */
+#undef FASYNC
+#endif
#include <sys/ioctl.h>
-
-#ifdef APOLLO
-#undef TIOCSTART
-#endif
+#include "systty.h"
#ifdef BSD
#ifdef BSD4_1
#endif /* not 4.1 */
#endif /* BSD */
-#ifdef AIX
-/* Get files for keyboard remapping */
-#define HFNKEYS 2
-#include <sys/hft.h>
-#include <sys/devinfo.h>
-#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 <termio.h>
-#include <termios.h>
-#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 <termio.h>
-#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 <sgtty.h>
-#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 <sys/utsname.h>
#include <string.h>
#include <sys/ptem.h>
#endif
#endif /* TIOCGWINSZ */
-#ifdef NEED_TIME_H
-#include <time.h>
-#else /* not NEED_TIME_H */
-#ifdef HAVE_TIMEVAL
-#include <sys/time.h>
-#endif /* HAVE_TIMEVAL */
-#endif /* not NEED_TIME_H */
#endif /* USG */
-#ifdef NEED_BSDTTY
-#include <sys/bsdtty.h>
-#endif
-
-#if defined (HPUX) && defined (HAVE_PTYS)
-#include <sys/ptyio.h>
-#endif
-
-#ifdef AIX
-#include <sys/pty.h>
-#include <unistd.h>
-#endif /* AIX */
-
-#ifdef SYSV_PTYS
-#include <sys/tty.h>
-#include <sys/pty.h>
-#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"
#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
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;
#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
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 */
}
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 = cfgetospeed (&sg);
+#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;
+ if (ioctl (0, TIOCGETP, &sg) < 0)
+ abort ();
+ 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]
#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 (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, and not HPUX version >= 6 */
+#if defined (UNIPLUS)
+ 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: 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 (SIGEMPTYMASK);
+#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
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 unnecessary: */
+ 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[VINTR] = 0377;
+#ifdef SIGNALS_VIA_CHARACTERS
+ /* the QUIT and INTR character are used in process_send_signal
+ so set them here to something useful. */
+ if (s.main.c_cc[VQUIT] == 0377)
+ s.main.c_cc[VQUIT] = '\\'&037; /* Control-\ */
+ if (s.main.c_cc[VINTR] == 0377)
+ s.main.c_cc[VINTR] = 'C'&037; /* Control-C */
+#else /* no TIOCGPGRP or no TIOCGLTC or no TIOCGETC */
+ /* 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_lflag &= ~ISIG;
+#endif /* no TIOCGPGRP or no TIOCGLTC or no TIOCGETC */
+ s.main.c_cc[VEOL] = 0377;
+ 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)
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. */
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);
} 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);
+ {
+#ifdef USG
+ int pgrp = getpgrp ();
#else
- kill (-getpgrp (0), SIGTSTP);
+ int pgrp = getpgrp (0);
#endif
+ EMACS_KILLPG (pgrp, SIGTSTP);
+ }
#else /* No SIGTSTP */
#ifdef USG_JOBCTRL /* If you don't know what this is don't mess with it */
#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);
{
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++;
}
}
unrequest_sigio ();
}
-#ifdef FASYNC /* F_SETFL does not imply existance of FASYNC */
+#ifdef FASYNC /* F_SETFL does not imply existence of FASYNC */
request_sigio ()
{
#endif /* FASYNC */
#endif /* F_SETFL */
\f
-TERMINAL old_gtty; /* The initial tty mode bits */
+/* Saving and restoring the process group of Emacs's terminal. */
+
+#ifdef BSD
+
+/* The process group of which Emacs was a member when it initially
+ started.
+
+ If Emacs was in its own process group (i.e. inherited_pgroup ==
+ getpid ()), then we know we're running under a shell with job
+ control (Emacs would never be run as part of a pipeline).
+ Everything is fine.
+
+ If Emacs was not in its own process group, then we know we're
+ running under a shell (or a caller) that doesn't know how to
+ separate itself from Emacs (like sh). Emacs must be in its own
+ process group in order to receive SIGIO correctly. In this
+ situation, we put ourselves in our own pgroup, forcibly set the
+ tty's pgroup to our pgroup, and make sure to restore and reinstate
+ the tty's pgroup just like any other terminal setting. If
+ inherited_group was not the tty's pgroup, then we'll get a
+ SIGTTmumble when we try to change the tty's pgroup, and a CONT if
+ it goes foreground in the future, which is what should happen. */
+int inherited_pgroup;
+
+/* Split off the foreground process group to Emacs alone.
+ When we are in the foreground, but not started in our own process
+ group, redirect the TTY to point to our own process group. We need
+ to be in our own process group to receive SIGIO properly. */
+narrow_foreground_group ()
+{
+ int me = getpid ();
+
+ setpgrp (0, inherited_pgroup);
+ if (inherited_pgroup != me)
+ EMACS_SET_TTY_PGRP (0, &me);
+ setpgrp (0, me);
+}
+
+/* Set the tty to our original foreground group. */
+widen_foreground_group ()
+{
+ if (inherited_pgroup != getpid ())
+ EMACS_SET_TTY_PGRP (0, &inherited_pgroup);
+ setpgrp (0, inherited_pgroup);
+}
+
+#endif
+\f
+/* 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
+ int i;
+ /* We have those nifty POSIX tcmumbleattr functions.
+ William J. Smith <wjs@wiis.wang.com> 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." */
+ /* This make sure that we don't loop indefinitely in here. */
+ for (i = 0 ; i < 10 ; i++)
+ 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);
+ /* We cannot use memcmp on the whole structure here because under
+ * aix386 the termios structure has some reserved field that may
+ * not be filled in.
+ */
+ 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
+ /* 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;
+}
+
+\f
+/* 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. */
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 */
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);
}
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 */
+
+#ifdef BSD
+ if (! read_socket_hook && EQ (Vwindow_system, Qnil))
+ narrow_foreground_group ();
+#endif
+
+ 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.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.c_lflag &= ~ECHO; /* Disable echo */
- tty.c_lflag &= ~ICANON; /* Disable erase/kill processing */
- tty.c_lflag |= ISIG; /* Enable signals */
+ 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 */
+#ifdef VLNEXT
+ tty.main.c_cc[VLNEXT] = CDISABLE;
+#endif /* VLNEXT */
+#ifdef VREPRINT
+ tty.main.c_cc[VREPRINT] = CDISABLE;
+#endif /* VREPRINT */
+#ifdef VWERASE
+ tty.main.c_cc[VWERASE] = CDISABLE;
+#endif /* VWERASE */
+#ifdef VDISCARD
+ tty.main.c_cc[VDISCARD] = CDISABLE;
+#endif /* VDISCARD */
#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
+
+#ifdef BSD4_1
+#define LNOFLSH 0100000
#endif
-#endif /* not VMS */
+
+ tty.lmode = LDECCTQ | LLITOUT | LPASS8 | LNOFLSH | old_tty.lmode;
+#ifdef ultrix
+ /* Under Ultrix 4.2a, leaving this out doesn't seem to hurt
+ anything, and leaving it in breaks the meta key. Go figure. */
+ tty.lmode &= ~LLITOUT;
+#endif
+
+#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
#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);
}
#ifdef F_SETFL
-#ifdef F_GETOWN /* F_SETFL does not imply existance of F_GETOWN */
+#ifdef F_GETOWN /* F_SETFL does not imply existence of F_GETOWN */
if (interrupt_input)
{
old_fcntl_owner = fcntl (0, F_GETOWN, 0);
}
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;
}
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 */
}
+
\f
+/* 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)
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
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 */
+#ifdef F_SETOWN /* F_SETFL does not imply existence of F_SETOWN */
if (interrupt_input)
{
reset_sigio ();
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 ();
#endif
+
+#ifdef BSD
+ widen_foreground_group ();
+#endif
}
\f
#ifdef HAVE_PTYS
{
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);
}
stop_vms_input ()
{
- return SYS$DASSGN (input_chan);
+ return SYS$DASSGN (input_fd);
}
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);
}
{
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);
{
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;
}
#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;
}
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;
{
#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) */
#include <whoami.h>
#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 <sys/socket.h>
+#include <netdb.h>
+#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;
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 */
+
\f
#ifndef VMS
#ifndef HAVE_SELECT
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) */
{
char buf[256 * BUFFER_SIZE_FACTOR];
struct input_event e;
- int nread;
+ int nread, i;
+ extern int quit_char;
if (read_socket_hook)
{
/* 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;
}
}
#endif /* not VMS */
\f
#ifdef BSD4_1
-/* VARARGS */
-setpriority ()
-{
- return 0;
-}
-
/*
* Partially emulate 4.2 open call.
* open is defined as this in 4.1.
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)
{
#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)
{
}
#endif /* not BSTRING */
\f
+#ifndef HAVE_RANDOM
#ifdef USG
/*
* The BSD random returns numbers in the range of
srand (arg);
}
#endif /* BSD4_1 */
+#endif
\f
#ifdef WRONG_NAME_INSQUE
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);
#ifdef VMS
#ifdef LINK_CRTL_SHARE
#ifdef SHAREABLE_LIB_BUG
-/* Variables declared noshare and initialized in shareable libraries
+/* Variables declared noshare and initialized in sharable libraries
cannot be shared. The VMS linker incorrectly forces you to use a private
version which is uninitialized... If not for this "feature", we
could use the C library definition of sys_nerr and sys_errlist. */
* to names for our own functions in sysdep.c that do the system call
* with retries. Actually, for portability reasons, it is good
* programming practice, as this example shows, to limit all actual
- * system calls to a single occurance in the source. Sure, this
+ * system calls to a single occurrence in the source. Sure, this
* adds an extra level of function call overhead but it is almost
* always negligible. Fred Fish, Unisoft Systems Inc.
*/
+#ifndef HAVE_SYS_SIGLIST
char *sys_siglist[NSIG + 1] =
{
#ifdef AIX
#endif /* not AIX */
0
};
+#endif /* HAVE_SYS_SIGLIST */
/*
* Warning, this function may not duplicate 4.2 action properly
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. */
npath++;
strcpy (pathname, npath);
free (spath); /* getcwd uses malloc */
+ UNBLOCK_INPUT;
return pathname;
}
* that files be of same type (regular->regular, dir->dir, etc).
*/
+#ifndef HAVE_RENAME
+
rename (from, to)
char *from;
char *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
tp->tv_sec = time ((long *)0);
tp->tv_usec = 0;
- tzp->tz_minuteswest = -1;
+ if (tzp != 0)
+ tzp->tz_minuteswest = -1;
}
#endif
"power-fail restart", /* 19 SIGPWR */
"window size changed", /* 20 SIGWINCH */
"undefined", /* 21 */
- "pollable event occured", /* 22 SIGPOLL */
+ "pollable event occurred", /* 22 SIGPOLL */
"sendable stop signal not from tty", /* 23 SIGSTOP */
"stop signal from tty", /* 24 SIGSTP */
"continue a stopped process", /* 25 SIGCONT */
#include <dirent.h>
-#ifndef AIX
+#ifndef HAVE_CLOSEDIR
int
closedir (dirp)
register DIR *dirp; /* stream from opendir */
{
sys_close (dirp->dd_fd);
- free ((char *) dirp->dd_buf); /* directory block defined in <dirent.h> */
- free ((char *) dirp);
+
+ /* Some systems (like Solaris) allocate the buffer and the DIR all
+ in one block. Why in the world are we freeing this ourselves
+ anyway? */
+#if ! (defined (sun) && defined (USG5_4))
+ xfree ((char *) dirp->dd_buf); /* directory block defined in <dirent.h> */
+#endif
+ xfree ((char *) dirp);
}
-#endif /* not AIX */
+#endif /* not HAVE_CLOSEDIR */
#endif /* SYSV_SYSTEM_DIR */
#ifdef NONSYSTEM_DIR_LIBRARY
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 */
register DIR *dirp; /* stream from opendir */
{
sys_close (dirp->dd_fd);
- free ((char *) dirp);
+ xfree ((char *) dirp);
}
\f
/* Functions for VMS */
#ifdef VMS
-#include "pwd.h"
+#include "vms-pwd.h"
#include <acldef.h>
#include <chpdef.h>
#include <jpidef.h>
#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))
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;
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 ()
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)
{
{
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;
}
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);
sys_creat (va_alist)
va_dcl
{
- va_list list_incrementor;
+ va_list list_incrementer;
char *name;
int mode;
int rfd; /* related file descriptor */
extern int vms_stmlf_recfm;
va_count (count);
- va_start (list_incrementor);
- name = va_arg (list_incrementor, char *);
- mode = va_arg (list_incrementor, int);
+ va_start (list_incrementer);
+ name = va_arg (list_incrementer, char *);
+ mode = va_arg (list_incrementer, int);
if (count > 2)
- rfd = va_arg (list_incrementor, int);
- va_end (list_incrementor);
+ rfd = va_arg (list_incrementer, int);
+ va_end (list_incrementer);
if (count > 2)
{
/* Use information from the related file descriptor to set record
/* 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;
}
/* 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;
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;
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;
/* 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;
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;
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;
ulimit ()
{}
-setpriority ()
-{}
-
setpgrp ()
{}
are renaming.
We could use the chmod function, but Eunichs uses 3 bits per user category
- to describe the protection, and VMS uses 4 (write and delete are seperate
+ to describe the protection, and VMS uses 4 (write and delete are separate
bits). To maintain portability, the VMS implementation of `chmod' wires
the W and D bits together. */
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;
}