/* Interfaces to system-dependent kernel and library entries.
- Copyright (C) 1985, 86,87,88,93,94,95, 1999, 2000, 2001
+ Copyright (C) 1985, 86,87,88,93,94,95,1999,2000,01,2003
Free Software Foundation, Inc.
This file is part of GNU Emacs.
#endif
#endif
+#include "sysselect.h"
+
#include "blockinput.h"
#undef NULL
-#ifdef macintosh
+#ifdef MAC_OS8
/* It is essential to include stdlib.h so that this file picks up
the correct definitions of rand, srand, and RAND_MAX.
Otherwise random numbers will not work correctly. */
/* Nonzero means delete a process right away if it exits (process.c). */
static int delete_exited_processes;
#endif
-#endif /* macintosh */
+#endif /* MAC_OS8 */
#ifdef WINDOWSNT
#define read sys_read
#endif
#endif /* not WINDOWSNT */
+#ifdef HAVE_CARBON
+#define read sys_read
+#endif
+
/* Does anyone other than VMS need this? */
#ifndef fwrite
#define sys_fwrite fwrite
#include <sys/stat.h>
#include <errno.h>
-/* Get _POSIX_VDISABLE, if it is available. */
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-
#ifdef HAVE_SETPGID
#if !defined (USG) || defined (BSD_PGRPS)
#undef setpgrp
#define MAXIOSIZE (32 * PAGESIZE) /* Don't I/O more than 32 blocks at a time */
#endif /* VMS */
-#ifndef BSD4_1
-#ifdef BSD_SYSTEM /* avoid writing defined (BSD_SYSTEM) || defined (USG)
- because the vms compiler doesn't grok `defined' */
-#include <fcntl.h>
-#endif
-#ifdef USG
-#ifndef USG5
+#ifndef VMS
+#include <sys/file.h>
+#endif /* not VMS */
+
+#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif
-#endif
-#endif /* not 4.1 bsd */
#ifndef MSDOS
#include <sys/ioctl.h>
#include "termopts.h"
#include "dispextern.h"
#include "process.h"
+#include "cm.h" /* for reset_sys_modes */
#ifdef WINDOWSNT
#include <direct.h>
int emacs_ospeed;
-/* The file descriptor for Emacs's input terminal.
- Under Unix, this is normally zero except when using X;
- under VMS, we place the input channel number here. */
-int input_fd;
-
void croak P_ ((char *));
#ifdef AIXHFT
-void hft_init ();
-void hft_reset ();
+void hft_init P_ ((struct tty_display_info *));
+void hft_reset P_ ((struct tty_display_info *));
#endif
/* Temporary used by `sigblock' when defined in terms of signprocmask. */
SIGMASKTYPE sigprocmask_set;
\f
-/* Specify a different file descriptor for further input operations. */
-
-void
-change_input_fd (fd)
- int fd;
-{
- input_fd = fd;
-}
-
-/* Discard pending input on descriptor input_fd. */
+/* Discard pending input on all input descriptors. */
void
discard_tty_input ()
if (noninteractive)
return;
- /* Discarding input is not safe when the input could contain
- replies from the X server. So don't do it. */
- if (read_socket_hook)
- return;
-
#ifdef VMS
end_kbd_input ();
- SYS$QIOW (0, input_fd, IO$_READVBLK|IO$M_PURGE, input_iosb, 0, 0,
+ SYS$QIOW (0, fileno (TTY_INPUT (CURTTY())), 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
{
- int zero = 0;
- ioctl (input_fd, TIOCFLUSH, &zero);
+ struct tty_display_info *tty;
+ for (tty = tty_list; tty; tty = tty->next)
+ {
+ int zero = 0;
+ ioctl (fileno (TTY_INPUT (tty)), TIOCFLUSH, &zero);
+ }
}
#else /* not Apollo */
#ifdef MSDOS /* Demacs 1.1.1 91/10/16 HIRANO Satoshi */
while (dos_keyread () != -1)
;
#else /* not MSDOS */
- EMACS_GET_TTY (input_fd, &buf);
- EMACS_SET_TTY (input_fd, &buf, 0);
+ {
+ struct tty_display_info *tty;
+ for (tty = tty_list; tty; tty = tty->next)
+ {
+ EMACS_GET_TTY (fileno (TTY_INPUT (tty)), &buf);
+ EMACS_SET_TTY (fileno (TTY_INPUT (tty)), &buf, 0);
+ }
+ }
#endif /* not MSDOS */
#endif /* not Apollo */
#endif /* not VMS */
#endif /* not WINDOWSNT */
}
+\f
#ifdef SIGTSTP
/* Arrange for character C to be read as the next input from
- the terminal. */
+ the terminal.
+ XXX What if we have multiple ttys?
+*/
void
-stuff_char (c)
- char c;
+stuff_char (char c)
{
- if (read_socket_hook)
+ if (! FRAME_TERMCAP_P (SELECTED_FRAME ()))
return;
/* Should perhaps error if in batch mode */
#ifdef TIOCSTI
- ioctl (input_fd, TIOCSTI, &c);
+ ioctl (fileno (TTY_INPUT (CURTTY())), TIOCSTI, &c);
#else /* no TIOCSTI */
error ("Cannot stuff terminal input characters in this version of Unix");
#endif /* no TIOCSTI */
#endif /* SIGTSTP */
\f
void
-init_baud_rate ()
+init_baud_rate (int fd)
{
if (noninteractive)
emacs_ospeed = 0;
#ifdef VMS
struct sensemode sg;
- SYS$QIOW (0, input_fd, IO$_SENSEMODE, &sg, 0, 0,
+ SYS$QIOW (0, fd, IO$_SENSEMODE, &sg, 0, 0,
&sg.class, 12, 0, 0, 0, 0 );
emacs_ospeed = sg.xmit_baud;
#else /* not VMS */
struct termios sg;
sg.c_cflag = B9600;
- tcgetattr (input_fd, &sg);
+ tcgetattr (fd, &sg);
emacs_ospeed = cfgetospeed (&sg);
#if defined (USE_GETOBAUD) && defined (getobaud)
/* m88k-motorola-sysv3 needs this (ghazi@noc.rutgers.edu) 9/1/94. */
sg.c_cflag = B9600;
#ifdef HAVE_TCATTR
- tcgetattr (input_fd, &sg);
+ tcgetattr (fd, &sg);
#else
- ioctl (input_fd, TCGETA, &sg);
+ ioctl (fd, TCGETA, &sg);
#endif
emacs_ospeed = sg.c_cflag & CBAUD;
#else /* neither VMS nor TERMIOS nor TERMIO */
struct sgttyb sg;
-
+
sg.sg_ospeed = B9600;
- if (ioctl (input_fd, TIOCGETP, &sg) < 0)
+ if (ioctl (fd, TIOCGETP, &sg) < 0)
abort ();
emacs_ospeed = sg.sg_ospeed;
#endif /* not HAVE_TERMIO */
#endif /* not DOS_NT */
#endif /* not INIT_BAUD_RATE */
}
-
+
baud_rate = (emacs_ospeed < sizeof baud_convert / sizeof baud_convert[0]
? baud_convert[emacs_ospeed] : 9600);
if (baud_rate == 0)
baud_rate = 1200;
}
+\f
/*ARGSUSED*/
void
set_exclusive_use (fd)
* flush any pending output
* (may flush input as well; it does not matter the way we use it)
*/
-
+
void
flush_pending_output (channel)
int channel;
#ifdef BSD4_1
if (interrupt_input)
- reset_sigio ();
+ reset_sigio (0);
#endif /* BSD4_1 */
#ifdef RTU
{
/* Fork a subshell. */
-#ifndef macintosh
+#ifndef MAC_OS8
void
sys_subshell ()
{
goto xyzzy;
dir = expand_and_dir_to_file (Funhandled_file_name_directory (dir), Qnil);
- str = (unsigned char *) alloca (XSTRING (dir)->size + 2);
- len = XSTRING (dir)->size;
- bcopy (XSTRING (dir)->data, str, len);
+ str = (unsigned char *) alloca (SCHARS (dir) + 2);
+ len = SCHARS (dir);
+ bcopy (SDATA (dir), str, len);
if (str[len - 1] != '/') str[len++] = '/';
str[len] = 0;
xyzzy:
save_signal_handlers (saved_handlers);
synch_process_alive = 1;
#endif /* __DJGPP__ > 1 */
-#else
+#else
pid = vfork ();
if (pid == -1)
error ("Can't spawn subshell");
synch_process_alive = 0;
#endif /* !VMS */
}
-#endif /* !macintosh */
+#endif /* !MAC_OS8 */
static void
save_signal_handlers (saved_handlers)
}
}
\f
+#ifndef SIGIO
+/* If SIGIO is broken, don't do anything. */
+void
+init_sigio (int fd)
+{
+}
+
+void
+reset_sigio (int fd)
+{
+}
+
+void
+request_sigio (void)
+{
+}
+
+void
+unrequest_sigio (void)
+{
+}
+
+#else
#ifdef F_SETFL
-int old_fcntl_flags;
+int old_fcntl_flags[MAXDESC];
void
init_sigio (fd)
int fd;
{
#ifdef FASYNC
- old_fcntl_flags = fcntl (fd, F_GETFL, 0) & ~FASYNC;
- fcntl (fd, F_SETFL, old_fcntl_flags | FASYNC);
+ old_fcntl_flags[fd] = fcntl (fd, F_GETFL, 0) & ~FASYNC;
+ fcntl (fd, F_SETFL, old_fcntl_flags[fd] | FASYNC);
#endif
interrupts_deferred = 0;
}
void
-reset_sigio ()
+reset_sigio (fd)
+ int fd;
{
- unrequest_sigio ();
+#ifdef FASYNC
+ fcntl (fd, F_SETFL, old_fcntl_flags[fd]);
+#endif
}
#ifdef FASYNC /* F_SETFL does not imply existence of FASYNC */
+/* XXX Uhm, FASYNC is not used anymore here. */
void
request_sigio ()
{
+ /* XXX read_socket_hook is not global anymore. Is blocking SIGIO
+ bad under X? */
+#if 0
if (read_socket_hook)
return;
+#endif
#ifdef SIGWINCH
sigunblock (sigmask (SIGWINCH));
#endif
- fcntl (input_fd, F_SETFL, old_fcntl_flags | FASYNC);
+ sigunblock (sigmask (SIGIO));
interrupts_deferred = 0;
}
void
-unrequest_sigio ()
-{
+unrequest_sigio (void)
+{
+ /* XXX read_socket_hook is not global anymore. Is blocking SIGIO
+ bad under X? */
+#if 0
if (read_socket_hook)
return;
-
+#endif
+
#ifdef SIGWINCH
sigblock (sigmask (SIGWINCH));
#endif
- fcntl (input_fd, F_SETFL, old_fcntl_flags);
+ sigblock (sigmask (SIGIO));
interrupts_deferred = 1;
}
if (read_socket_hook)
return;
- ioctl (input_fd, FIOASYNC, &on);
+ /* XXX CURTTY() is bogus here. */
+ ioctl (fileno (TTY_INPUT (CURTTY ())), FIOASYNC, &on);
interrupts_deferred = 0;
}
if (read_socket_hook)
return;
- ioctl (input_fd, FIOASYNC, &off);
+ /* XXX CURTTY() is bogus here. */
+ ioctl (fileno (TTY_INPUT (CURTTY ())), FIOASYNC, &off);
interrupts_deferred = 1;
}
#else /* not FASYNC, not STRIDE */
-
+
#ifdef _CX_UX
#include <termios.h>
sigemptyset (&st);
sigaddset (&st, SIGIO);
- ioctl (input_fd, FIOASYNC, &on);
+ ioctl (0, FIOASYNC, &on); /* XXX This fails for multiple ttys. */
interrupts_deferred = 0;
sigprocmask (SIG_UNBLOCK, &st, (sigset_t *)0);
}
if (read_socket_hook)
return;
- ioctl (input_fd, FIOASYNC, &off);
+ ioctl (0, FIOASYNC, &off); /* XXX This fails for multiple ttys. */
interrupts_deferred = 1;
}
#else /* ! _CX_UX */
+#ifndef MSDOS
void
request_sigio ()
croak ("request_sigio");
}
-
+
void
unrequest_sigio ()
{
croak ("unrequest_sigio");
}
-
+
+#endif /* MSDOS */
#endif /* _CX_UX */
#endif /* STRIDE */
#endif /* FASYNC */
#endif /* F_SETFL */
+#endif /* SIGIO */
\f
/* Saving and restoring the process group of Emacs's terminal. */
group, redirect the TTY to point to our own process group. We need
to be in our own process group to receive SIGIO properly. */
void
-narrow_foreground_group ()
+narrow_foreground_group (int fd)
{
int me = getpid ();
- setpgrp (0, inherited_pgroup);
+ if (! inherited_pgroup)
+ inherited_pgroup = getpgid (0);
+ /* XXX This only works on the controlling tty. */
if (inherited_pgroup != me)
- EMACS_SET_TTY_PGRP (input_fd, &me);
- setpgrp (0, me);
+ EMACS_SET_TTY_PGRP (fd, &me);
+ setpgid (0, me);
}
/* Set the tty to our original foreground group. */
void
-widen_foreground_group ()
+widen_foreground_group (int fd)
{
if (inherited_pgroup != getpid ())
- EMACS_SET_TTY_PGRP (input_fd, &inherited_pgroup);
- setpgrp (0, inherited_pgroup);
+ EMACS_SET_TTY_PGRP (fd, &inherited_pgroup);
+ setpgid (0, inherited_pgroup);
}
#endif /* BSD_PGRPS */
|| 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;
-
-/* 1 if we have been through init_sys_modes. */
-int term_initted;
-
-/* 1 if outer tty status has been recorded. */
-int old_tty_valid;
#ifdef BSD4_1
/* BSD 4.1 needs to keep track of the lmode bits in order to start
#ifndef F_SETOWN_BUG
#ifdef F_SETOWN
-int old_fcntl_owner;
+int old_fcntl_owner[MAXDESC];
#endif /* F_SETOWN */
#endif /* F_SETOWN_BUG */
char _sobuf[BUFSIZ];
#endif
#endif
-
+
#ifdef HAVE_LTCHARS
static struct ltchars new_ltchars = {-1,-1,-1,-1,-1,-1};
#endif
#ifdef HAVE_TCHARS
static struct tchars new_tchars = {-1,-1,-1,-1,-1,-1};
-#endif
+#endif
+
+void
+init_all_sys_modes (void)
+{
+ struct tty_display_info *tty;
+ for (tty = tty_list; tty; tty = tty->next)
+ init_sys_modes (tty);
+}
void
-init_sys_modes ()
+init_sys_modes (tty_out)
+ struct tty_display_info *tty_out;
{
struct emacs_tty tty;
-#ifdef macintosh
+#ifdef MAC_OS8
/* cus-start.el complains if delete-exited-processes is not defined */
#ifndef subprocesses
DEFVAR_BOOL ("delete-exited-processes", &delete_exited_processes,
nil means don't delete them until `list-processes' is run. */);
delete_exited_processes = 0;
#endif
-#endif /* not macintosh */
+#endif /* MAC_OS8 */
#ifdef VMS
#if 0
#ifndef VMS4_4
sys_access_reinit ();
#endif
-#endif /* not VMS */
+#endif /* VMS */
#ifdef BSD_PGRPS
+#if 0
+ /* read_socket_hook is not global anymore. I think doing this
+ unconditionally will not cause any problems. */
if (! read_socket_hook && EQ (Vwindow_system, Qnil))
- narrow_foreground_group ();
+#endif
+ narrow_foreground_group (fileno (TTY_INPUT (tty_out)));
#endif
#ifdef HAVE_WINDOW_SYSTEM
/* Emacs' window system on MSDOG uses the `internal terminal' and therefore
needs the initialization code below. */
- if (!read_socket_hook && EQ (Vwindow_system, Qnil))
+ if (tty_out->input != stdin || EQ (Vwindow_system, Qnil))
#endif
{
- EMACS_GET_TTY (input_fd, &old_tty);
-
- old_tty_valid = 1;
+ if (! tty_out->old_tty)
+ tty_out->old_tty = (struct emacs_tty *) xmalloc (sizeof (struct emacs_tty));
+
+ EMACS_GET_TTY (fileno (TTY_INPUT (tty_out)), tty_out->old_tty);
- tty = old_tty;
+ tty = *tty_out->old_tty;
#if defined (HAVE_TERMIO) || defined (HAVE_TERMIOS)
- XSETINT (Vtty_erase_char, old_tty.main.c_cc[VERASE]);
+ XSETINT (Vtty_erase_char, tty.main.c_cc[VERASE]);
#ifdef DGUX
/* This allows meta to be sent on 8th bit. */
tty.main.c_lflag &= ~IEXTEN; /* Disable other editing characters. */
#endif
tty.main.c_lflag |= ISIG; /* Enable signals */
- if (flow_control)
+ if (tty_out->flow_control)
{
tty.main.c_iflag |= IXON; /* Enable start/stop output control */
#ifdef IXANY
}
else
tty.main.c_iflag &= ~IXON; /* Disable start/stop output control */
- tty.main.c_oflag &= ~ONLCR; /* Disable map of NL to CR-NL
+ 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)
+ if (tty_out->meta_key)
{
tty.main.c_cflag |= CS8; /* allow 8th bit on input */
tty.main.c_cflag &= ~PARENB;/* Don't check parity */
}
#endif
- 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.main.c_cc[VQUIT] = quit_char;
+ if (tty_out->input == stdin)
+ {
+ 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.main.c_cc[VQUIT] = quit_char;
+ }
+ else
+ {
+ /* We normally don't get interrupt or quit signals from tty
+ devices other than our controlling terminal; therefore,
+ we must handle C-g as normal input. Unfortunately, this
+ means that the interrupt and quit feature must be
+ disabled on secondary ttys, or we would not even see the
+ keypress.
+
+ Note that even though emacsclient could have special code
+ to pass SIGINT to Emacs, we should _not_ enable
+ interrupt/quit keys for emacsclient frames. This means
+ that we can't break out of loops in C code from a
+ secondary tty frame, but we can always decide what
+ display the C-g came from, which is more important from a
+ usability point of view. (Consider the case when two
+ people work together using the same Emacs instance.) */
+ tty.main.c_cc[VINTR] = CDISABLE;
+ tty.main.c_cc[VQUIT] = CDISABLE;
+ }
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.main.c_cc[VDISCARD] = CDISABLE;
#endif /* VDISCARD */
- if (flow_control)
+ if (tty_out->flow_control)
{
#ifdef VSTART
tty.main.c_cc[VSTART] = '\021';
tty.main.c_cc[VSUSP] = 255;
tty.main.c_cc[VDSUSP] = 255;
#endif /* IBMR2AIX */
- if (flow_control)
+ if (tty_out->flow_control)
{
#ifdef VSTART
tty.main.c_cc[VSTART] = '\021';
tty.main.tt_char |= TT$M_NOECHO;
if (meta_key)
tty.main.tt_char |= TT$M_EIGHTBIT;
- if (flow_control)
+ if (tty_out->flow_control)
tty.main.tt_char |= TT$M_TTSYNC;
else
tty.main.tt_char &= ~TT$M_TTSYNC;
set this */
tty.tchars = new_tchars;
tty.tchars.t_intrc = quit_char;
- if (flow_control)
+ if (tty_out->flow_control)
{
tty.tchars.t_startc = '\021';
tty.tchars.t_stopc = '\023';
}
- tty.lmode = LDECCTQ | LLITOUT | LPASS8 | LNOFLSH | old_tty.lmode;
+ tty.lmode = LDECCTQ | LLITOUT | LPASS8 | LNOFLSH | tty_out->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
tty.ltchars = new_ltchars;
#endif /* HAVE_LTCHARS */
#ifdef MSDOS /* Demacs 1.1.2 91/10/20 Manabu Higashida, MW Aug 1993 */
- if (!term_initted)
+ if (!tty_out->term_initted)
internal_terminal_init ();
dos_ttraw ();
#endif
- EMACS_SET_TTY (input_fd, &tty, 0);
+ EMACS_SET_TTY (fileno (TTY_INPUT (tty_out)), &tty, 0);
/* This code added to insure that, if flow-control is not to be used,
we have an unlocked terminal at the start. */
#ifdef TCXONC
- if (!flow_control) ioctl (input_fd, TCXONC, 1);
+ if (!tty_out->flow_control) ioctl (fileno (TTY_INPUT (tty_out)), TCXONC, 1);
#endif
#ifndef APOLLO
#ifdef TIOCSTART
- if (!flow_control) ioctl (input_fd, TIOCSTART, 0);
+ if (!tty_out->flow_control) ioctl (fileno (TTY_INPUT (tty_out)), TIOCSTART, 0);
#endif
#endif
#if defined (HAVE_TERMIOS) || defined (HPUX9)
#ifdef TCOON
- if (!flow_control) tcflow (input_fd, TCOON);
+ if (!tty_out->flow_control) tcflow (fileno (TTY_INPUT (tty_out)), TCOON);
#endif
#endif
#ifdef AIXHFT
- hft_init ();
+ hft_init (tty_out);
#ifdef IBMR2AIX
{
/* IBM's HFT device usually thinks a ^J should be LF/CR. We need it
#ifdef VMS
/* Appears to do nothing when in PASTHRU mode.
- SYS$QIOW (0, input_fd, IO$_SETMODE|IO$M_OUTBAND, 0, 0, 0,
+ SYS$QIOW (0, fileno (TTY_INPUT (tty_out)), IO$_SETMODE|IO$M_OUTBAND, 0, 0, 0,
interrupt_signal, oob_chars, 0, 0, 0, 0);
*/
queue_kbd_input (0);
#ifndef F_SETOWN_BUG
#ifdef F_GETOWN /* F_SETFL does not imply existence of F_GETOWN */
if (interrupt_input
- && ! read_socket_hook && EQ (Vwindow_system, Qnil))
+ && (tty_out->input != stdin || EQ (Vwindow_system, Qnil)))
{
- old_fcntl_owner = fcntl (input_fd, F_GETOWN, 0);
- fcntl (input_fd, F_SETOWN, getpid ());
- init_sigio (input_fd);
+ old_fcntl_owner[fileno (TTY_INPUT (tty_out))] =
+ fcntl (fileno (TTY_INPUT (tty_out)), F_GETOWN, 0);
+ fcntl (fileno (TTY_INPUT (tty_out)), F_SETOWN, getpid ());
+ init_sigio (fileno (TTY_INPUT (tty_out)));
}
#endif /* F_GETOWN */
#endif /* F_SETOWN_BUG */
#ifdef BSD4_1
if (interrupt_input)
- init_sigio (input_fd);
+ init_sigio (fileno (TTY_INPUT (tty_out)));
#endif
#ifdef VMS /* VMS sometimes has this symbol but lacks setvbuf. */
/* This symbol is defined on recent USG systems.
Someone says without this call USG won't really buffer the file
even with a call to setbuf. */
- setvbuf (stdout, (char *) _sobuf, _IOFBF, sizeof _sobuf);
+ setvbuf (TTY_OUTPUT (tty_out), (char *) _sobuf, _IOFBF, sizeof _sobuf);
#else
- setbuf (stdout, (char *) _sobuf);
+ setbuf (TTY_OUTPUT (tty_out), (char *) _sobuf);
#endif
+
+#if 0 /* We always need this with multi-tty support. */
#ifdef HAVE_WINDOW_SYSTEM
/* Emacs' window system on MSDOG uses the `internal terminal' and therefore
needs the initialization code below. */
#endif
)
#endif
- set_terminal_modes ();
+#endif
+ tty_set_terminal_modes (tty_out->display);
- if (!term_initted
- && FRAMEP (Vterminal_frame)
- && FRAME_TERMCAP_P (XFRAME (Vterminal_frame)))
- init_frame_faces (XFRAME (Vterminal_frame));
+ if (!tty_out->term_initted)
+ {
+ Lisp_Object tail, frame;
+ FOR_EACH_FRAME (tail, frame)
+ {
+ /* XXX This needs to be revised. */
+ if (FRAME_TERMCAP_P (XFRAME (frame))
+ && FRAME_TTY (XFRAME (frame)) == tty_out)
+ init_frame_faces (XFRAME (frame));
+ }
+ }
- if (term_initted && no_redraw_on_reenter)
+ if (tty_out->term_initted && no_redraw_on_reenter)
{
if (display_completed)
direct_output_forward_char (0);
}
else
{
+ Lisp_Object tail, frame;
frame_garbaged = 1;
- if (FRAMEP (Vterminal_frame))
- FRAME_GARBAGED_P (XFRAME (Vterminal_frame)) = 1;
+ FOR_EACH_FRAME (tail, frame)
+ {
+ if (FRAME_TERMCAP_P (XFRAME (frame))
+ && FRAME_TTY (XFRAME (frame)) == tty_out)
+ FRAME_GARBAGED_P (XFRAME (frame)) = 1;
+ }
}
- term_initted = 1;
+ tty_out->term_initted = 1;
}
/* Return nonzero if safe to use tabs in output.
At the time this is called, init_sys_modes has not been done yet. */
-
+
int
-tabs_safe_p ()
+tabs_safe_p (int fd)
{
- struct emacs_tty tty;
+ struct emacs_tty etty;
- EMACS_GET_TTY (input_fd, &tty);
- return EMACS_TTY_TABS_OK (&tty);
+ EMACS_GET_TTY (fd, &etty);
+ return EMACS_TTY_TABS_OK (&etty);
}
\f
/* Get terminal size from system.
We store 0 if there's no valid information. */
void
-get_frame_size (widthp, heightp)
- int *widthp, *heightp;
+get_tty_size (int fd, int *widthp, int *heightp)
{
#ifdef TIOCGWINSZ
/* BSD-style. */
struct winsize size;
- if (ioctl (input_fd, TIOCGWINSZ, &size) == -1)
+ if (ioctl (fd, TIOCGWINSZ, &size) == -1)
*widthp = *heightp = 0;
else
{
#ifdef TIOCGSIZE
/* SunOS - style. */
- struct ttysize size;
+ struct ttysize size;
- if (ioctl (input_fd, TIOCGSIZE, &size) == -1)
+ if (ioctl (fd, TIOCGSIZE, &size) == -1)
*widthp = *heightp = 0;
else
{
#ifdef VMS
struct sensemode tty;
-
- SYS$QIOW (0, input_fd, IO$_SENSEMODE, &tty, 0, 0,
+
+ SYS$QIOW (0, fd, IO$_SENSEMODE, &tty, 0, 0,
&tty.class, 12, 0, 0, 0, 0);
*widthp = tty.scr_wid;
*heightp = tty.scr_len;
*widthp = 0;
*heightp = 0;
#endif
-
#endif /* not VMS */
#endif /* not SunOS-style */
#endif /* not BSD-style */
#ifdef TIOCSSIZE
/* SunOS - style. */
- struct ttysize size;
+ struct ttysize size;
size.ts_lines = height;
size.ts_cols = width;
}
\f
-/* Prepare the terminal for exiting Emacs; move the cursor to the
+void
+reset_all_sys_modes (void)
+{
+ struct tty_display_info *tty;
+ for (tty = tty_list; tty; tty = tty->next)
+ reset_sys_modes (tty);
+}
+
+/* Prepare the terminal for closing it; move the cursor to the
bottom of the frame, turn off interrupt-driven I/O, etc. */
void
-reset_sys_modes ()
+reset_sys_modes (tty_out)
+ struct tty_display_info *tty_out;
{
- struct frame *sf;
-
if (noninteractive)
{
fflush (stdout);
return;
}
- if (!term_initted)
+ if (!tty_out->term_initted)
return;
+#if 0 /* We always need to do this with multi-tty support. */
#ifdef HAVE_WINDOW_SYSTEM
/* Emacs' window system on MSDOG uses the `internal terminal' and therefore
needs the clean-up code below. */
- if (!EQ (Vwindow_system, Qnil)
+ if (tty_out->input != stdin
+ || (!EQ (Vwindow_system, Qnil)
#ifndef WINDOWSNT
/* When running in tty mode on NT/Win95, we have a read_socket
hook, but still need the rest of the clean-up code below. */
|| read_socket_hook
#endif
- )
+ ))
return;
#endif
- sf = SELECTED_FRAME ();
- cursor_to (FRAME_HEIGHT (sf) - 1, 0);
- clear_end_of_line (FRAME_WIDTH (sf));
- /* clear_end_of_line may move the cursor */
- cursor_to (FRAME_HEIGHT (sf) - 1, 0);
+#endif
+
+ cmgoto (tty_out, FrameRows (tty_out) - 1, 0);
+#if 0 /* XXX This doesn't work anymore, the signature has changed. */
+ tty_clear_end_of_line (tty_out, FrameCols (tty_out));
+#endif
+ cmgoto (tty_out, FrameRows (tty_out) - 1, 0);
+ fflush (tty_out->output);
+
#if defined (IBMR2AIX) && defined (AIXHFT)
{
- /* HFT devices normally use ^J as a LF/CR. We forced it to
+ /* HFT devices normally use ^J as a LF/CR. We forced it to
do the LF only. Now, we need to reset it. */
struct termio tty;
}
#endif
- reset_terminal_modes ();
- fflush (stdout);
+ tty_reset_terminal_modes (tty_out->display);
+ fflush (TTY_OUTPUT (tty_out));
#ifdef BSD_SYSTEM
#ifndef BSD4_1
/* Avoid possible loss of output when changing terminal modes. */
- fsync (fileno (stdout));
+ fsync (fileno (TTY_OUTPUT (tty_out)));
#endif
#endif
#ifdef F_SETOWN /* F_SETFL does not imply existence of F_SETOWN */
if (interrupt_input)
{
- reset_sigio ();
- fcntl (input_fd, F_SETOWN, old_fcntl_owner);
+ reset_sigio (fileno (TTY_INPUT (tty_out)));
+ fcntl (fileno (TTY_INPUT (tty_out)), F_SETOWN,
+ old_fcntl_owner[fileno (TTY_INPUT (tty_out))]);
}
#endif /* F_SETOWN */
#endif /* F_SETOWN_BUG */
#ifdef O_NDELAY
- fcntl (input_fd, F_SETFL, fcntl (input_fd, F_GETFL, 0) & ~O_NDELAY);
+ fcntl (fileno (TTY_INPUT (tty_out)), F_SETFL,
+ fcntl (fileno (TTY_INPUT (tty_out)), F_GETFL, 0) & ~O_NDELAY);
#endif
#endif /* F_SETFL */
#ifdef BSD4_1
if (interrupt_input)
- reset_sigio ();
+ reset_sigio (fileno (TTY_INPUT (tty_out)));
#endif /* BSD4_1 */
- if (old_tty_valid)
- while (EMACS_SET_TTY (input_fd, &old_tty, 0) < 0 && errno == EINTR)
+ if (tty_out->old_tty)
+ while (EMACS_SET_TTY (fileno (TTY_INPUT (tty_out)),
+ tty_out->old_tty, 0) < 0 && errno == EINTR)
;
#ifdef MSDOS /* Demacs 1.1.2 91/10/20 Manabu Higashida */
/* Ultrix's termios *ignores* any line discipline except TERMIODISC.
A different old line discipline is therefore not restored, yet.
Restore the old line discipline by hand. */
- ioctl (0, TIOCSETD, &old_tty.main.c_line);
+ ioctl (0, TIOCSETD, &tty_out->old_tty.main.c_line);
#endif
#ifdef AIXHFT
#endif
#ifdef BSD_PGRPS
- widen_foreground_group ();
+ widen_foreground_group (fileno (TTY_INPUT (tty_out)));
#endif
}
\f
does this. Also it is known that telnet mode will hang
in such a way that Emacs must be stopped (perhaps this
is the same problem).
-
+
If TIOCREMOTE is turned off, then there is a bug in
hp-ux which sometimes loses data. Apparently the
code which blocks the master process when the internal
buffer fills up does not work. Other than this,
though, everything else seems to work fine.
-
+
Since the latter lossage is more benign, we may as well
lose that way. -- cph */
#ifdef FIONBIO
init_vms_input ()
{
int status;
-
- if (input_fd == 0)
+
+ if (fileno (TTY_INPUT (CURTTY())) == 0)
{
- status = SYS$ASSIGN (&input_dsc, &input_fd, 0, 0);
+ status = SYS$ASSIGN (&input_dsc, &fileno (TTY_INPUT (CURTTY())), 0, 0);
if (! (status & 1))
LIB$STOP (status);
}
void
stop_vms_input ()
{
- return SYS$DASSGN (input_fd);
+ return SYS$DASSGN (fileno (TTY_INPUT (CURTTY())));
}
short input_buffer;
waiting_for_ast = 0;
stop_input = 0;
- status = SYS$QIO (0, input_fd, IO$_READVBLK,
+ status = SYS$QIO (0, fileno (TTY_INPUT (CURTTY())), IO$_READVBLK,
&input_iosb, kbd_input_ast, 1,
&input_buffer, 1, 0, terminator_mask, 0, 0);
}
if (c >= 0)
{
struct input_event e;
- e.kind = ascii_keystroke;
+ EVENT_INIT (e);
+
+ e.kind = ASCII_KEYSTROKE_EVENT;
XSETINT (e.code, c);
e.frame_or_window = selected_frame;
kbd_buffer_store_event (&e);
#endif
if (LIB$AST_IN_PROG ()) /* Don't wait if suspending from kbd_buffer_store_event! */
{
- SYS$CANCEL (input_fd);
+ SYS$CANCEL (fileno (TTY_INPUT (CURTTY())));
return;
}
SYS$CLREF (input_ef);
waiting_for_ast = 1;
stop_input = 1;
- SYS$CANCEL (input_fd);
+ SYS$CANCEL (fileno (TTY_INPUT (CURTTY())));
SYS$SETAST (1);
SYS$WAITFR (input_ef);
waiting_for_ast = 0;
int time [2];
static int zero = 0;
static int large = -10000000;
-
+
LIB$EMUL (&timeval, &large, &zero, time); /* Convert to VMS format */
SYS$CANTIM (1, 0);
request_sigio ();
}
-reset_sigio ()
+reset_sigio (fd)
+ int fd;
{
unrequest_sigio ();
}
* will be patched by unexec to the correct value.
*
*/
-
+
+#ifndef start_of_data
char *
start_of_data ()
{
#endif /* ORDINARY_LINK */
#endif /* DATA_START */
}
+#endif /* start_of_data */
#endif /* NEED_STARTS (not CANNOT_DUMP or not SYSTEM_MALLOC) */
-
-#ifndef CANNOT_DUMP
-/* Some systems that cannot dump also cannot implement these. */
-
-/*
- * Return the address of the end of the text segment prior to
- * doing an unexec. After unexec the return value is undefined.
- */
-
-char *
-end_of_text ()
-{
-#ifdef TEXT_END
- return ((char *) TEXT_END);
-#else
- extern int etext;
- return ((char *) &etext);
-#endif
-}
-
-/*
- * Return the address of the end of the data segment prior to
- * doing an unexec. After unexec the return value is undefined.
- */
-
-char *
-end_of_data ()
-{
-#ifdef DATA_END
- return ((char *) DATA_END);
-#else
- extern int edata;
- return ((char *) &edata);
-#endif
-}
-
-#endif /* not CANNOT_DUMP */
\f
/* init_system_name sets up the string for the Lisp function
system-name to return. */
#endif /* BSD4_1 */
{
unsigned char *p;
- for (p = XSTRING (Vsystem_name)->data; *p; p++)
+ for (p = SDATA (Vsystem_name); *p; p++)
if (*p == ' ' || *p == '\t')
*p = '-';
}
/* Once a second, till the timer expires, check all the flagged read
* descriptors to see if any input is available. If there is some then
* set the corresponding bit in the return copy of rfds.
- */
+ */
while (1)
{
register int to_check, fd;
signal (SIGALRM, select_alarm);
select_alarmed = 0;
alarm (SELECT_PAUSE);
-
+
/* Wait for a SIGALRM (or maybe a SIGTINT) */
while (select_alarmed == 0 && *local_timeout != 0
&& process_tick == update_tick)
pause ();
}
(*local_timeout) -= SELECT_PAUSE;
-
+
/* Reset the old alarm if there was one. */
turn_on_atimers (1);
-
+
if (*local_timeout == 0) /* Stop on timer being cleared */
break;
}
return ravail;
}
-#endif /* not WINDOWSNT */
+#endif not WINDOWSNT
/* Read keyboard input into the standard buffer,
waiting for at least one character. */
void
read_input_waiting ()
{
- struct input_event e;
+ /* XXX This needs to be updated for multi-tty support. Does
+ anybody need to emulate select these days? */
int nread, i;
extern int quit_char;
if (read_socket_hook)
{
struct input_event buf[256];
-
+ for (i = 0; i < 256; i++)
+ EVENT_INIT (buf[i]);
+
read_alarm_should_throw = 0;
if (! setjmp (read_alarm_throw))
nread = (*read_socket_hook) (0, buf, 256, 1);
kbd_buffer_store_event (&buf[i]);
/* Don't look at input that follows a C-g too closely.
This reduces lossage due to autorepeat on C-g. */
- if (buf[i].kind == ascii_keystroke
+ if (buf[i].kind == ASCII_KEYSTROKE_EVENT
&& buf[i].code == quit_char)
break;
}
}
else
{
+ struct input_event e;
char buf[3];
nread = read (fileno (stdin), buf, 1);
+ EVENT_INIT (e);
/* Scan the chars for C-g and store them in kbd_buffer. */
- e.kind = ascii_keystroke;
+ e.kind = ASCII_KEYSTROKE_EVENT;
e.frame_or_window = selected_frame;
e.modifiers = 0;
for (i = 0; i < nread; i++)
}
}
+#if !defined (HAVE_SELECT) || defined (BROKEN_SELECT_NON_X)
+#define select sys_select
+#endif
+
#endif /* not HAVE_SELECT */
#endif /* not VMS */
#endif /* not MSDOS */
}
void
-reset_sigio ()
+reset_sigio (fd)
+ int fd;
{
if (noninteractive)
return;
lmode = ~LINTRUP & lmode;
- ioctl (0, TIOCLSET, &lmode);
+ ioctl (fd, TIOCLSET, &lmode);
}
void
struct sigaction new_action, old_action;
sigemptyset (&new_action.sa_mask);
new_action.sa_handler = action;
-#ifdef SA_RESTART
+#if defined (SA_RESTART) && ! defined (BROKEN_SA_RESTART)
/* Emacs mostly works better with restartable system services. If this
- * flag exists, we probably want to turn it on here.
- */
+ flag exists, we probably want to turn it on here.
+ However, on some systems this resets the timeout of `select'
+ which means that `select' never finishes if it keeps getting signals.
+ BROKEN_SA_RESTART is defined on those systems. */
new_action.sa_flags = SA_RESTART;
#else
new_action.sa_flags = 0;
#endif /* POSIX_SIGNALS */
\f
-#if !defined HAVE_STRSIGNAL && !defined SYS_SIGLIST_DECLARED
+#if !defined HAVE_STRSIGNAL && !HAVE_DECL_SYS_SIGLIST
static char *my_sys_siglist[NSIG];
# ifdef sys_siglist
# undef sys_siglist
sigfillset (&full_mask);
#endif
-#if !defined HAVE_STRSIGNAL && !defined SYS_SIGLIST_DECLARED
+#if !defined HAVE_STRSIGNAL && !HAVE_DECL_SYS_SIGLIST
if (! initialized)
{
# ifdef SIGABRT
sys_siglist[SIGXFSZ] = "File size limit exceeded";
# endif
}
-#endif /* !defined HAVE_STRSIGNAL && !defined SYS_SIGLIST_DECLARED */
+#endif /* !defined HAVE_STRSIGNAL && !defined HAVE_DECL_SYS_SIGLIST */
}
\f
#ifndef HAVE_RANDOM
#undef abort
sys_abort ()
{
- reset_sys_modes ();
+ reset_all_sys_modes ();
LIB$SIGNAL (SS$_DEBUG);
}
#endif /* abort */
\f
int
emacs_open (path, oflag, mode)
- char *path;
+ const char *path;
int oflag, mode;
{
register int rtnval;
#ifdef BSD4_1
- if (oflag & O_CREAT)
+ if (oflag & O_CREAT)
return creat (path, mode);
#endif
-
+
while ((rtnval = open (path, oflag, mode)) == -1
&& (errno == EINTR));
return (rtnval);
unsigned int nbyte;
{
register int rtnval;
-
+
while ((rtnval = read (fildes, buf, nbyte)) == -1
&& (errno == EINTR));
return (rtnval);
int
emacs_write (fildes, buf, nbyte)
int fildes;
- char *buf;
+ const char *buf;
unsigned int nbyte;
{
register int rtnval, bytes_written;
int newd;
{
register int fd, ret;
-
+
emacs_close (newd);
#ifdef F_DUPFD
#ifndef VMS
#ifndef HAVE_GETTIMEOFDAY
#ifdef HAVE_TIMEVAL
-
+
/* ARGSUSED */
int
gettimeofday (tp, tzp)
{
extern long time ();
- tp->tv_sec = time ((long *)0);
+ tp->tv_sec = time ((long *)0);
tp->tv_usec = 0;
if (tzp != 0)
tzp->tz_minuteswest = -1;
return 0;
}
-
+
#endif
#endif
#endif
#endif /* subprocess && !HAVE_GETTIMEOFDAY && HAVE_TIMEVAL && !VMS */
-
+
/*
* This function will go away as soon as all the stubs fixed. (fnf)
*/
char *badfunc;
{
printf ("%s not yet implemented\r\n", badfunc);
- reset_sys_modes ();
+ reset_all_sys_modes ();
exit (1);
}
\f
int
set_file_times (filename, atime, mtime)
- char *filename;
+ const char *filename;
EMACS_TIME atime, mtime;
{
#ifdef HAVE_UTIMES
#ifdef access
#undef access
-
+
/* The following is necessary because 'access' emulation by VMS C (2.0) does
* not work correctly. (It also doesn't work well in version 2.3.)
*/
* access can treat the directory like a file. */
if (directory_file_name (path, dir_fn))
path = dir_fn;
-
+
if (mode == F_OK)
return access (path, mode);
if (user == NULL && (user = (char *) getenv ("USER")) == NULL)
static int constant = ACL$C_FILE;
DESCRIPTOR (path_desc, path);
DESCRIPTOR (user_desc, user);
-
+
flags = 0;
acces = 0;
if ((mode & X_OK) && ((stat = access (path, mode)) < 0 || mode == X_OK))
return access (filename, type);
/* Check write protection. */
-
+
#define CHECKPRIV(bit) (prvmask.bit)
#define WRITABLE(field) (! ((xab.xab$w_pro >> field) & XAB$M_NOWRITE))
}
#endif /* not VMS4_4 */
#endif /* access */
-
+
static char vtbuf[NAM$C_MAXRSS+1];
/* translate a vms file spec to a unix path */
*targ++ = '.';
*targ++ = '.';
break;
-
+
default:
*targ++ = *vfile;
break;
ufile++;
}
*targ = '\0';
-
+
return utbuf;
}
}
strcpy (pathname, ptr);
xfree (ptr);
-
+
return pathname;
}
* when this is not the desired behavior, for instance, when writing an
* auto save file (you only want one version), or when you don't have
* write permission in the directory containing the file (but the file
- * itself is writable). Hence this routine, which is equivalent to
+ * itself is writable). Hence this routine, which is equivalent to
* "close (creat (fn, 0));" on Unix if fn already exists.
*/
int
register status;
struct FAB uaf_fab;
struct RAB uaf_rab;
-
+
uaf_fab = cc$rms_fab;
uaf_rab = cc$rms_rab;
/* initialize fab fields */
register status;
struct FAB uaf_fab;
struct RAB uaf_rab;
-
+
uaf_fab = cc$rms_fab;
uaf_rab = cc$rms_rab;
/* initialize fab fields */
bits). To maintain portability, the VMS implementation of `chmod' wires
the W and D bits together. */
-
+
static struct fibdef fib; /* We need this initialized to zero */
char vms_file_written[NAM$C_MAXRSS];
char *badfunc;
{
printf ("%s not yet implemented\r\n", badfunc);
- reset_sys_modes ();
+ reset_all_sys_modes ();
exit (1);
}
/* Called from init_sys_modes. */
void
-hft_init ()
+hft_init (struct tty_display_info *tty_out)
{
int junk;
/* If we're not on an HFT we shouldn't do any of this. We determine
if we are on an HFT by trying to get an HFT error code. If this
- call fails, we're not on an HFT. */
+ call fails, we're not on an HFT. */
#ifdef IBMR2AIX
if (ioctl (0, HFQERROR, &junk) < 0)
return;
keymap.hfkey[1].hf_char = 127;
hftctl (0, HFSKBD, &buf);
}
- /* The HFT system on AIX doesn't optimize for scrolling, so it's really ugly
- at times. */
- line_ins_del_ok = char_ins_del_ok = 0;
}
/* Reset the rubout key to backspace. */
void
-hft_reset ()
+hft_reset (struct tty_display_info *tty_out)
{
struct hfbuf buf;
struct hfkeymap keymap;
}
#endif /* HAVE_STRSIGNAL */
+/* arch-tag: edb43589-4e09-4544-b325-978b5b121dcf
+ (do not change this comment) */