/* Interfaces to system-dependent kernel and library entries.
- Copyright (C) 1985, 86, 87, 88, 93, 94 Free Software Foundation, Inc.
+ Copyright (C) 1985, 86, 87, 88, 93, 94, 95 Free Software Foundation, Inc.
This file is part of GNU Emacs.
You should have received a copy of the GNU General Public License
along with GNU Emacs; see the file COPYING. If not, write to
-the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
#include <signal.h>
#undef read
#undef write
+#ifdef WINDOWSNT
+#define read _read
+#define write _write
+#include <windows.h>
+extern int errno;
+#endif /* not WINDOWSNT */
+
#ifndef close
#define sys_close close
#else
#undef fwrite
#endif
+#ifndef HAVE_H_ERRNO
+extern int h_errno;
+#endif
+
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
+/* Get _POSIX_VDISABLE, if it is available. */
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+/* Get SI_SRPC_DOMAIN, if it is available. */
+#ifdef HAVE_SYS_SYSTEMINFO_H
+#include <sys/systeminfo.h>
+#endif
+
#ifdef MSDOS /* Demacs 1.1.2 91/10/20 Manabu Higashida, MW Aug 1993 */
#include <dos.h>
#include "dosfns.h"
#include "msdos.h"
#include <sys/param.h>
+
+#if __DJGPP__ > 1
+extern int etext;
+extern unsigned start __asm__ ("start");
+#endif
#endif
extern int errno;
#ifndef RAB$C_BID
#include <rab.h>
#endif
-#define MAXIOSIZE ( 32 * PAGESIZE ) /* Don't I/O more than 32 blocks at a time */
+#define MAXIOSIZE (32 * PAGESIZE) /* Don't I/O more than 32 blocks at a time */
#endif /* VMS */
#ifndef BSD4_1
-#ifdef BSD /* this is done this way to avoid defined (BSD) || defined (USG)
+#ifdef BSD_SYSTEM /* avoid writing defined (BSD_SYSTEM) || defined (USG)
because the vms compiler doesn't grok `defined' */
#include <fcntl.h>
#endif
#endif
#endif /* not 4.1 bsd */
-#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
-
#ifndef MSDOS
#include <sys/ioctl.h>
#endif
+
#include "systty.h"
#include "syswait.h"
#ifdef BROKEN_TIOCGWINSZ
#undef TIOCGWINSZ
+#undef TIOCSWINSZ
#endif
-#ifdef USG
+#if defined(USG) || defined(DGUX)
#include <sys/utsname.h>
#include <string.h>
#ifndef MEMORY_IN_STRING_H
#include <sys/ptem.h>
#endif
#endif /* TIOCGWINSZ or ISC4_0 */
-#endif /* USG */
+#endif /* USG or DGUX */
extern int quit_char;
#include "dispextern.h"
#include "process.h"
+#ifdef WINDOWSNT
+#include <direct.h>
+/* In process.h which conflicts with the local copy. */
+#define _P_WAIT 0
+int _CRTAPI1 _spawnlp (int, const char *, const char *, ...);
+int _CRTAPI1 _getpid (void);
+#endif
+
#ifdef NONSYSTEM_DIR_LIBRARY
#include "ndir.h"
#endif /* NONSYSTEM_DIR_LIBRARY */
#include "syssignal.h"
#include "systime.h"
+#ifdef HAVE_UTIME_H
+#include <utime.h>
+#endif
+
+#ifndef HAVE_UTIMES
+#ifndef HAVE_STRUCT_UTIMBUF
+/* We want to use utime rather than utimes, but we couldn't find the
+ structure declaration. We'll use the traditional one. */
+struct utimbuf {
+ long actime;
+ long modtime;
+};
+#endif
+#endif
+
+#ifndef VFORK_RETURN_TYPE
+#define VFORK_RETURN_TYPE int
+#endif
/* LPASS8 is new in 4.3, and makes cbreak mode provide all 8 bits. */
#ifndef LPASS8
};
#endif
+#if defined (HAVE_LIBNCURSES) && ! defined (NCURSES_OSPEED_T)
+extern short ospeed;
+#else
+#if defined (HAVE_TERMIOS_H) && defined (LINUX)
+#include <termios.h>
+/* HJL's version of libc is said to need this on the Alpha.
+ On the other hand, DEC OSF1 on the Alpha needs ospeed to be a short. */
+extern speed_t ospeed;
+#else
extern short ospeed;
+#endif
+#endif
/* The file descriptor for Emacs's input terminal.
- Under Unix, this is normaly zero except when using X;
- 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;
+ 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 *));
+
+
\f
/* Specify a different file descriptor for further input operations. */
/* Discard pending input on descriptor input_fd. */
+void
discard_tty_input ()
{
+#ifndef WINDOWSNT
struct emacs_tty buf;
if (noninteractive)
ioctl (input_fd, TIOCFLUSH, &zero);
}
#else /* not Apollo */
-#ifdef MSDOS /* Demacs 1.1.1 91/10/16 HIRANO Satoshi */
+#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);
#endif /* not MSDOS */
#endif /* not Apollo */
#endif /* not VMS */
+#endif /* not WINDOWSNT */
}
#ifdef SIGTSTP
/* Arrange for character C to be read as the next input from
the terminal. */
+void
stuff_char (c)
char c;
{
+ if (read_socket_hook)
+ return;
+
/* Should perhaps error if in batch mode */
#ifdef TIOCSTI
ioctl (input_fd, TIOCSTI, &c);
#endif /* SIGTSTP */
\f
+void
init_baud_rate ()
{
if (noninteractive)
ospeed = 0;
else
{
-#ifdef MSDOS
- ospeed = 15;
+#ifdef INIT_BAUD_RATE
+ INIT_BAUD_RATE ();
#else
+#ifdef DOS_NT
+ ospeed = 15;
+#else /* not DOS_NT */
#ifdef VMS
struct sensemode sg;
sg.c_cflag = B9600;
tcgetattr (input_fd, &sg);
ospeed = cfgetospeed (&sg);
+#if defined (USE_GETOBAUD) && defined (getobaud)
+ /* m88k-motorola-sysv3 needs this (ghazi@noc.rutgers.edu) 9/1/94. */
+ if (ospeed == 0)
+ ospeed = getobaud (sg.c_cflag);
+#endif
#else /* neither VMS nor TERMIOS */
#ifdef HAVE_TERMIO
struct termio sg;
#endif /* not HAVE_TERMIO */
#endif /* not HAVE_TERMIOS */
#endif /* not VMS */
-#endif /* not MSDOS */
+#endif /* not DOS_NT */
+#endif /* not INIT_BAUD_RATE */
}
baud_rate = (ospeed < sizeof baud_convert / sizeof baud_convert[0]
- ? baud_convert[ospeed] : 9600);
+ ? baud_convert[ospeed] : 9600);
if (baud_rate == 0)
baud_rate = 1200;
}
/*ARGSUSED*/
+void
set_exclusive_use (fd)
int fd;
{
wait_without_blocking ()
{
-#ifdef BSD
+#ifdef BSD_SYSTEM
wait3 (0, WNOHANG | WUNTRACED, 0);
#else
croak ("wait_without_blocking");
#endif /* not subprocesses */
int wait_debugging; /* Set nonzero to make following function work under dbx
- (at least for bsd). */
+ (at least for bsd). */
SIGTYPE
wait_for_termination_signal ()
/* Wait for subprocess with process id `pid' to terminate and
make sure it will get eliminated (not remain forever as a zombie) */
+void
wait_for_termination (pid)
int pid;
{
status = SYS$FORCEX (&pid, 0, 0);
break;
#else /* not VMS */
-#if defined (BSD) || (defined (HPUX) && !defined (HPUX_5))
+#if defined (BSD_SYSTEM) || (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. */
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;
sleep (1);
else
sigpause (SIGEMPTYMASK);
-#else /* not BSD, and not HPUX version >= 6 */
+#else /* not BSD_SYSTEM, and not HPUX version >= 6 */
#if defined (UNIPLUS)
if (0 > kill (pid, 0))
break;
wait (0);
-#else /* neither BSD nor UNIPLUS: random sysV */
-#ifdef POSIX_SIGNALS /* would this work for LINUX as well? */
+#else /* neither BSD_SYSTEM nor UNIPLUS: random sysV */
+#ifdef POSIX_SIGNALS /* would this work for LINUX as well? */
sigblock (sigmask (SIGCHLD));
if (0 > kill (pid, 0))
{
}
sigpause (SIGCHLD);
#else /* not HAVE_SYSV_SIGPAUSE */
+#ifdef WINDOWSNT
+ wait (0);
+ break;
+#else /* not WINDOWSNT */
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 WINDOWSNT */
#endif /* not HAVE_SYSV_SIGPAUSE */
#endif /* not POSIX_SIGNALS */
#endif /* not UNIPLUS */
-#endif /* not BSD, and not HPUX version >= 6 */
+#endif /* not BSD_SYSTEM, and not HPUX version >= 6 */
#endif /* not VMS */
#else /* not subprocesses */
+#if __DJGPP__ > 1
+ break;
+#else /* not __DJGPP__ > 1 */
#ifndef BSD4_1
if (kill (pid, 0) < 0)
break;
if (status == pid || status == -1)
break;
#endif /* BSD4_1 */
+#endif /* not __DJGPP__ > 1*/
#endif /* not subprocesses */
}
}
* (may flush input as well; it does not matter the way we use it)
*/
+void
flush_pending_output (channel)
int channel;
{
It should not echo or do line-editing, since that is done
in Emacs. No padding needed for insertion into an Emacs buffer. */
+void
child_setup_tty (out)
int out;
{
-#ifndef MSDOS
+#ifndef DOS_NT
struct emacs_tty s;
EMACS_GET_TTY (out, &s);
#ifdef IUCLC
s.main.c_iflag &= ~IUCLC; /* Disable downcasing on input. */
#endif
+#ifdef ISTRIP
+ s.main.c_iflag &= ~ISTRIP; /* don't strip 8th bit on input */
+#endif
#ifdef OLCUC
s.main.c_oflag &= ~OLCUC; /* Disable upcasing on output. */
#endif
+ s.main.c_oflag &= ~TAB3; /* Disable tab expansion */
s.main.c_cflag = (s.main.c_cflag & ~CSIZE) | CS8; /* Don't strip 8th bit */
#if 0
/* Said to be unnecessary: */
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 */
+ s.main.c_cc[VERASE] = CDISABLE; /* disable erase processing */
+ s.main.c_cc[VKILL] = CDISABLE; /* disable kill processing */
#ifdef HPUX
s.main.c_cflag = (s.main.c_cflag & ~CBAUD) | B9600; /* baud rate sanity */
ioctl (out, FIOASYNC, &zero);
}
#endif /* RTU */
-#endif /* not MSDOS */
+#endif /* not DOS_NT */
}
#endif /* not VMS */
#endif /* subprocesses */
-
-/*ARGSUSED*/
-setpgrp_of_tty (pid)
- int pid;
-{
- EMACS_SET_TTY_PGRP (input_fd, &pid);
-}
\f
/* Record a signal code and the handler for it. */
struct save_signal
{
int code;
- SIGTYPE (*handler) ();
+ SIGTYPE (*handler) P_ ((int));
};
+static void save_signal_handlers P_ ((struct save_signal *));
+static void restore_signal_handlers P_ ((struct save_signal *));
+
/* Suspend the Emacs process; give terminal to its superior. */
+void
sys_suspend ()
{
#ifdef VMS
/* Fork a subshell. */
+void
sys_subshell ()
{
#ifndef VMS
-#ifdef MSDOS /* Demacs 1.1.2 91/10/20 Manabu Higashida */
+#ifdef DOS_NT /* Demacs 1.1.2 91/10/20 Manabu Higashida */
int st;
char oldwd[MAXPATHLEN+1]; /* Fixed length is safe on MSDOS. */
#endif
- int pid = fork ();
+ int pid;
struct save_signal saved_handlers[5];
+ Lisp_Object dir;
+ unsigned char *str = 0;
+ int len;
saved_handlers[0].code = SIGINT;
saved_handlers[1].code = SIGQUIT;
saved_handlers[3].code = 0;
#endif
+ /* Mentioning current_buffer->buffer would mean including buffer.h,
+ which somehow wedges the hp compiler. So instead... */
+
+ dir = intern ("default-directory");
+ if (NILP (Fboundp (dir)))
+ goto xyzzy;
+ dir = Fsymbol_value (dir);
+ if (!STRINGP (dir))
+ goto xyzzy;
+
+ dir = expand_and_dir_to_file (Funhandled_file_name_directory (dir), Qnil);
+ str = (unsigned char *) alloca (XSTRING (dir)->size + 2);
+ len = XSTRING (dir)->size;
+ bcopy (XSTRING (dir)->data, str, len);
+ if (str[len - 1] != '/') str[len++] = '/';
+ str[len] = 0;
+ xyzzy:
+
+#ifdef DOS_NT
+ pid = 0;
+#if __DJGPP__ > 1
+ save_signal_handlers (saved_handlers);
+ synch_process_alive = 1;
+#endif /* __DJGPP__ > 1 */
+#else
+ pid = vfork ();
if (pid == -1)
error ("Can't spawn subshell");
+#endif
+
if (pid == 0)
{
- char *sh;
+ char *sh = 0;
-#ifdef MSDOS /* MW, Aug 1993 */
+#ifdef DOS_NT /* MW, Aug 1993 */
getwd (oldwd);
+ if (sh == 0)
+ sh = (char *) egetenv ("SUSPEND"); /* KFS, 1994-12-14 */
#endif
- sh = (char *) egetenv ("SHELL");
+ if (sh == 0)
+ sh = (char *) egetenv ("SHELL");
if (sh == 0)
sh = "sh";
/* Use our buffer's default directory for the subshell. */
- {
- Lisp_Object dir;
- unsigned char *str;
- int len;
-
- /* mentioning current_buffer->buffer would mean including buffer.h,
- which somehow wedges the hp compiler. So instead... */
-
- dir = intern ("default-directory");
- /* Can't use NILP */
- if (XFASTINT (Fboundp (dir)) == XFASTINT (Qnil))
- goto xyzzy;
- dir = Fsymbol_value (dir);
- if (XTYPE (dir) != Lisp_String)
- goto xyzzy;
-
- str = (unsigned char *) alloca (XSTRING (dir)->size + 2);
- len = XSTRING (dir)->size;
- bcopy (XSTRING (dir)->data, str, len);
- if (str[len - 1] != '/') str[len++] = '/';
- str[len] = 0;
+ if (str)
chdir (str);
- }
- xyzzy:
+
#ifdef subprocesses
close_process_descs (); /* Close Emacs's pipes/ptys */
#endif
}
#endif
-#ifdef MSDOS /* Demacs 1.1.2 91/10/20 Manabu Higashida */
+#ifdef MSDOS /* Demacs 1.1.2 91/10/20 Manabu Higashida */
st = system (sh);
chdir (oldwd);
+#if 0 /* This is also reported if last command executed in subshell failed, KFS */
if (st)
- report_file_error ("Can't execute subshell", Fcons (build_string (sh), Qnil));
+ report_file_error ("Can't execute subshell", Fcons (build_string (sh), Qnil));
+#endif
#else /* not MSDOS */
+#ifdef WINDOWSNT
+ /* Waits for process completion */
+ pid = _spawnlp (_P_WAIT, sh, sh, NULL);
+ chdir (oldwd);
+ if (pid == -1)
+ write (1, "Can't execute subshell", 22);
+#else /* not WINDOWSNT */
execlp (sh, sh, 0);
write (1, "Can't execute subshell", 22);
_exit (1);
+#endif /* not WINDOWSNT */
#endif /* not MSDOS */
}
+ /* Do this now if we did not do it before. */
+#if !defined (MSDOS) || __DJGPP__ == 1
save_signal_handlers (saved_handlers);
synch_process_alive = 1;
+#endif
+
+#ifndef DOS_NT
wait_for_termination (pid);
+#endif
restore_signal_handlers (saved_handlers);
+ synch_process_alive = 0;
#endif /* !VMS */
}
+static void
save_signal_handlers (saved_handlers)
struct save_signal *saved_handlers;
{
while (saved_handlers->code)
{
saved_handlers->handler
- = (SIGTYPE (*) ()) signal (saved_handlers->code, SIG_IGN);
+ = (SIGTYPE (*) P_ ((int))) signal (saved_handlers->code, SIG_IGN);
saved_handlers++;
}
}
+static void
restore_signal_handlers (saved_handlers)
struct save_signal *saved_handlers;
{
int old_fcntl_flags;
-init_sigio ()
+void
+init_sigio (fd)
+ int fd;
{
#ifdef FASYNC
- old_fcntl_flags = fcntl (input_fd, F_GETFL, 0) & ~FASYNC;
+ old_fcntl_flags = fcntl (fd, F_GETFL, 0) & ~FASYNC;
+ fcntl (fd, F_SETFL, old_fcntl_flags | FASYNC);
#endif
- request_sigio ();
+ interrupts_deferred = 0;
}
+void
reset_sigio ()
{
unrequest_sigio ();
#ifdef FASYNC /* F_SETFL does not imply existence of FASYNC */
+void
request_sigio ()
{
+ if (read_socket_hook)
+ return;
+
#ifdef SIGWINCH
sigunblock (sigmask (SIGWINCH));
#endif
interrupts_deferred = 0;
}
+void
unrequest_sigio ()
{
+ if (read_socket_hook)
+ return;
+
#ifdef SIGWINCH
sigblock (sigmask (SIGWINCH));
#endif
#else /* no FASYNC */
#ifdef STRIDE /* Stride doesn't have FASYNC - use FIOASYNC */
+void
request_sigio ()
{
int on = 1;
+
+ if (read_socket_hook)
+ return;
+
ioctl (input_fd, FIOASYNC, &on);
interrupts_deferred = 0;
}
+void
unrequest_sigio ()
{
int off = 0;
+ if (read_socket_hook)
+ return;
+
ioctl (input_fd, FIOASYNC, &off);
interrupts_deferred = 1;
}
#include <termios.h>
+void
request_sigio ()
{
int on = 1;
sigset_t st;
+ if (read_socket_hook)
+ return;
+
sigemptyset(&st);
sigaddset(&st, SIGIO);
ioctl (input_fd, FIOASYNC, &on);
sigprocmask(SIG_UNBLOCK, &st, (sigset_t *)0);
}
+void
unrequest_sigio ()
{
int off = 0;
+ if (read_socket_hook)
+ return;
+
ioctl (input_fd, FIOASYNC, &off);
interrupts_deferred = 1;
}
#else /* ! _CX_UX */
+void
request_sigio ()
{
+ if (read_socket_hook)
+ return;
+
croak ("request_sigio");
}
+void
unrequest_sigio ()
{
+ if (read_socket_hook)
+ return;
+
croak ("unrequest_sigio");
}
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. */
+void
narrow_foreground_group ()
{
int me = getpid ();
}
/* Set the tty to our original foreground group. */
+void
widen_foreground_group ()
{
if (inherited_pgroup != getpid ())
/* Retrieve the primary parameters - baud rate, character size, etcetera. */
#ifdef HAVE_TCATTR
/* We have those nifty POSIX tcmumbleattr functions. */
+ bzero (&settings->main, sizeof (settings->main));
if (tcgetattr (fd, &settings->main) < 0)
return -1;
return -1;
#else
-#ifndef MSDOS
+#ifndef DOS_NT
/* I give up - I hope you have the BSD ioctls. */
if (ioctl (fd, TIOCGETP, &settings->main) < 0)
return -1;
-#endif /* not MSDOS */
+#endif /* not DOS_NT */
#endif
#endif
#endif
/* 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.
+ *SETTINGS. If FLUSHP is non-zero, we discard input.
Return 0 if all went well, and -1 if anything failed. */
+
int
-emacs_set_tty (fd, settings, waitp)
+emacs_set_tty (fd, settings, flushp)
int fd;
struct emacs_tty *settings;
- int waitp;
+ int flushp;
{
/* Set the primary parameters - baud rate, character size, etcetera. */
#ifdef HAVE_TCATTR
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 (tcsetattr (fd, flushp ? TCSAFLUSH : TCSADRAIN, &settings->main) < 0)
{
if (errno == EINTR)
continue;
{
struct termios new;
+ bzero (&new, sizeof (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
#else
#ifdef HAVE_TERMIO
/* The SYSV-style interface? */
- if (ioctl (fd, waitp ? TCSETAW : TCSETAF, &settings->main) < 0)
+ if (ioctl (fd, flushp ? TCSETAF : TCSETAW, &settings->main) < 0)
return -1;
#else
return -1;
#else
-#ifndef MSDOS
+#ifndef DOS_NT
/* I give up - I hope you have the BSD ioctls. */
- if (ioctl (fd, (waitp) ? TIOCSETP : TIOCSETN, &settings->main) < 0)
+ if (ioctl (fd, (flushp) ? TIOCSETP : TIOCSETN, &settings->main) < 0)
return -1;
-#endif /* not MSDOS */
+#endif /* not DOS_NT */
#endif
#endif
/* The initial tty mode bits */
struct emacs_tty old_tty;
-int term_initted; /* 1 if outer tty status has been recorded */
+/* 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
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};
+static struct tchars new_tchars = {-1,-1,-1,-1,-1,-1};
#endif
+void
init_sys_modes ()
{
struct emacs_tty tty;
#endif
#endif
+ Vtty_erase_char = Qnil;
+
if (noninteractive)
return;
narrow_foreground_group ();
#endif
- EMACS_GET_TTY (input_fd, &old_tty);
-
+#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))
+#endif
{
+ EMACS_GET_TTY (input_fd, &old_tty);
+
+ old_tty_valid = 1;
+
tty = old_tty;
#if defined (HAVE_TERMIO) || defined (HAVE_TERMIOS)
+ XSETINT (Vtty_erase_char, old_tty.main.c_cc[VERASE]);
+
+#ifdef DGUX
+ /* This allows meta to be sent on 8th bit. */
+ tty.main.c_iflag &= ~INPCK; /* don't check input for parity */
+#endif
tty.main.c_iflag |= (IGNBRK); /* Ignore break condition */
tty.main.c_iflag &= ~ICRNL; /* Disable map of CR to NL on input */
+#ifdef INLCR /* I'm just being cautious,
+ since I can't check how widespread INLCR is--rms. */
+ tty.main.c_iflag &= ~INLCR; /* Disable map of NL to CR on input */
+#endif
#ifdef ISTRIP
tty.main.c_iflag &= ~ISTRIP; /* don't strip 8th bit on input */
#endif
tty.main.c_cc[VSWTCH] = CDISABLE; /* Turn off shell layering use
of C-z */
#endif /* VSWTCH */
+
#if defined (mips) || defined (HAVE_TCATTR)
#ifdef VSUSP
tty.main.c_cc[VSUSP] = CDISABLE; /* Turn off mips handling of C-z. */
#ifdef VDISCARD
tty.main.c_cc[VDISCARD] = CDISABLE;
#endif /* VDISCARD */
+
+ if (flow_control)
+ {
+#ifdef VSTART
+ tty.main.c_cc[VSTART] = '\021';
+#endif /* VSTART */
+#ifdef VSTOP
+ tty.main.c_cc[VSTOP] = '\023';
+#endif /* VSTOP */
+ }
+ else
+ {
+#ifdef VSTART
+ tty.main.c_cc[VSTART] = CDISABLE;
+#endif /* VSTART */
+#ifdef VSTOP
+ tty.main.c_cc[VSTOP] = CDISABLE;
+#endif /* VSTOP */
+ }
#endif /* mips or HAVE_TCATTR */
+
+#ifdef SET_LINE_DISCIPLINE
+ /* Need to explicitly request TERMIODISC line discipline or
+ Ultrix's termios does not work correctly. */
+ tty.main.c_line = SET_LINE_DISCIPLINE;
+#endif
#ifdef AIX
#ifndef IBMR2AIX
- /* AIX enhanced edit loses NULs, so disable it */
+ /* AIX enhanced edit loses NULs, so disable it. */
tty.main.c_line = 0;
tty.main.c_iflag &= ~ASCEDIT;
#else
tty.main.c_cc[VSUSP] = 255;
tty.main.c_cc[VDSUSP] = 255;
#endif /* IBMR2AIX */
+ if (flow_control)
+ {
+#ifdef VSTART
+ tty.main.c_cc[VSTART] = '\021';
+#endif /* VSTART */
+#ifdef VSTOP
+ tty.main.c_cc[VSTOP] = '\023';
+#endif /* VSTOP */
+ }
/* 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
tty.main.tt_char &= ~TT$M_TTSYNC;
tty.main.tt2_char |= TT2$M_PASTHRU | TT2$M_XON;
#else /* not VMS (BSD, that is) */
-#ifndef MSDOS
+#ifndef DOS_NT
+ XSETINT (Vtty_erase_char, tty.main.sg_erase);
tty.main.sg_flags &= ~(ECHO | CRMOD | XTABS);
if (meta_key)
tty.main.sg_flags |= ANYP;
tty.main.sg_flags |= interrupt_input ? RAW : CBREAK;
-#endif
+#endif /* not DOS_NT */
#endif /* not VMS (BSD, that is) */
#endif /* not HAVE_TERMIO */
tty.ltchars = new_ltchars;
#endif /* HAVE_LTCHARS */
#ifdef MSDOS /* Demacs 1.1.2 91/10/20 Manabu Higashida, MW Aug 1993 */
- internal_terminal_init ();
+ if (!term_initted)
+ internal_terminal_init ();
dos_ttraw ();
#endif
#endif
#endif
-#ifdef AIX
+#if defined (HAVE_TERMIOS) || defined (HPUX9)
+#ifdef TCOON
+ if (!flow_control) tcflow (input_fd, TCOON);
+#endif
+#endif
+
+#ifdef AIXHFT
hft_init ();
#ifdef IBMR2AIX
{
write (1, "\033[20l", 5);
}
#endif
-#endif
+#endif /* AIXHFT */
#ifdef VMS
/* Appears to do nothing when in PASTHRU mode.
#ifdef F_SETFL
#ifndef F_SETOWN_BUG
#ifdef F_GETOWN /* F_SETFL does not imply existence of F_GETOWN */
- if (interrupt_input)
+ if (interrupt_input
+ && ! read_socket_hook && EQ (Vwindow_system, Qnil))
{
old_fcntl_owner = fcntl (input_fd, F_GETOWN, 0);
fcntl (input_fd, F_SETOWN, getpid ());
- init_sigio ();
+ init_sigio (input_fd);
}
#endif /* F_GETOWN */
#endif /* F_SETOWN_BUG */
#ifdef BSD4_1
if (interrupt_input)
- init_sigio ();
+ init_sigio (input_fd);
#endif
#ifdef VMS /* VMS sometimes has this symbol but lacks setvbuf. */
#else
setbuf (stdout, _sobuf);
#endif
- set_terminal_modes ();
+#ifdef HAVE_WINDOW_SYSTEM
+ /* Emacs' window system on MSDOG uses the `internal terminal' and therefore
+ needs the initialization code below. */
+ if (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 initialization code below. */
+ && (! read_socket_hook)
+#endif
+ )
+#endif
+ set_terminal_modes ();
+
if (term_initted && no_redraw_on_reenter)
{
if (display_completed)
else
{
frame_garbaged = 1;
-#ifdef MULTI_FRAME
if (FRAMEP (Vterminal_frame))
FRAME_GARBAGED_P (XFRAME (Vterminal_frame)) = 1;
-#endif
}
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 ()
{
struct emacs_tty tty;
Store number of lines into *HEIGHTP and width into *WIDTHP.
We store 0 if there's no valid information. */
+void
get_frame_size (widthp, heightp)
int *widthp, *heightp;
{
\f
/* Prepare the terminal for exiting Emacs; move the cursor to the
bottom of the frame, turn off interrupt-driven I/O, etc. */
+void
reset_sys_modes ()
{
if (noninteractive)
}
if (!term_initted)
return;
- if (read_socket_hook || !EQ (Vwindow_system, Qnil))
+#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)
+#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
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 (FRAME_HEIGHT (selected_frame) - 1, 0);
-#ifdef IBMR2AIX
+#if defined (IBMR2AIX) && defined (AIXHFT)
{
/* HFT devices normally use ^J as a LF/CR. We forced it to
do the LF only. Now, we need to reset it. */
reset_terminal_modes ();
fflush (stdout);
-#ifdef BSD
+#ifdef BSD_SYSTEM
#ifndef BSD4_1
/* Avoid possible loss of output when changing terminal modes. */
fsync (fileno (stdout));
reset_sigio ();
#endif /* BSD4_1 */
- while (EMACS_SET_TTY (input_fd, &old_tty, 0) < 0 && errno == EINTR)
- ;
+ if (old_tty_valid)
+ while (EMACS_SET_TTY (input_fd, &old_tty, 0) < 0 && errno == EINTR)
+ ;
#ifdef MSDOS /* Demacs 1.1.2 91/10/20 Manabu Higashida */
dos_ttcooked ();
#endif
-#ifdef AIX
+#ifdef SET_LINE_DISCIPLINE
+ /* 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);
+#endif
+
+#ifdef AIXHFT
hft_reset ();
#endif
/* Set up the proper status flags for use of a pty. */
+void
setup_pty (fd)
int fd;
{
This is called each time Emacs is resumed, also, but does nothing
because input_chain is no longer zero. */
+void
init_vms_input ()
{
int status;
/* Deassigning the input channel is done before exiting. */
+void
stop_vms_input ()
{
return SYS$DASSGN (input_fd);
/* Request reading one character into the keyboard buffer.
This is done as soon as the buffer becomes empty. */
+void
queue_kbd_input ()
{
int status;
/* Ast routine that is called when keyboard input comes in
in accord with the SYS$QIO above. */
+void
kbd_input_ast ()
{
register int c = -1;
{
struct input_event e;
e.kind = ascii_keystroke;
- 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
+ XSETINT (e.code, c);
+ XSETFRAME (e.frame_or_window, selected_frame);
kbd_buffer_store_event (&e);
}
if (input_available_clear_time)
/* Wait until there is something in kbd_buffer. */
+void
wait_for_kbd_input ()
{
extern int have_process_input, process_exited;
and therefore there is no I/O request queued when we return.
SYS$SETAST is used to avoid a timing error. */
+void
end_kbd_input ()
{
#ifdef ASTDEBUG
/* Wait for either input available or time interval expiry. */
+void
input_wait_timeout (timeval)
int timeval; /* Time to wait, in seconds */
{
SYS$WAITFR (timer_ef); /* Wait for timer expiry only */
}
-init_sigio ()
+void
+init_sigio (fd)
+ int fd;
{
request_sigio ();
}
unrequest_sigio ();
}
+void
request_sigio ()
{
croak ("request sigio");
}
+void
unrequest_sigio ()
{
croak ("unrequest sigio");
*
*/
-#if !defined (CANNOT_UNEXEC) && !defined (HAVE_TEXT_START)
+#ifndef HAVE_TEXT_START
char *
start_of_text ()
{
#endif /* GOULD */
#endif /* TEXT_START */
}
-#endif /* not CANNOT_UNEXEC and not HAVE_TEXT_START */
+#endif /* not HAVE_TEXT_START */
/*
* Return the address of the start of the data segment prior to
* at least on UniPlus, is temacs will have to be made unshared so
* that text and data are contiguous. Then once loadup is complete,
* unexec will produce a shared executable where the data can be
- * at the normal shared text boundry and the startofdata variable
+ * at the normal shared text boundary and the startofdata variable
* will be patched by unexec to the correct value.
*
*/
#endif /* not CANNOT_DUMP */
\f
-/* get_system_name returns as its value
- a string for the Lisp function system-name to return. */
+/* init_system_name sets up the string for the Lisp function
+ system-name to return. */
#ifdef BSD4_1
#include <whoami.h>
#endif
-/* Can't have this within the function since `static' is #defined to
- nothing for some USG systems. */
-static char *get_system_name_cache;
-static int get_system_name_predump_p;
+extern Lisp_Object Vsystem_name;
#ifndef BSD4_1
#ifndef VMS
#endif /* not VMS */
#endif /* not BSD4_1 */
-char *
-get_system_name ()
+void
+init_system_name ()
{
#ifdef BSD4_1
- return sysname;
+ Vsystem_name = build_string (sysname);
#else
-#ifndef CANNOT_DUMP
- /* If the cached value is from before the dump, and we've dumped
- since then, then the cached value is no good. */
- if (get_system_name_predump_p && initialized && get_system_name_cache)
- {
- xfree (get_system_name_cache);
- get_system_name_cache = 0;
- }
-#endif
- if (!get_system_name_cache)
- {
- /* No cached value, so get the name from the system. */
#ifdef VMS
- char *sp;
- if ((sp = egetenv ("SYS$NODE")) == 0)
- sp = "vax-vms";
- else
- {
- char *end;
-
- if ((end = index (sp, ':')) != 0)
- *end = '\0';
- }
- get_system_name_cache = (char *) xmalloc (strlen (sp) + 1);
- strcpy (get_system_name_cache, sp);
+ char *sp, *end;
+ if ((sp = egetenv ("SYS$NODE")) == 0)
+ Vsystem_name = build_string ("vax-vms");
+ else if ((end = index (sp, ':')) == 0)
+ Vsystem_name = build_string (sp);
+ else
+ Vsystem_name = make_string (sp, end - sp);
#else
#ifndef HAVE_GETHOSTNAME
- struct utsname uts;
- uname (&uts);
- get_system_name_cache = (char *) xmalloc (strlen (uts.nodename) + 1);
- strcpy (get_system_name_cache, uts.nodename);
+ struct utsname uts;
+ uname (&uts);
+ Vsystem_name = build_string (uts.nodename);
#else /* HAVE_GETHOSTNAME */
- {
- int hostname_size = 256;
- char *hostname = (char *) xmalloc (hostname_size);
-
- /* Try to get the host name; if the buffer is too short, try
- again. Apparently, the only indication gethostname gives of
- whether the buffer was large enough is the presence or absence
- of a '\0' in the string. Eech. */
- for (;;)
- {
- gethostname (hostname, hostname_size - 1);
- hostname[hostname_size - 1] = '\0';
+ unsigned int hostname_size = 256;
+ char *hostname = (char *) alloca (hostname_size);
+
+ /* Try to get the host name; if the buffer is too short, try
+ again. Apparently, the only indication gethostname gives of
+ whether the buffer was large enough is the presence or absence
+ of a '\0' in the string. Eech. */
+ for (;;)
+ {
+ gethostname (hostname, hostname_size - 1);
+ hostname[hostname_size - 1] = '\0';
- /* Was the buffer large enough for the '\0'? */
- if (strlen (hostname) < hostname_size - 1)
- break;
+ /* Was the buffer large enough for the '\0'? */
+ if (strlen (hostname) < hostname_size - 1)
+ break;
- hostname_size <<= 1;
- hostname = (char *) xrealloc (hostname, hostname_size);
- }
- get_system_name_cache = hostname;
+ hostname_size <<= 1;
+ hostname = (char *) alloca (hostname_size);
+ }
#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. */
+ /* 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)
+ if (initialized)
#endif /* not CANNOT_DUMP */
+ if (! index (hostname, '.'))
+ {
+ struct hostent *hp;
+ int count;
+ for (count = 0;; count++)
+ {
+#ifdef TRY_AGAIN
+ h_errno = 0;
+#endif
+ hp = gethostbyname (hostname);
+#ifdef TRY_AGAIN
+ if (! (hp == 0 && h_errno == TRY_AGAIN))
+#endif
+ break;
+ if (count >= 5)
+ break;
+ Fsleep_for (make_number (1), Qnil);
+ }
+ if (hp)
{
- struct hostent *hp = gethostbyname (hostname);
- if (hp)
+ char *fqdn = (char *) hp->h_name;
+ char *p;
+
+ if (!index (fqdn, '.'))
{
- char *fqdn = hp->h_name;
- char *p;
-
- if (!index (fqdn, '.'))
- {
- /* We still don't have a fully qualified domain name.
- Try to find one in the list of alternate names */
- char **alias = hp->h_aliases;
- while (*alias && !index (*alias, '.'))
- alias++;
- if (*alias)
- fqdn = *alias;
- }
- hostname = (char *) xrealloc (hostname, strlen (fqdn) + 1);
- strcpy (hostname, fqdn);
+ /* We still don't have a fully qualified domain name.
+ Try to find one in the list of alternate names */
+ char **alias = hp->h_aliases;
+ while (*alias && !index (*alias, '.'))
+ alias++;
+ if (*alias)
+ fqdn = *alias;
+ }
+ hostname = fqdn;
#if 0
- /* Convert the host name to lower case. */
- /* Using ctype.h here would introduce a possible locale
- dependence that is probably wrong for hostnames. */
- p = hostname
- while (*p)
- {
- if (*p >= 'A' && *p <= 'Z')
- *p += 'a' - 'A';
- p++;
- }
-#endif
+ /* Convert the host name to lower case. */
+ /* Using ctype.h here would introduce a possible locale
+ dependence that is probably wrong for hostnames. */
+ p = hostname;
+ while (*p)
+ {
+ if (*p >= 'A' && *p <= 'Z')
+ *p += 'a' - 'A';
+ p++;
}
+#endif
}
-#endif /* HAVE_SOCKETS */
- get_system_name_cache = hostname;
}
+#endif /* HAVE_SOCKETS */
+ /* We used to try using getdomainname here,
+ but NIIBE Yutaka <gniibe@etl.go.jp> says that
+ getdomainname gets the NIS/YP domain which often is not the same
+ as in Internet domain name. */
+#if 0 /* Turned off because sysinfo is not really likely to return the
+ correct Internet domain. */
+#if (HAVE_SYSINFO && defined (SI_SRPC_DOMAIN))
+ if (! index (hostname, '.'))
+ {
+ /* The hostname is not fully qualified. Append the domain name. */
+
+ int hostlen = strlen (hostname);
+ int domain_size = 256;
+
+ for (;;)
+ {
+ char *domain = (char *) alloca (domain_size + 1);
+ char *fqdn = (char *) alloca (hostlen + 1 + domain_size + 1);
+ int sys_domain_size = sysinfo (SI_SRPC_DOMAIN, domain, domain_size);
+ if (sys_domain_size <= 0)
+ break;
+ if (domain_size < sys_domain_size)
+ {
+ domain_size = sys_domain_size;
+ continue;
+ }
+ strcpy (fqdn, hostname);
+ if (domain[0] == '.')
+ strcpy (fqdn + hostlen, domain);
+ else if (domain[0] != 0)
+ {
+ fqdn[hostlen] = '.';
+ strcpy (fqdn + hostlen + 1, domain);
+ }
+ hostname = fqdn;
+ break;
+ }
+ }
+#endif /* HAVE_SYSINFO && defined (SI_SRPC_DOMAIN) */
+#endif /* 0 */
+ Vsystem_name = build_string (hostname);
#endif /* HAVE_GETHOSTNAME */
#endif /* VMS */
-#ifndef CANNOT_DUMP
- get_system_name_predump_p = !initialized;
-#endif
- }
- return (get_system_name_cache);
#endif /* BSD4_1 */
+ {
+ unsigned char *p;
+ for (p = XSTRING (Vsystem_name)->data; *p; p++)
+ if (*p == ' ' || *p == '\t')
+ *p = '-';
+ }
}
\f
+#ifndef MSDOS
#ifndef VMS
-#ifndef HAVE_SELECT
+#if !defined (HAVE_SELECT) || defined (BROKEN_SELECT_NON_X)
-#ifdef HAVE_X_WINDOWS
+#include "sysselect.h"
+#undef select
+
+#if defined (HAVE_X_WINDOWS) && !defined (HAVE_SELECT)
/* Cause explanatory error message at compile time,
since the select emulation is not good enough for X. */
int *x = &x_windows_lose_if_no_select_system_call;
longjmp (read_alarm_throw, 1);
}
+#ifndef WINDOWSNT
/* Only rfds are checked. */
int
-select (nfds, rfds, wfds, efds, timeout)
+sys_select (nfds, rfds, wfds, efds, timeout)
int nfds;
- int *rfds, *wfds, *efds, *timeout;
+ SELECT_TYPE *rfds, *wfds, *efds;
+ EMACS_TIME *timeout;
{
- int ravail = 0, orfds = 0, old_alarm;
- int timeoutval = timeout ? *timeout : 100000;
- int *local_timeout = &timeoutval;
+ int ravail = 0, old_alarm;
+ SELECT_TYPE orfds;
+ int timeoutval;
+ int *local_timeout;
extern int proc_buffered_char[];
#ifndef subprocesses
int process_tick = 0, update_tick = 0;
SIGTYPE (*old_trap) ();
unsigned char buf;
+#if defined (HAVE_SELECT) && defined (HAVE_X_WINDOWS)
+ /* If we're using X, then the native select will work; we only need the
+ emulation for non-X usage. */
+ if (!NILP (Vwindow_system))
+ return select (nfds, rfds, wfds, efds, timeout);
+#endif
+ timeoutval = timeout ? EMACS_SECS (*timeout) : 100000;
+ local_timeout = &timeoutval;
+ FD_ZERO (&orfds);
if (rfds)
{
orfds = *rfds;
- *rfds = 0;
+ FD_ZERO (rfds);
}
if (wfds)
- *wfds = 0;
+ FD_ZERO (wfds);
if (efds)
- *efds = 0;
+ FD_ZERO (efds);
/* If we are looking only for the terminal, with no timeout,
just read it and wait -- that's more efficient. */
- if (orfds == 1 && *local_timeout == 100000 && process_tick == update_tick)
+ if (*local_timeout == 100000 && process_tick == update_tick
+ && FD_ISSET (0, &orfds))
{
+ int fd;
+ for (fd = 1; fd < nfds; ++fd)
+ if (FD_ISSET (fd, &orfds))
+ goto hardway;
if (! detect_input_pending ())
read_input_waiting ();
- *rfds = 1;
+ FD_SET (0, rfds);
return 1;
}
+ hardway:
/* 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, bit, fd;
+ register int to_check, fd;
if (rfds)
{
- for (to_check = nfds, bit = 1, fd = 0; --to_check >= 0; bit <<= 1, fd++)
+ for (to_check = nfds, fd = 0; --to_check >= 0; fd++)
{
- if (orfds & bit)
+ if (FD_ISSET (fd, &orfds))
{
int avail = 0, status = 0;
- if (bit == 1)
+ if (fd == 0)
avail = detect_input_pending (); /* Special keyboard handler */
else
{
#ifdef FIONREAD
status = ioctl (fd, FIONREAD, &avail);
#else /* no FIONREAD */
-#ifdef MSDOS
- abort (); /* I don't think we need it. */
-#else /* not MSDOS */
/* Hoping it will return -1 if nothing available
or 0 if all 0 chars requested are read. */
if (proc_buffered_char[fd] >= 0)
if (avail > 0)
proc_buffered_char[fd] = buf;
}
-#endif /* not MSDOS */
#endif /* no FIONREAD */
}
if (status >= 0 && avail > 0)
{
- (*rfds) |= bit;
+ FD_SET (fd, rfds);
ravail++;
}
}
while (select_alarmed == 0 && *local_timeout != 0
&& process_tick == update_tick)
{
-#ifdef MSDOS
- sleep_or_kbd_hit (SELECT_PAUSE, (orfds & 1) != 0);
- select_alarm ();
-#else /* not MSDOS */
/* If we are interested in terminal input,
wait by reading the terminal.
That makes instant wakeup for terminal input at least. */
- if (orfds & 1)
+ if (FD_ISSET (0, &orfds))
{
read_input_waiting ();
if (detect_input_pending ())
}
else
pause ();
-#endif /* not MSDOS */
}
(*local_timeout) -= SELECT_PAUSE;
/* Reset the old alarm if there was one */
}
return ravail;
}
+#endif /* not WINDOWSNT */
/* Read keyboard input into the standard buffer,
waiting for at least one character. */
-/* Make all keyboard buffers much bigger when using X windows. */
-#ifdef HAVE_X_WINDOWS
+/* Make all keyboard buffers much bigger when using a window system. */
+#ifdef HAVE_WINDOW_SYSTEM
#define BUFFER_SIZE_FACTOR 16
#else
#define BUFFER_SIZE_FACTOR 1
#endif
+void
read_input_waiting ()
{
struct input_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].kind == ascii_keystroke
- && XINT(buf[i].code) == quit_char)
+ && buf[i].code == quit_char)
break;
}
}
/* Scan the chars for C-g and store them in kbd_buffer. */
e.kind = ascii_keystroke;
- e.frame_or_window = selected_frame;
+ XSETFRAME (e.frame_or_window, selected_frame);
e.modifiers = 0;
for (i = 0; i < nread; i++)
{
buf[i] &= ~0x80;
}
- XSET (e.code, Lisp_Int, buf[i]);
+ XSETINT (e.code, 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. */
#endif /* not HAVE_SELECT */
#endif /* not VMS */
+#endif /* not MSDOS */
\f
#ifdef BSD4_1
/*
return open (path, oflag);
}
-init_sigio ()
+void
+init_sigio (fd)
+ int fd;
{
if (noninteractive)
return;
lmode = LINTRUP | lmode;
- ioctl (0, TIOCLSET, &lmode);
+ ioctl (fd, TIOCLSET, &lmode);
}
+void
reset_sigio ()
{
if (noninteractive)
ioctl (0, TIOCLSET, &lmode);
}
+void
request_sigio ()
{
sigrelse (SIGTINT);
interrupts_deferred = 0;
}
+void
unrequest_sigio ()
{
sighold (SIGTINT);
int sigheld; /* Mask of held signals */
+void
sigholdx (signum)
int signum;
{
sighold (signum);
}
+void
sigisheld (signum)
int signum;
{
sigheld |= sigbit (signum);
}
+void
sigunhold (signum)
int signum;
{
sigrelse (signum);
}
+void
sigfree () /* Free all held signals */
{
int i;
sigheld = 0;
}
+int
sigbit (i)
{
return 1 << (i - 1);
#ifdef POSIX_SIGNALS
-sigset_t old_mask, empty_mask, full_mask, temp_mask;
-static struct sigaction new_action, old_action;
+sigset_t empty_mask, full_mask;
+void
init_signals ()
{
sigemptyset (&empty_mask);
signal_handler_t
sys_signal (int signal_number, signal_handler_t action)
{
-#ifdef DGUX
- /* This gets us restartable system calls for efficiency.
- The "else" code will works as well. */
- return (berk_signal (signal_number, action));
-#else
+ struct sigaction new_action, old_action;
sigemptyset (&new_action.sa_mask);
new_action.sa_handler = action;
#ifdef SA_RESTART
#endif
sigaction (signal_number, &new_action, &old_action);
return (old_action.sa_handler);
-#endif /* DGUX */
}
#ifndef __GNUC__
}
#endif
-int
-sys_sigpause (sigset_t new_mask)
-{
- /* pause emulating berk sigpause... */
- sigsuspend (&new_mask);
- return (EINTR);
-}
-
/* I'd like to have these guys return pointers to the mask storage in here,
but there'd be trouble if the code was saving multiple masks. I'll be
safe and pass the structure. It normally won't be more than 2 bytes
#endif /* POSIX_SIGNALS */
\f
-#ifndef BSTRING
+#ifndef HAVE_RANDOM
+#ifdef random
+#define HAVE_RANDOM
+#endif
+#endif
-#ifndef bzero
+/* Figure out how many bits the system's random number generator uses.
+ `random' and `lrand48' are assumed to return 31 usable bits.
+ BSD `rand' returns a 31 bit value but the low order bits are unusable;
+ so we'll shift it and treat it like the 15-bit USG `rand'. */
+
+#ifndef RAND_BITS
+# ifdef HAVE_RANDOM
+# define RAND_BITS 31
+# else /* !HAVE_RANDOM */
+# ifdef HAVE_LRAND48
+# define RAND_BITS 31
+# define random lrand48
+# else /* !HAVE_LRAND48 */
+# define RAND_BITS 15
+# if RAND_MAX == 32767
+# define random rand
+# else /* RAND_MAX != 32767 */
+# if RAND_MAX == 2147483647
+# define random() (rand () >> 16)
+# else /* RAND_MAX != 2147483647 */
+# ifdef USG
+# define random rand
+# else
+# define random() (rand () >> 16)
+# endif /* !USG */
+# endif /* RAND_MAX != 2147483647 */
+# endif /* RAND_MAX != 32767 */
+# endif /* !HAVE_LRAND48 */
+# endif /* !HAVE_RANDOM */
+#endif /* !RAND_BITS */
void
-bzero (b, length)
- register char *b;
- register int length;
-{
-#ifdef VMS
- short zero = 0;
- long max_str = 65535;
-
- while (length > max_str) {
- (void) LIB$MOVC5 (&zero, &zero, &zero, &max_str, b);
- length -= max_str;
- b += max_str;
- }
- max_str = length;
- (void) LIB$MOVC5 (&zero, &zero, &zero, &max_str, b);
-#else
- while (length-- > 0)
- *b++ = 0;
-#endif /* not VMS */
-}
-
-#endif /* no bzero */
-
-#ifndef bcopy
-/* Saying `void' requires a declaration, above, where bcopy is used
- and that declaration causes pain for systems where bcopy is a macro. */
-bcopy (b1, b2, length)
- register char *b1;
- register char *b2;
- register int length;
-{
-#ifdef VMS
- long max_str = 65535;
-
- while (length > max_str) {
- (void) LIB$MOVC3 (&max_str, b1, b2);
- length -= max_str;
- b1 += max_str;
- b2 += max_str;
- }
- max_str = length;
- (void) LIB$MOVC3 (&length, b1, b2);
-#else
- while (length-- > 0)
- *b2++ = *b1++;
-#endif /* not VMS */
-}
-#endif /* no bcopy */
-
-#ifndef bcmp
-int
-bcmp (b1, b2, length) /* This could be a macro! */
- register char *b1;
- register char *b2;
- register int length;
+seed_random (arg)
+ long arg;
{
-#ifdef VMS
- struct dsc$descriptor_s src1 = {length, DSC$K_DTYPE_T, DSC$K_CLASS_S, b1};
- struct dsc$descriptor_s src2 = {length, DSC$K_DTYPE_T, DSC$K_CLASS_S, b2};
-
- return STR$COMPARE (&src1, &src2);
+#ifdef HAVE_RANDOM
+ srandom ((unsigned int)arg);
#else
- while (length-- > 0)
- if (*b1++ != *b2++)
- return 1;
-
- return 0;
-#endif /* not VMS */
+# ifdef HAVE_LRAND48
+ srand48 (arg);
+# else
+ srand ((unsigned int)arg);
+# endif
+#endif
}
-#endif /* no bcmp */
-#endif /* not BSTRING */
-\f
-#ifndef HAVE_RANDOM
-#ifdef USG
/*
- * The BSD random returns numbers in the range of
- * 0 to 2e31 - 1. The USG rand returns numbers in the
- * range of 0 to 2e15 - 1. This is probably not significant
- * in this usage.
+ * Build a full Emacs-sized word out of whatever we've got.
+ * This suffices even for a 64-bit architecture with a 15-bit rand.
*/
-
long
-random ()
-{
- /* Arrange to return a range centered on zero. */
- return (rand () << 15) + rand () - (1 << 29);
-}
-
-srandom (arg)
- int arg;
-{
- srand (arg);
-}
-
-#endif /* USG */
-
-#ifdef BSD4_1
-long random ()
-{
- /* Arrange to return a range centered on zero. */
- return (rand () << 15) + rand () - (1 << 29);
-}
-
-srandom (arg)
- int arg;
-{
- srand (arg);
+get_random ()
+{
+ long val = random ();
+#if VALBITS > RAND_BITS
+ val = (val << RAND_BITS) ^ random ();
+#if VALBITS > 2*RAND_BITS
+ val = (val << RAND_BITS) ^ random ();
+#if VALBITS > 3*RAND_BITS
+ val = (val << RAND_BITS) ^ random ();
+#if VALBITS > 4*RAND_BITS
+ val = (val << RAND_BITS) ^ random ();
+#endif /* need at least 5 */
+#endif /* need at least 4 */
+#endif /* need at least 3 */
+#endif /* need at least 2 */
+ return val & ((1L << VALBITS) - 1);
}
-#endif /* BSD4_1 */
-#endif
\f
#ifdef WRONG_NAME_INSQUE
\f
#ifdef VMS
#ifdef LINK_CRTL_SHARE
-#ifdef SHAREABLE_LIB_BUG
+#ifdef SHARABLE_LIB_BUG
/* 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
"I/O stream empty",
"vax/vms specific error code nontranslatable error"
};
-#endif /* SHAREABLE_LIB_BUG */
+#endif /* SHARABLE_LIB_BUG */
#endif /* LINK_CRTL_SHARE */
#endif /* VMS */
#ifndef HAVE_STRERROR
+#ifndef WINDOWSNT
char *
strerror (errnum)
int errnum;
return sys_errlist[errnum];
return (char *) "Unknown error";
}
-
+#endif /* not WINDOWSNT */
#endif /* ! HAVE_STRERROR */
\f
#ifdef INTERRUPTIBLE_OPEN
#ifdef INTERRUPTIBLE_CLOSE
+int
sys_close (fd)
int fd;
{
+ int did_retry = 0;
register int rtnval;
while ((rtnval = close (fd)) == -1
- && (errno == EINTR));
+ && (errno == EINTR))
+ did_retry = 1;
+
+ /* If close is interrupted SunOS 4.1 may or may not have closed the
+ file descriptor. If it did the second close will fail with
+ errno = EBADF. That means we have succeeded. */
+ if (rtnval == -1 && did_retry && errno == EBADF)
+ return 0;
+
return rtnval;
}
#endif /* INTERRUPTIBLE_IO */
\f
#ifndef HAVE_VFORK
-
+#ifndef WINDOWSNT
/*
- * Substitute fork for vfork on USG flavors.
+ * Substitute fork for vfork on USG flavors.
*/
+VFORK_RETURN_TYPE
vfork ()
{
return (fork ());
}
-
+#endif /* not WINDOWSNT */
#endif /* not HAVE_VFORK */
\f
#ifdef USG
"LAN I/O interrupt", /* 25 SIGAIO */
"PTY I/O interrupt", /* 26 SIGPTY */
"I/O intervention required", /* 27 SIGIOINT */
+#ifdef AIXHFT
"HFT grant", /* 28 SIGGRANT */
"HFT retract", /* 29 SIGRETRACT */
"HFT sound done", /* 30 SIGSOUND */
"HFT input ready", /* 31 SIGMSG */
+#endif
#else /* not AIX */
"bogus signal", /* 0 */
"hangup", /* 1 SIGHUP */
#ifdef sun
"window size change", /* 20 SIGWINCH */
"urgent socket condition", /* 21 SIGURG */
- "pollable event occured", /* 22 SIGPOLL */
+ "pollable event occurred", /* 22 SIGPOLL */
"stop (cannot be caught or ignored)", /* 23 SIGSTOP */
"user stop requested from tty", /* 24 SIGTSTP */
"stopped process has been continued", /* 25 SIGCONT */
#endif
-#ifdef MISSING_UTIMES
-
-/* HPUX (among others) sets HAVE_TIMEVAL but does not implement utimes. */
-
-utimes ()
-{
-}
-#endif
-
-#ifdef IRIS_UTIME
-
-/* The IRIS (3.5) has timevals, but uses sys V utime, and doesn't have the
- utimbuf structure defined anywhere but in the man page. */
-
-struct utimbuf
- {
- long actime;
- long modtime;
- };
-
-utimes (name, tvp)
- char *name;
- struct timeval tvp[];
-{
- struct utimbuf utb;
- utb.actime = tvp[0].tv_sec;
- utb.modtime = tvp[1].tv_sec;
- utime (name, &utb);
-}
-#endif /* IRIS_UTIME */
-
#ifdef HPUX
#ifndef HAVE_PERROR
#ifdef HAVE_TIMEVAL
/* ARGSUSED */
+int
gettimeofday (tp, tzp)
struct timeval *tp;
struct timezone *tzp;
tp->tv_usec = 0;
if (tzp != 0)
tzp->tz_minuteswest = -1;
+ return 0;
}
#endif
* This function will go away as soon as all the stubs fixed. (fnf)
*/
+void
croak (badfunc)
char *badfunc;
{
#endif /* NONSYSTEM_DIR_LIBRARY */
+\f
+int
+set_file_times (filename, atime, mtime)
+ char *filename;
+ EMACS_TIME atime, mtime;
+{
+#ifdef HAVE_UTIMES
+ struct timeval tv[2];
+ tv[0] = atime;
+ tv[1] = mtime;
+ return utimes (filename, tv);
+#else /* not HAVE_UTIMES */
+ struct utimbuf utb;
+ utb.actime = EMACS_SECS (atime);
+ utb.modtime = EMACS_SECS (mtime);
+ return utime (filename, &utb);
+#endif /* not HAVE_UTIMES */
+}
\f
/* mkdir and rmdir functions, for systems which don't have them. */
dup2 (fd, 1);
dup2 (fd, 2);
}
- wait_for_termination (cpid);
- if (synch_process_death != 0 || synch_process_retcode != 0)
- return -1; /* /bin/rmdir failed */
+ execl ("/bin/rmdir", "rmdir", dpath, (char *) 0);
+ _exit (-1); /* Can't exec /bin/rmdir */
+
default: /* Parent process */
- while (cpid != wait (&status)); /* Wait for kid to finish */
+ wait_for_termination (cpid);
}
- if (WIFSIGNALED (status) || WEXITSTATUS (status) != 0)
+ if (synch_process_death != 0 || synch_process_retcode != 0)
{
errno = EIO; /* We don't know why, but */
- return -1; /* /bin/mkdir failed */
+ return -1; /* /bin/rmdir failed */
}
return 0;
#else /* not VMS4_4 */
#include <prvdef.h>
-#define ACE$M_WRITE 2
-#define ACE$C_KEYID 1
+#define ACE$M_WRITE 2
+#define ACE$C_KEYID 1
static unsigned short memid, grpid;
static unsigned int uic;
/* Called from init_sys_modes, so it happens not very often
but at least each time Emacs is loaded. */
+void
sys_access_reinit ()
{
uic = 0;
grpid = uic >> 16;
}
- if (type != 2) /* not checking write access */
+ if (type != 2) /* not checking write access */
return access (filename, type);
/* Check write protection. */
-#define CHECKPRIV(bit) (prvmask.bit)
-#define WRITEABLE(field) (! ((xab.xab$w_pro >> field) & XAB$M_NOWRITE))
+#define CHECKPRIV(bit) (prvmask.bit)
+#define WRITABLE(field) (! ((xab.xab$w_pro >> field) & XAB$M_NOWRITE))
/* Find privilege bits */
status = SYS$SETPRV (0, 0, 0, prvmask);
return -1;
SYS$CLOSE (&fab, 0, 0);
/* Check system access */
- if (CHECKPRIV (PRV$V_SYSPRV) && WRITEABLE (XAB$V_SYS))
+ if (CHECKPRIV (PRV$V_SYSPRV) && WRITABLE (XAB$V_SYS))
return 0;
/* Check ACL entries, if any */
acl_controlled = 0;
return -1;
}
/* No ACL entries specified, check normal protection */
- if (WRITEABLE (XAB$V_WLD)) /* World writeable */
+ if (WRITABLE (XAB$V_WLD)) /* World writable */
return 0;
- if (WRITEABLE (XAB$V_GRP) &&
+ if (WRITABLE (XAB$V_GRP) &&
(unsigned short) (xab.xab$l_uic >> 16) == grpid)
- return 0; /* Group writeable */
- if (WRITEABLE (XAB$V_OWN) &&
+ return 0; /* Group writable */
+ if (WRITABLE (XAB$V_OWN) &&
(xab.xab$l_uic & 0xFFFF) == memid)
- return 0; /* Owner writeable */
+ return 0; /* Owner writable */
- return -1; /* Not writeable */
+ return -1; /* Not writable */
}
#endif /* not VMS4_4 */
#endif /* access */
return pathname;
}
+int
getppid ()
{
long item_code = JPI$_OWNER;
#endif
#endif
+int
sys_creat (va_alist)
va_dcl
{
#endif /* creat */
/* fwrite to stdout is S L O W. Speed it up by using fputc...*/
+int
sys_fwrite (ptr, size, num, fp)
register char * ptr;
FILE * fp;
while (tot--)
fputc (*ptr++, fp);
+ return num;
}
/*
retpw.pw_uid = up->uaf$w_mem;
retpw.pw_gid = up->uaf$w_grp;
- /* I suppose this is not the best sytle, to possibly overwrite one
+ /* I suppose this is not the best style, to possibly overwrite one
byte beyond the end of the field, but what the heck... */
ptr = &up->uaf$t_username[UAF$S_USERNAME];
while (ptr[-1] == ' ')
/* return total address space available to the current process. This is
the sum of the current p0 size, p1 size and free page table entries
available. */
+int
vlimit ()
{
int item_code;
return free_pages + frep0va + (0x7fffffff - frep1va);
}
+int
define_logical_name (varname, string)
char *varname;
char *string;
return LIB$SET_LOGICAL (&envdsc, &strdsc, &lnmdsc, 0, 0);
}
+int
delete_logical_name (varname)
char *varname;
{
return LIB$DELETE_LOGICAL (&envdsc, &lnmdsc);
}
+int
ulimit ()
-{}
+{
+ return 0;
+}
+int
setpgrp ()
-{}
+{
+ return 0;
+}
+int
execvp ()
{
error ("execvp system call not implemented");
+ return -1;
}
int
return 0;
}
+int
link (file, new)
char * file, * new;
{
return 0;
}
+void
croak (badfunc)
char *badfunc;
{
return rand () - (1 << 30);
}
+void
srandom (seed)
{
srand (seed);
}
#endif /* VMS */
\f
-#ifdef AIX
+#ifdef AIXHFT
/* Called from init_sys_modes. */
+void
hft_init ()
{
int junk;
/* Reset the rubout key to backspace. */
+void
hft_reset ()
{
struct hfbuf buf;
hftctl (0, HFSKBD, &buf);
}
-#endif /* AIX */
+#endif /* AIXHFT */
+
+#ifdef USE_DL_STUBS
+
+/* These are included on Sunos 4.1 when we do not use shared libraries.
+ X11 libraries may refer to these functions but (we hope) do not
+ actually call them. */
+
+void *
+dlopen ()
+{
+ return 0;
+}
+
+void *
+dlsym ()
+{
+ return 0;
+}
+
+int
+dlclose ()
+{
+ return -1;
+}
+
+#endif /* USE_DL_STUBS */
+\f
+#ifndef BSTRING
+
+#ifndef bzero
+
+void
+bzero (b, length)
+ register char *b;
+ register int length;
+{
+#ifdef VMS
+ short zero = 0;
+ long max_str = 65535;
+
+ while (length > max_str) {
+ (void) LIB$MOVC5 (&zero, &zero, &zero, &max_str, b);
+ length -= max_str;
+ b += max_str;
+ }
+ max_str = length;
+ (void) LIB$MOVC5 (&zero, &zero, &zero, &max_str, b);
+#else
+ while (length-- > 0)
+ *b++ = 0;
+#endif /* not VMS */
+}
+
+#endif /* no bzero */
+#endif /* BSTRING */
+
+#if (!defined (BSTRING) && !defined (bcopy)) || defined (NEED_BCOPY)
+#undef bcopy
+
+/* Saying `void' requires a declaration, above, where bcopy is used
+ and that declaration causes pain for systems where bcopy is a macro. */
+bcopy (b1, b2, length)
+ register char *b1;
+ register char *b2;
+ register int length;
+{
+#ifdef VMS
+ long max_str = 65535;
+
+ while (length > max_str) {
+ (void) LIB$MOVC3 (&max_str, b1, b2);
+ length -= max_str;
+ b1 += max_str;
+ b2 += max_str;
+ }
+ max_str = length;
+ (void) LIB$MOVC3 (&length, b1, b2);
+#else
+ while (length-- > 0)
+ *b2++ = *b1++;
+#endif /* not VMS */
+}
+#endif /* (!defined (BSTRING) && !defined (bcopy)) || defined (NEED_BCOPY) */
+
+#ifndef BSTRING
+#ifndef bcmp
+int
+bcmp (b1, b2, length) /* This could be a macro! */
+ register char *b1;
+ register char *b2;
+ register int length;
+{
+#ifdef VMS
+ struct dsc$descriptor_s src1 = {length, DSC$K_DTYPE_T, DSC$K_CLASS_S, b1};
+ struct dsc$descriptor_s src2 = {length, DSC$K_DTYPE_T, DSC$K_CLASS_S, b2};
+
+ return STR$COMPARE (&src1, &src2);
+#else
+ while (length-- > 0)
+ if (*b1++ != *b2++)
+ return 1;
+
+ return 0;
+#endif /* not VMS */
+}
+#endif /* no bcmp */
+#endif /* not BSTRING */