Fix C-g handling with multiple ttys.
[bpt/emacs.git] / src / sysdep.c
index 1a3123d..5a2bb44 100644 (file)
@@ -1,5 +1,6 @@
 /* Interfaces to system-dependent kernel and library entries.
-   Copyright (C) 1985, 86,87,88,93,94,95, 1999 Free Software Foundation, Inc.
+   Copyright (C) 1985, 86,87,88,93,94,95,1999,2000,01,2003
+   Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -18,42 +19,62 @@ along with GNU Emacs; see the file COPYING.  If not, write to
 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 Boston, MA 02111-1307, USA.  */
 
-
+#ifdef HAVE_CONFIG_H
 #include <config.h>
+#endif
+
 #include <signal.h>
 #include <setjmp.h>
-
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
 #include "lisp.h"
+/* Including stdlib.h isn't necessarily enough to get srandom
+   declared, e.g. without __USE_XOPEN_EXTENDED with glibc 2.  */
+#ifdef HAVE_RANDOM
+#if 0 /* It turns out that defining _OSF_SOURCE in osf5-0.h gets
+        random prototyped as returning `int'.  It looks to me as
+        though the best way to DTRT is to prefer the rand48 functions
+        (per libc.info).  -- fx */
+extern long int random P_ ((void));
+#endif
+#if 0 /* Don't prototype srandom; it takes an unsigned argument on
+        some systems, and an unsigned long on others, like FreeBSD
+        4.1.  */
+extern void srandom P_ ((unsigned int));
+#endif
+#endif
+
+#include "sysselect.h"
+
 #include "blockinput.h"
 #undef NULL
 
-#ifdef macintosh
-#ifdef __MRC__
-__sigfun sys_signal (int signal, __sigfun signal_func);
-#elif __MWERKS__
-__signal_func_ptr sys_signal (int signal, __signal_func_ptr signal_func);
-#else
-You lose!!!
-#endif
+#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.  */
+#include <stdlib.h>
+
 #ifndef subprocesses
 /* Nonzero means delete a process right away if it exits (process.c).  */
 static int delete_exited_processes;
 #endif
-#ifndef HAVE_X_WINDOWS
-/* Search path for bitmap files (xfns.c).  */
-Lisp_Object Vx_bitmap_file_path;
-#endif
-#endif  /* macintosh */
-
-#define min(x,y) ((x) > (y) ? (y) : (x))
+#endif  /* MAC_OS8 */
 
 #ifdef WINDOWSNT
-#define read _read
-#define write _write
+#define read sys_read
+#define write sys_write
 #include <windows.h>
-extern int errno;
+#ifndef NULL
+#define NULL 0
+#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
@@ -61,18 +82,16 @@ extern int errno;
 #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>
+#ifdef HAVE_SETPGID
+#if !defined (USG) || defined (BSD_PGRPS)
+#undef setpgrp
+#define setpgrp setpgid
+#endif
 #endif
 
 /* Get SI_SRPC_DOMAIN, if it is available.  */
@@ -92,9 +111,11 @@ extern unsigned start __asm__ ("start");
 #endif
 #endif
 
+#ifndef USE_CRT_DLL
 #ifndef errno
 extern int errno;
 #endif
+#endif
 
 #ifdef VMS
 #include <rms.h>
@@ -119,17 +140,13 @@ extern int errno;
 #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>
@@ -145,7 +162,6 @@ extern int errno;
 
 #if defined (USG) || defined (DGUX)
 #include <sys/utsname.h>
-#include <string.h>
 #ifndef MEMORY_IN_STRING_H
 #include <memory.h>
 #endif
@@ -162,6 +178,7 @@ extern int errno;
 
 extern int quit_char;
 
+#include "keyboard.h"
 #include "frame.h"
 #include "window.h"
 #include "termhooks.h"
@@ -169,6 +186,7 @@ extern int quit_char;
 #include "termopts.h"
 #include "dispextern.h"
 #include "process.h"
+#include "cm.h"  /* for reset_sys_modes */
 
 #ifdef WINDOWSNT
 #include <direct.h>
@@ -199,10 +217,6 @@ struct utimbuf {
 #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
 #define LPASS8 0
@@ -222,42 +236,32 @@ static int baud_convert[] =
   };
 #endif
 
+#ifdef HAVE_SPEED_T
+#include <termios.h>
+#else
 #if defined (HAVE_LIBNCURSES) && ! defined (NCURSES_OSPEED_T)
-extern short ospeed;
 #else
-#if defined (HAVE_TERMIOS_H) && defined (LINUX)
+#if defined (HAVE_TERMIOS_H) && defined (GNU_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
 #endif
 
-/* 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;
+int emacs_ospeed;
 
 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
 
-\f
-/* Specify a different file descriptor for further input operations.  */
+/* Temporary used by `sigblock' when defined in terms of signprocmask.  */
 
-void
-change_input_fd (fd)
-     int fd;
-{
-  input_fd = fd;
-}
+SIGMASKTYPE sigprocmask_set;
 
-/* Discard pending input on descriptor input_fd.  */
+\f
+/* Discard pending input on all input descriptors.  */
 
 void
 discard_tty_input ()
@@ -268,50 +272,57 @@ 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 */
@@ -320,35 +331,35 @@ stuff_char (c)
 #endif /* SIGTSTP */
 \f
 void
-init_baud_rate ()
+init_baud_rate (int fd)
 {
   if (noninteractive)
-    ospeed = 0;
+    emacs_ospeed = 0;
   else
     {
 #ifdef INIT_BAUD_RATE
       INIT_BAUD_RATE ();
 #else
 #ifdef DOS_NT
-    ospeed = 15;
+    emacs_ospeed = 15;
 #else  /* not DOS_NT */
 #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 );
-      ospeed = sg.xmit_baud;
+      emacs_ospeed = sg.xmit_baud;
 #else /* not VMS */
 #ifdef HAVE_TERMIOS
       struct termios sg;
 
       sg.c_cflag = B9600;
-      tcgetattr (input_fd, &sg);
-      ospeed = cfgetospeed (&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. */
-      if (ospeed == 0)
-        ospeed = getobaud (sg.c_cflag);
+      if (emacs_ospeed == 0)
+        emacs_ospeed = getobaud (sg.c_cflag);
 #endif
 #else /* neither VMS nor TERMIOS */
 #ifdef HAVE_TERMIO
@@ -356,31 +367,32 @@ init_baud_rate ()
 
       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
-      ospeed = sg.c_cflag & CBAUD;
+      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 ();
-      ospeed = sg.sg_ospeed;
+      emacs_ospeed = sg.sg_ospeed;
 #endif /* not HAVE_TERMIO */
 #endif /* not HAVE_TERMIOS */
 #endif /* not VMS */
 #endif /* not DOS_NT */
 #endif /* not INIT_BAUD_RATE */
     }
-   
-  baud_rate = (ospeed < sizeof baud_convert / sizeof baud_convert[0]
-              ? baud_convert[ospeed] : 9600);
+
+  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)
@@ -454,14 +466,16 @@ wait_for_termination (pid)
        break;
       wait (0);
 #else /* neither BSD_SYSTEM nor UNIPLUS: random sysV */
-#ifdef POSIX_SIGNALS    /* would this work for LINUX as well? */
+#ifdef POSIX_SIGNALS    /* would this work for GNU/Linux as well? */
       sigblock (sigmask (SIGCHLD));
-      if (0 > kill (pid, 0))
+      errno = 0;
+      if (kill (pid, 0) == -1 && errno == ESRCH)
        {
          sigunblock (sigmask (SIGCHLD));
          break;
        }
-      sigpause (SIGEMPTYMASK);
+
+      sigsuspend (&empty_mask);
 #else /* not POSIX_SIGNALS */
 #ifdef HAVE_SYSV_SIGPAUSE
       sighold (SIGCHLD);
@@ -513,7 +527,7 @@ wait_for_termination (pid)
  *     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;
@@ -560,6 +574,13 @@ child_setup_tty (out)
 #endif
   s.main.c_lflag &= ~ECHO;     /* Disable echo */
   s.main.c_lflag |= ISIG;      /* Enable signals */
+#if 0  /* This causes bugs in (for instance) telnet to certain sites.  */
+  s.main.c_iflag &= ~ICRNL;    /* Disable map of CR to NL on input */
+#ifdef INLCR  /* Just being cautious, since I can't check how
+                widespread INLCR is--rms.  */
+  s.main.c_iflag &= ~INLCR;    /* Disable map of NL to CR on input */
+#endif
+#endif
 #ifdef IUCLC
   s.main.c_iflag &= ~IUCLC;    /* Disable downcasing on input.  */
 #endif
@@ -630,7 +651,7 @@ child_setup_tty (out)
 
 #ifdef BSD4_1
   if (interrupt_input)
-    reset_sigio ();
+    reset_sigio (0);
 #endif /* BSD4_1 */
 #ifdef RTU
   {
@@ -726,12 +747,10 @@ sys_suspend ()
 
 /* Fork a subshell.  */
 
+#ifndef MAC_OS8
 void
 sys_subshell ()
 {
-#ifdef macintosh
-    error ("Can't spawn subshell");
-#else
 #ifndef VMS
 #ifdef DOS_NT  /* Demacs 1.1.2 91/10/20 Manabu Higashida */
   int st;
@@ -764,9 +783,9 @@ 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:
@@ -777,7 +796,7 @@ sys_subshell ()
   save_signal_handlers (saved_handlers);
   synch_process_alive = 1;
 #endif /* __DJGPP__ > 1 */
-#else  
+#else
   pid = vfork ();
   if (pid == -1)
     error ("Can't spawn subshell");
@@ -807,7 +826,7 @@ sys_subshell ()
 
 #ifdef SET_EMACS_PRIORITY
       {
-       extern int emacs_priority;
+       extern EMACS_INT emacs_priority;
 
        if (emacs_priority < 0)
          nice (-emacs_priority);
@@ -815,8 +834,23 @@ sys_subshell ()
 #endif
 
 #ifdef MSDOS    /* Demacs 1.1.2 91/10/20 Manabu Higashida */
-      st = system (sh);
-      chdir (oldwd);
+      {
+       char *epwd = getenv ("PWD");
+       char old_pwd[MAXPATHLEN+1+4];
+
+       /* If PWD is set, pass it with corrected value.  */
+       if (epwd)
+         {
+           strcpy (old_pwd, epwd);
+           if (str[len - 1] == '/')
+             str[len - 1] = '\0';
+           setenv ("PWD", str, 1);
+         }
+       st = system (sh);
+       chdir (oldwd);
+       if (epwd)
+         putenv (old_pwd);     /* restore previous value */
+      }
 #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));
@@ -848,8 +882,8 @@ sys_subshell ()
   restore_signal_handlers (saved_handlers);
   synch_process_alive = 0;
 #endif /* !VMS */
-#endif /* !macintosh */
 }
+#endif /* !MAC_OS8 */
 
 static void
 save_signal_handlers (saved_handlers)
@@ -874,53 +908,88 @@ restore_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;
 }
 
@@ -935,7 +1004,8 @@ request_sigio ()
   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;
 }
 
@@ -947,12 +1017,13 @@ unrequest_sigio ()
   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>
@@ -968,7 +1039,7 @@ request_sigio ()
 
   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);
 }
@@ -981,11 +1052,12 @@ unrequest_sigio ()
   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 ()
@@ -995,7 +1067,7 @@ request_sigio ()
 
   croak ("request_sigio");
 }
+
 void
 unrequest_sigio ()
 {
@@ -1004,11 +1076,13 @@ 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.  */
 
@@ -1039,23 +1113,25 @@ int inherited_pgroup;
    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 */
@@ -1206,20 +1282,12 @@ emacs_set_tty (fd, settings, flushp)
       || 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
@@ -1229,7 +1297,7 @@ int lmode;
 
 #ifndef F_SETOWN_BUG
 #ifdef F_SETOWN
-int old_fcntl_owner;
+int old_fcntl_owner[MAXDESC];
 #endif /* F_SETOWN */
 #endif /* F_SETOWN_BUG */
 
@@ -1246,38 +1314,37 @@ unsigned char _sobuf[BUFSIZ+8];
 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_sys_modes ()
+init_all_sys_modes (void)
 {
-  struct emacs_tty tty;
+  struct tty_display_info *tty;
+  for (tty = tty_list; tty; tty = tty->next)
+    init_sys_modes (tty);
+}
 
-#ifdef macintosh
-  Vwindow_system = intern ("mac");
-  Vwindow_system_version = make_number (1);
+void
+init_sys_modes (tty_out)
+     struct tty_display_info *tty_out;
+{
+  struct emacs_tty tty;
 
-/* cus-start.el complains if delete-exited-processes and x-bitmap-file-path not defined */
+#ifdef MAC_OS8
+/* cus-start.el complains if delete-exited-processes is not defined */
 #ifndef subprocesses
   DEFVAR_BOOL ("delete-exited-processes", &delete_exited_processes,
-    "*Non-nil means delete processes immediately when they exit.\n\
-nil means don't delete them until `list-processes' is run.");
+              doc: /* *Non-nil means delete processes immediately when they exit.
+nil means don't delete them until `list-processes' is run.  */);
   delete_exited_processes = 0;
 #endif
-
-#ifndef HAVE_X_WINDOWS
-  DEFVAR_LISP ("x-bitmap-file-path", &Vx_bitmap_file_path,
-    "List of directories to search for bitmap files for X.");
-  Vx_bitmap_file_path = decode_env_path ((char *) 0, ".");
-#endif
-
-#endif /* not macintosh */
+#endif /* MAC_OS8 */
 
 #ifdef VMS
 #if 0
@@ -1321,27 +1388,32 @@ nil means don't delete them until `list-processes' is run.");
 #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.  */
@@ -1362,7 +1434,7 @@ nil means don't delete them until `list-processes' is run.");
       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
@@ -1371,21 +1443,44 @@ nil means don't delete them until `list-processes' is run.");
        }
       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
@@ -1416,7 +1511,7 @@ nil means don't delete them until `list-processes' is run.");
       tty.main.c_cc[VDISCARD] = CDISABLE;
 #endif /* VDISCARD */
 
-      if (flow_control)
+      if (tty_out->flow_control)
        {
 #ifdef VSTART
          tty.main.c_cc[VSTART] = '\021';
@@ -1452,7 +1547,7 @@ nil means don't delete them until `list-processes' is run.");
       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';
@@ -1473,7 +1568,7 @@ nil means don't delete them until `list-processes' is run.");
       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;
@@ -1500,19 +1595,19 @@ nil means don't delete them until `list-processes' is run.");
         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
@@ -1524,33 +1619,33 @@ nil means don't delete them until `list-processes' is run.");
       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
@@ -1565,7 +1660,7 @@ nil means don't delete them until `list-processes' is run.");
 
 #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);
@@ -1576,11 +1671,12 @@ nil means don't delete them until `list-processes' is run.");
 #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 */
@@ -1588,7 +1684,7 @@ nil means don't delete them until `list-processes' is run.");
 
 #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.  */
@@ -1598,10 +1694,12 @@ nil means don't delete them until `list-processes' is run.");
   /* 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.  */
@@ -1613,38 +1711,51 @@ nil means don't delete them until `list-processes' is run.");
 #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.
@@ -1652,8 +1763,7 @@ tabs_safe_p ()
    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
@@ -1661,7 +1771,7 @@ get_frame_size (widthp, heightp)
   /* BSD-style.  */
   struct winsize size;
 
-  if (ioctl (input_fd, TIOCGWINSZ, &size) == -1)
+  if (ioctl (fd, TIOCGWINSZ, &size) == -1)
     *widthp = *heightp = 0;
   else
     {
@@ -1673,9 +1783,9 @@ get_frame_size (widthp, heightp)
 #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
     {
@@ -1687,8 +1797,8 @@ get_frame_size (widthp, heightp)
 #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;
@@ -1701,7 +1811,6 @@ get_frame_size (widthp, heightp)
   *widthp = 0;
   *heightp = 0;
 #endif
-
 #endif /* not VMS */
 #endif /* not SunOS-style */
 #endif /* not BSD-style */
@@ -1730,7 +1839,7 @@ set_window_size (fd, height, width)
 #ifdef TIOCSSIZE
 
   /* SunOS - style.  */
-  struct ttysize size;  
+  struct ttysize size;
   size.ts_lines = height;
   size.ts_cols = width;
 
@@ -1745,40 +1854,53 @@ set_window_size (fd, height, 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;
 
@@ -1787,12 +1909,12 @@ reset_sys_modes ()
   }
 #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
 
@@ -1801,22 +1923,25 @@ reset_sys_modes ()
 #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 */
@@ -1827,7 +1952,7 @@ reset_sys_modes ()
   /* 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
@@ -1835,7 +1960,7 @@ reset_sys_modes ()
 #endif
 
 #ifdef BSD_PGRPS
-  widen_foreground_group ();
+  widen_foreground_group (fileno (TTY_INPUT (tty_out)));
 #endif
 }
 \f
@@ -1861,17 +1986,17 @@ setup_pty (fd)
      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
-#ifdef SYSV_PTYS
+#if defined(SYSV_PTYS) || defined(UNIX98_PTYS)
   {
     int on = 1;
     ioctl (fd, FIONBIO, &on);
@@ -1899,10 +2024,10 @@ void
 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);
     }
@@ -1913,7 +2038,7 @@ init_vms_input ()
 void
 stop_vms_input ()
 {
-  return SYS$DASSGN (input_fd);
+  return SYS$DASSGN (fileno (TTY_INPUT (CURTTY())));
 }
 
 short input_buffer;
@@ -1929,7 +2054,7 @@ queue_kbd_input ()
 
   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);
 }
@@ -1975,7 +2100,9 @@ kbd_input_ast ()
   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);
@@ -2006,7 +2133,7 @@ wait_for_kbd_input ()
       /* No timing error: wait for flag to be set.  */
       set_waiting_for_input (0);
       SYS$WFLOR (input_ef, input_eflist);
-      clear_waiting_for_input (0);
+      clear_waiting_for_input ();
       if (!detect_input_pending ())
        /* Check for subprocess input availability */
        {
@@ -2021,7 +2148,7 @@ wait_for_kbd_input ()
            {
              update_mode_lines++;
              prepare_menu_bars ();
-             redisplay_preserve_echo_area ();
+             redisplay_preserve_echo_area (18);
            }
        }
     }
@@ -2044,7 +2171,7 @@ end_kbd_input ()
 #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;
     }
 
@@ -2053,7 +2180,7 @@ end_kbd_input ()
   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;
@@ -2100,7 +2227,7 @@ sys_sleep (timeval)
   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);
@@ -2115,7 +2242,8 @@ init_sigio (fd)
   request_sigio ();
 }
 
-reset_sigio ()
+reset_sigio (fd)
+     int fd;
 {
   unrequest_sigio ();
 }
@@ -2155,6 +2283,7 @@ unrequest_sigio ()
  *
  */
 
+#if !(defined (__NetBSD__) && defined (__ELF__))
 #ifndef HAVE_TEXT_START
 char *
 start_of_text ()
@@ -2172,6 +2301,7 @@ start_of_text ()
 #endif /* TEXT_START */
 }
 #endif /* not HAVE_TEXT_START */
+#endif
 
 /*
  *     Return the address of the start of the data segment prior to
@@ -2198,7 +2328,8 @@ start_of_text ()
  *     will be patched by unexec to the correct value.
  *
  */
+
+#ifndef start_of_data
 char *
 start_of_data ()
 {
@@ -2221,44 +2352,8 @@ 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. */
@@ -2278,6 +2373,12 @@ extern Lisp_Object Vsystem_name;
 #endif /* not VMS */
 #endif /* not BSD4_1 */
 
+#ifdef TRY_AGAIN
+#ifndef HAVE_H_ERRNO
+extern int h_errno;
+#endif
+#endif /* TRY_AGAIN */
+
 void
 init_system_name ()
 {
@@ -2345,7 +2446,9 @@ init_system_name ()
        if (hp)
          {
            char *fqdn = (char *) hp->h_name;
+#if 0
            char *p;
+#endif
 
            if (!index (fqdn, '.'))
              {
@@ -2419,7 +2522,7 @@ init_system_name ()
 #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 = '-';
   }
@@ -2475,7 +2578,7 @@ sys_select (nfds, rfds, wfds, efds, timeout)
      SELECT_TYPE *rfds, *wfds, *efds;
      EMACS_TIME *timeout;
 {
-  int ravail = 0, old_alarm;
+  int ravail = 0;
   SELECT_TYPE orfds;
   int timeoutval;
   int *local_timeout;
@@ -2485,7 +2588,6 @@ sys_select (nfds, rfds, wfds, efds, timeout)
 #else
   extern int process_tick, update_tick;
 #endif
-  SIGTYPE (*old_trap) ();
   unsigned char buf;
 
 #if defined (HAVE_SELECT) && defined (HAVE_X_WINDOWS)
@@ -2526,7 +2628,7 @@ sys_select (nfds, rfds, wfds, efds, timeout)
   /* 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;
@@ -2568,10 +2670,12 @@ sys_select (nfds, rfds, wfds, efds, timeout)
        }
       if (*local_timeout == 0 || ravail != 0 || process_tick != update_tick)
        break;
-      old_alarm = alarm (0);
-      old_trap = signal (SIGALRM, select_alarm);
+
+      turn_on_atimers (0);
+      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)
@@ -2589,24 +2693,16 @@ sys_select (nfds, rfds, wfds, efds, timeout)
            pause ();
        }
       (*local_timeout) -= SELECT_PAUSE;
-      /* Reset the old alarm if there was one */
-      alarm (0);
-      signal (SIGALRM, old_trap);
-      if (old_alarm != 0)
-       {
-         /* Reset or forge an interrupt for the original handler. */
-         old_alarm -= SELECT_PAUSE;
-         if (old_alarm <= 0)
-           kill (getpid (), SIGALRM); /* Fake an alarm with the orig' handler */
-         else
-           alarm (old_alarm);
-       }
+
+      /* 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.  */
@@ -2621,14 +2717,17 @@ sys_select (nfds, rfds, wfds, efds, timeout)
 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);
@@ -2641,18 +2740,20 @@ read_input_waiting ()
          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++)
@@ -2678,6 +2779,10 @@ read_input_waiting ()
     }
 }
 
+#if !defined (HAVE_SELECT) || defined (BROKEN_SELECT_NON_X)
+#define select sys_select
+#endif
+
 #endif /* not HAVE_SELECT */
 #endif /* not VMS */
 #endif /* not MSDOS */
@@ -2694,12 +2799,13 @@ init_sigio (fd)
 }
 
 void
-reset_sigio ()
+reset_sigio (fd)
+     int fd;
 {
   if (noninteractive)
     return;
   lmode = ~LINTRUP & lmode;
-  ioctl (0, TIOCLSET, &lmode);
+  ioctl (fd, TIOCLSET, &lmode);
 }
 
 void
@@ -2771,23 +2877,18 @@ sigbit (i)
 
 sigset_t empty_mask, full_mask;
 
-void
-init_signals ()
-{
-  sigemptyset (&empty_mask);
-  sigfillset (&full_mask);
-}
-
 signal_handler_t
 sys_signal (int signal_number, signal_handler_t action)
 {
   struct sigaction new_action, old_action;
   sigemptyset (&new_action.sa_mask);
   new_action.sa_handler = action;
-#ifdef SA_RESTART
+#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;
@@ -2840,19 +2941,198 @@ sys_sigsetmask (sigset_t new_mask)
 
 #endif /* POSIX_SIGNALS */
 \f
-#ifndef HAVE_RANDOM
-#ifdef random
-#define HAVE_RANDOM
-#endif
+#if !defined HAVE_STRSIGNAL && !HAVE_DECL_SYS_SIGLIST
+static char *my_sys_siglist[NSIG];
+# ifdef sys_siglist
+#  undef sys_siglist
+# endif
+# define sys_siglist my_sys_siglist
 #endif
 
-/* 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'.  */
+void
+init_signals ()
+{
+#ifdef POSIX_SIGNALS
+  sigemptyset (&empty_mask);
+  sigfillset (&full_mask);
+#endif
 
-#ifndef RAND_BITS
-# ifdef HAVE_RANDOM
+#if !defined HAVE_STRSIGNAL && !HAVE_DECL_SYS_SIGLIST
+  if (! initialized)
+    {
+# ifdef SIGABRT
+      sys_siglist[SIGABRT] = "Aborted";
+# endif
+# ifdef SIGAIO
+      sys_siglist[SIGAIO] = "LAN I/O interrupt";
+# endif
+# ifdef SIGALRM
+      sys_siglist[SIGALRM] = "Alarm clock";
+# endif
+# ifdef SIGBUS
+      sys_siglist[SIGBUS] = "Bus error";
+# endif
+# ifdef SIGCLD
+      sys_siglist[SIGCLD] = "Child status changed";
+# endif
+# ifdef SIGCHLD
+      sys_siglist[SIGCHLD] = "Child status changed";
+# endif
+# ifdef SIGCONT
+      sys_siglist[SIGCONT] = "Continued";
+# endif
+# ifdef SIGDANGER
+      sys_siglist[SIGDANGER] = "Swap space dangerously low";
+# endif
+# ifdef SIGDGNOTIFY
+      sys_siglist[SIGDGNOTIFY] = "Notification message in queue";
+# endif
+# ifdef SIGEMT
+      sys_siglist[SIGEMT] = "Emulation trap";
+# endif
+# ifdef SIGFPE
+      sys_siglist[SIGFPE] = "Arithmetic exception";
+# endif
+# ifdef SIGFREEZE
+      sys_siglist[SIGFREEZE] = "SIGFREEZE";
+# endif
+# ifdef SIGGRANT
+      sys_siglist[SIGGRANT] = "Monitor mode granted";
+# endif
+# ifdef SIGHUP
+      sys_siglist[SIGHUP] = "Hangup";
+# endif
+# ifdef SIGILL
+      sys_siglist[SIGILL] = "Illegal instruction";
+# endif
+# ifdef SIGINT
+      sys_siglist[SIGINT] = "Interrupt";
+# endif
+# ifdef SIGIO
+      sys_siglist[SIGIO] = "I/O possible";
+# endif
+# ifdef SIGIOINT
+      sys_siglist[SIGIOINT] = "I/O intervention required";
+# endif
+# ifdef SIGIOT
+      sys_siglist[SIGIOT] = "IOT trap";
+# endif
+# ifdef SIGKILL
+      sys_siglist[SIGKILL] = "Killed";
+# endif
+# ifdef SIGLOST
+      sys_siglist[SIGLOST] = "Resource lost";
+# endif
+# ifdef SIGLWP
+      sys_siglist[SIGLWP] = "SIGLWP";
+# endif
+# ifdef SIGMSG
+      sys_siglist[SIGMSG] = "Monitor mode data available";
+# endif
+# ifdef SIGPHONE
+      sys_siglist[SIGWIND] = "SIGPHONE";
+# endif
+# ifdef SIGPIPE
+      sys_siglist[SIGPIPE] = "Broken pipe";
+# endif
+# ifdef SIGPOLL
+      sys_siglist[SIGPOLL] = "Pollable event occurred";
+# endif
+# ifdef SIGPROF
+      sys_siglist[SIGPROF] = "Profiling timer expired";
+# endif
+# ifdef SIGPTY
+      sys_siglist[SIGPTY] = "PTY I/O interrupt";
+# endif
+# ifdef SIGPWR
+      sys_siglist[SIGPWR] = "Power-fail restart";
+# endif
+# ifdef SIGQUIT
+      sys_siglist[SIGQUIT] = "Quit";
+# endif
+# ifdef SIGRETRACT
+      sys_siglist[SIGRETRACT] = "Need to relinguish monitor mode";
+# endif
+# ifdef SIGSAK
+      sys_siglist[SIGSAK] = "Secure attention";
+# endif
+# ifdef SIGSEGV
+      sys_siglist[SIGSEGV] = "Segmentation violation";
+# endif
+# ifdef SIGSOUND
+      sys_siglist[SIGSOUND] = "Sound completed";
+# endif
+# ifdef SIGSTOP
+      sys_siglist[SIGSTOP] = "Stopped (signal)";
+# endif
+# ifdef SIGSTP
+      sys_siglist[SIGSTP] = "Stopped (user)";
+# endif
+# ifdef SIGSYS
+      sys_siglist[SIGSYS] = "Bad argument to system call";
+# endif
+# ifdef SIGTERM
+      sys_siglist[SIGTERM] = "Terminated";
+# endif
+# ifdef SIGTHAW
+      sys_siglist[SIGTHAW] = "SIGTHAW";
+# endif
+# ifdef SIGTRAP
+      sys_siglist[SIGTRAP] = "Trace/breakpoint trap";
+# endif
+# ifdef SIGTSTP
+      sys_siglist[SIGTSTP] = "Stopped (user)";
+# endif
+# ifdef SIGTTIN
+      sys_siglist[SIGTTIN] = "Stopped (tty input)";
+# endif
+# ifdef SIGTTOU
+      sys_siglist[SIGTTOU] = "Stopped (tty output)";
+# endif
+# ifdef SIGURG
+      sys_siglist[SIGURG] = "Urgent I/O condition";
+# endif
+# ifdef SIGUSR1
+      sys_siglist[SIGUSR1] = "User defined signal 1";
+# endif
+# ifdef SIGUSR2
+      sys_siglist[SIGUSR2] = "User defined signal 2";
+# endif
+# ifdef SIGVTALRM
+      sys_siglist[SIGVTALRM] = "Virtual timer expired";
+# endif
+# ifdef SIGWAITING
+      sys_siglist[SIGWAITING] = "Process's LWPs are blocked";
+# endif
+# ifdef SIGWINCH
+      sys_siglist[SIGWINCH] = "Window size changed";
+# endif
+# ifdef SIGWIND
+      sys_siglist[SIGWIND] = "SIGWIND";
+# endif
+# ifdef SIGXCPU
+      sys_siglist[SIGXCPU] = "CPU time limit exceeded";
+# endif
+# ifdef SIGXFSZ
+      sys_siglist[SIGXFSZ] = "File size limit exceeded";
+# endif
+    }
+#endif /* !defined HAVE_STRSIGNAL && !defined HAVE_DECL_SYS_SIGLIST */
+}
+\f
+#ifndef HAVE_RANDOM
+#ifdef random
+#define HAVE_RANDOM
+#endif
+#endif
+
+/* 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
@@ -2973,7 +3253,7 @@ sys_getenv (name)
 #undef abort
 sys_abort ()
 {
-  reset_sys_modes ();
+  reset_all_sys_modes ();
   LIB$SIGNAL (SS$_DEBUG);
 }
 #endif /* abort */
@@ -3049,16 +3329,16 @@ strerror (errnum)
 \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);
@@ -3091,7 +3371,7 @@ emacs_read (fildes, buf, nbyte)
      unsigned int nbyte;
 {
   register int rtnval;
-  
+
   while ((rtnval = read (fildes, buf, nbyte)) == -1
         && (errno == EINTR));
   return (rtnval);
@@ -3100,7 +3380,7 @@ emacs_read (fildes, buf, nbyte)
 int
 emacs_write (fildes, buf, nbyte)
      int fildes;
-     char *buf;
+     const char *buf;
      unsigned int nbyte;
 {
   register int rtnval, bytes_written;
@@ -3126,20 +3406,6 @@ emacs_write (fildes, buf, nbyte)
   return (bytes_written);
 }
 \f
-#ifndef HAVE_VFORK
-#ifndef WINDOWSNT
-/*
- *      Substitute fork for vfork on USG flavors.
- */
-
-VFORK_RETURN_TYPE
-vfork ()
-{
-  return (fork ());
-}
-#endif /* not WINDOWSNT */
-#endif /* not HAVE_VFORK */
-\f
 #ifdef USG
 /*
  *     All of the following are for USG.
@@ -3156,95 +3422,6 @@ vfork ()
  *     always negligible.   Fred Fish, Unisoft Systems Inc.
  */
 
-#ifndef HAVE_STRSIGNAL
-#ifndef HAVE_SYS_SIGLIST
-char *sys_siglist[NSIG + 1] =
-{
-#ifdef AIX
-/* AIX has changed the signals a bit */
-  "bogus signal",                      /* 0 */
-  "hangup",                            /* 1  SIGHUP */
-  "interrupt",                         /* 2  SIGINT */
-  "quit",                              /* 3  SIGQUIT */
-  "illegal instruction",               /* 4  SIGILL */
-  "trace trap",                                /* 5  SIGTRAP */
-  "IOT instruction",                   /* 6  SIGIOT */
-  "crash likely",                      /* 7  SIGDANGER */
-  "floating point exception",          /* 8  SIGFPE */
-  "kill",                              /* 9  SIGKILL */
-  "bus error",                         /* 10 SIGBUS */
-  "segmentation violation",            /* 11 SIGSEGV */
-  "bad argument to system call",       /* 12 SIGSYS */
-  "write on a pipe with no one to read it", /* 13 SIGPIPE */
-  "alarm clock",                       /* 14 SIGALRM */
-  "software termination signum",       /* 15 SIGTERM */
-  "user defined signal 1",             /* 16 SIGUSR1 */
-  "user defined signal 2",             /* 17 SIGUSR2 */
-  "death of a child",                  /* 18 SIGCLD */
-  "power-fail restart",                        /* 19 SIGPWR */
-  "bogus signal",                      /* 20 */
-  "bogus signal",                      /* 21 */
-  "bogus signal",                      /* 22 */
-  "bogus signal",                      /* 23 */
-  "bogus signal",                      /* 24 */
-  "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 */
-  "interrupt",                         /* 2  SIGINT */
-  "quit",                              /* 3  SIGQUIT */
-  "illegal instruction",               /* 4  SIGILL */
-  "trace trap",                                /* 5  SIGTRAP */
-  "IOT instruction",                   /* 6  SIGIOT */
-  "EMT instruction",                   /* 7  SIGEMT */
-  "floating point exception",          /* 8  SIGFPE */
-  "kill",                              /* 9  SIGKILL */
-  "bus error",                         /* 10 SIGBUS */
-  "segmentation violation",            /* 11 SIGSEGV */
-  "bad argument to system call",       /* 12 SIGSYS */
-  "write on a pipe with no one to read it", /* 13 SIGPIPE */
-  "alarm clock",                       /* 14 SIGALRM */
-  "software termination signum",       /* 15 SIGTERM */
-  "user defined signal 1",             /* 16 SIGUSR1 */
-  "user defined signal 2",             /* 17 SIGUSR2 */
-  "death of a child",                  /* 18 SIGCLD */
-  "power-fail restart",                        /* 19 SIGPWR */
-#ifdef sun
-  "window size change",                            /* 20 SIGWINCH */
-  "urgent socket condition",               /* 21 SIGURG */
-  "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 */
-  "background tty read attempted",         /* 26 SIGTTIN */
-  "background tty write attempted",    /* 27 SIGTTOU */
-  "virtual timer expired",                 /* 28 SIGVTALRM */
-  "profiling timer expired",               /* 29 SIGPROF */
-  "exceeded cpu limit",                            /* 30 SIGXCPU */
-  "exceeded file size limit",              /* 31 SIGXFSZ */
-  "process's lwps are blocked",            /*  32 SIGWAITING */
-  "special signal used by thread library", /* 33 SIGLWP */
-#ifdef SIGFREEZE
-  "Special Signal Used By CPR",            /* 34 SIGFREEZE */
-#endif
-#ifdef SIGTHAW
-  "Special Signal Used By CPR",            /* 35 SIGTHAW */
-#endif
-#endif /* sun */
-#endif /* not AIX */
-  0
-  };
-#endif /* HAVE_SYS_SIGLIST */
-#endif /* HAVE_STRSIGNAL */
-
 /*
  *     Warning, this function may not duplicate 4.2 action properly
  *     under error conditions.
@@ -3267,7 +3444,10 @@ getwd (pathname)
   BLOCK_INPUT;                 /* getcwd uses malloc */
   spath = npath = getcwd ((char *) 0, MAXPATHLEN);
   if (spath == 0)
-    return spath;
+    {
+      UNBLOCK_INPUT;
+      return spath;
+    }
   /* On Altos 3068, getcwd can return @hostname/dir, so discard
      up to first slash.  Should be harmless on other systems.  */
   while (*npath && *npath != '/')
@@ -3331,7 +3511,7 @@ dup2 (oldd, newd)
      int newd;
 {
   register int fd, ret;
-  
+
   emacs_close (newd);
 
 #ifdef F_DUPFD
@@ -3360,7 +3540,7 @@ dup2 (oldd, newd)
 #ifndef VMS
 #ifndef HAVE_GETTIMEOFDAY
 #ifdef HAVE_TIMEVAL
+
 /* ARGSUSED */
 int
 gettimeofday (tp, tzp)
@@ -3369,18 +3549,18 @@ 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)
  */
@@ -3390,88 +3570,12 @@ croak (badfunc)
      char *badfunc;
 {
   printf ("%s not yet implemented\r\n", badfunc);
-  reset_sys_modes ();
+  reset_all_sys_modes ();
   exit (1);
 }
 
 #endif /* USG */
 \f
-#ifdef DGUX
-
-#ifndef HAVE_STRSIGNAL
-char *sys_siglist[NSIG + 1] =
-{
-  "null signal",                        /*  0 SIGNULL   */
-  "hangup",                             /*  1 SIGHUP    */
-  "interrupt",                          /*  2 SIGINT    */
-  "quit",                               /*  3 SIGQUIT   */
-  "illegal instruction",                /*  4 SIGILL    */
-  "trace trap",                                 /*  5 SIGTRAP   */
-  "abort termination",                  /*  6 SIGABRT   */
-  "SIGEMT",                             /*  7 SIGEMT    */
-  "floating point exception",           /*  8 SIGFPE    */
-  "kill",                               /*  9 SIGKILL   */
-  "bus error",                          /* 10 SIGBUS    */
-  "segmentation violation",             /* 11 SIGSEGV   */
-  "bad argument to system call",        /* 12 SIGSYS    */
-  "write on a pipe with no reader",     /* 13 SIGPIPE   */
-  "alarm clock",                        /* 14 SIGALRM   */
-  "software termination signal",        /* 15 SIGTERM   */
-  "user defined signal 1",              /* 16 SIGUSR1   */
-  "user defined signal 2",              /* 17 SIGUSR2   */
-  "child stopped or terminated",        /* 18 SIGCLD    */
-  "power-fail restart",                         /* 19 SIGPWR    */
-  "window size changed",                /* 20 SIGWINCH  */
-  "undefined",                          /* 21           */
-  "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   */
-  "attempted background tty read",      /* 26 SIGTTIN   */
-  "attempted background tty write",     /* 27 SIGTTOU   */
-  "undefined",                          /* 28           */
-  "undefined",                          /* 29           */
-  "undefined",                          /* 30           */
-  "undefined",                          /* 31           */
-  "undefined",                          /* 32           */
-  "socket (TCP/IP) urgent data arrival", /* 33 SIGURG    */
-  "I/O is possible",                    /* 34 SIGIO     */
-  "exceeded cpu time limit",            /* 35 SIGXCPU   */
-  "exceeded file size limit",           /* 36 SIGXFSZ   */
-  "virtual time alarm",                         /* 37 SIGVTALRM */
-  "profiling time alarm",               /* 38 SIGPROF   */
-  "undefined",                          /* 39           */
-  "file record locks revoked",          /* 40 SIGLOST   */
-  "undefined",                          /* 41           */
-  "undefined",                          /* 42           */
-  "undefined",                          /* 43           */
-  "undefined",                          /* 44           */
-  "undefined",                          /* 45           */
-  "undefined",                          /* 46           */
-  "undefined",                          /* 47           */
-  "undefined",                          /* 48           */
-  "undefined",                          /* 49           */
-  "undefined",                          /* 50           */
-  "undefined",                          /* 51           */
-  "undefined",                          /* 52           */
-  "undefined",                          /* 53           */
-  "undefined",                          /* 54           */
-  "undefined",                          /* 55           */
-  "undefined",                          /* 56           */
-  "undefined",                          /* 57           */
-  "undefined",                          /* 58           */
-  "undefined",                          /* 59           */
-  "undefined",                          /* 60           */
-  "undefined",                          /* 61           */
-  "undefined",                          /* 62           */
-  "undefined",                          /* 63           */
-  "notification message in mess. queue", /* 64 SIGDGNOTIFY */
-  0
-};
-#endif /* HAVE_STRSIGNAL */
-
-#endif /* DGUX */
-\f
 /* Directory routines for systems that don't have them. */
 
 #ifdef SYSV_SYSTEM_DIR
@@ -3518,7 +3622,7 @@ opendir (filename)
   BLOCK_INPUT;
   if (fstat (fd, &sbuf) < 0
       || (sbuf.st_mode & S_IFMT) != S_IFDIR
-      || (dirp = (DIR *) malloc (sizeof (DIR))) == 0)
+      || (dirp = (DIR *) xmalloc (sizeof (DIR))) == 0)
     {
       emacs_close (fd);
       UNBLOCK_INPUT;
@@ -3648,7 +3752,7 @@ readdirver (dirp)
 \f
 int
 set_file_times (filename, atime, mtime)
-     char *filename;
+     const char *filename;
      EMACS_TIME atime, mtime;
 {
 #ifdef HAVE_UTIMES
@@ -3823,7 +3927,7 @@ vmserrstr (status)
 
 #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.)
  */
@@ -3864,7 +3968,7 @@ sys_access (path, mode)
    * 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)
@@ -3878,7 +3982,7 @@ sys_access (path, mode)
     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))
@@ -3943,7 +4047,7 @@ sys_access (filename, type)
     return access (filename, type);
 
   /* Check write protection. */
-    
+
 #define CHECKPRIV(bit)    (prvmask.bit)
 #define WRITABLE(field)  (! ((xab.xab$w_pro >> field) & XAB$M_NOWRITE))
 
@@ -4005,7 +4109,7 @@ sys_access (filename, type)
 }
 #endif /* not VMS4_4 */
 #endif /* access */
-  
+
 static char vtbuf[NAM$C_MAXRSS+1];
 
 /* translate a vms file spec to a unix path */
@@ -4046,7 +4150,7 @@ sys_translate_vms (vfile)
            *targ++ = '.';
            *targ++ = '.';
            break;
-           
+
          default:
            *targ++ = *vfile;
            break;
@@ -4139,7 +4243,7 @@ sys_translate_unix (ufile)
       ufile++;
     }
   *targ = '\0';
-  
+
   return utbuf;
 }
 
@@ -4161,7 +4265,7 @@ getwd (pathname)
     }
   strcpy (pathname, ptr);
   xfree (ptr);
-  
+
  return pathname;
 }
 
@@ -4498,7 +4602,7 @@ sys_fwrite (ptr, size, num, fp)
  * 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
@@ -4555,7 +4659,7 @@ get_uaf_name (uname)
   register status;
   struct FAB uaf_fab;
   struct RAB uaf_rab;
-  
+
   uaf_fab = cc$rms_fab;
   uaf_rab = cc$rms_rab;
   /* initialize fab fields */
@@ -4619,7 +4723,7 @@ get_uaf_uic (uic)
   register status;
   struct FAB uaf_fab;
   struct RAB uaf_rab;
-  
+
   uaf_fab = cc$rms_fab;
   uaf_rab = cc$rms_rab;
   /* initialize fab fields */
@@ -4912,7 +5016,7 @@ rename (from, to)
    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];
 
@@ -5052,7 +5156,7 @@ croak (badfunc)
      char *badfunc;
 {
   printf ("%s not yet implemented\r\n", badfunc);
-  reset_sys_modes ();
+  reset_all_sys_modes ();
   exit (1);
 }
 
@@ -5074,13 +5178,13 @@ srandom (seed)
 
 /* 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;
@@ -5120,15 +5224,12 @@ hft_init ()
     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;
@@ -5293,1569 +5394,6 @@ strsignal (code)
   return signame;
 }
 #endif /* HAVE_STRSIGNAL */
-\f
-/* All the Macintosh stuffs go here */
-
-#ifdef macintosh
-
-#include <Files.h>
-#include <MacTypes.h>
-#include <TextUtils.h>
-#include <Folders.h>
-
-#include <dirent.h>
-#include <sys/stat.h>
-#include <string.h>
-#include <pwd.h>
-#include <sys/param.h>
-
-/* Convert a Mac pathname to Unix form.  A Mac full pathname is one
-   that does not begin with a ':' and contains at least one ':'. A Mac
-   full pathname causes an '/' to be prepended to the Unix pathname.
-   The algorithm for the rest of the pathname is as follows:
-     For each segment between two ':',
-       if it is non-null, copy as is and then add a '/' at the end,
-       otherwise, insert a "../" into the Unix pathname.
-   Returns 1 if successful; 0 if fails.  */
-   
-int
-Mac2UnixPathname (const char *mfn, char *ufn, int ufnbuflen)
-{
-  const char *p, *q, *pe;
-       
-  strcpy (ufn, "");
-       
-  if (*mfn == '\0')
-    return 1;
-       
-  p = strchr (mfn, ':');
-  if (p != 0 && p != mfn)  /* full pathname */
-    strcat (ufn, "/");
-               
-  p = mfn;
-  if (*p == ':')
-    p++;
-
-  pe = mfn + strlen (mfn);
-  while (p < pe)
-    {
-      q = strchr (p, ':');
-      if (q)
-       {
-         if (q == p)
-           {  /* two consecutive ':' */
-             if (strlen (ufn) + 3 >= ufnbuflen)
-               return 0;
-             strcat (ufn, "../");
-           }
-         else
-           {
-             if (strlen (ufn) + (q - p) + 1 >= ufnbuflen)
-               return 0;
-             strncat (ufn, p, q - p);
-             strcat (ufn, "/");
-           }
-         p = q + 1;
-       }
-      else
-       {
-         if (strlen (ufn) + (pe - p) >= ufnbuflen)
-           return 0;
-         strncat (ufn, p, pe - p);  /* no separator for last one */
-         p = pe;
-       }
-    }
-       
-  return 1;
-}
-
-extern char *GetTempDirName ();
-
-/* Convert a Unix pathname to Mac form.  Approximately reverse of the
-   above in algorithm.  */
-int
-Unix2MacPathname (const char *ufn, char *mfn, int mfnbuflen)
-{
-  const char *p, *q, *pe;
-  char expandedPathname[MAXPATHLEN+1];
-       
-  strcpy (mfn, "");
-       
-  if (*ufn == '\0')
-    return 1;
-
-  p = ufn;
-  
-  /* Check for and handle volume names.  Last comparison: strangely
-     somewhere `/.emacs' is passed.  A temporary fix for now.  */
-  if (*p == '/' && strchr (p+1, '/') == NULL && strcmp (p, "/.emacs") != 0)
-    {
-      if (strlen (p) + 1 > mfnbuflen)
-       return 0;
-      strcpy (mfn, p+1);
-      strcat (mfn, ":");
-      return 1;
-    }
-
-  if (strncmp (p, "~emacs/", 7) == 0)
-    {  /* expand to emacs dir found by InitEmacsPasswdDir */
-      struct passwd *pw = getpwnam ("emacs");
-      p += 7;
-      if (strlen (pw->pw_dir) + strlen (p) > MAXPATHLEN)
-       return 0;
-      strcpy (expandedPathname, pw->pw_dir);
-      strcat (expandedPathname, p);
-      p = expandedPathname;
-      /* Now p points to the pathname with emacs dir prefix.  */
-    }
-  else if (strncmp (p, "/tmp/", 5) == 0)
-    {
-      char *t = GetTempDirName ();
-      p += 5;
-      if (strlen (t) + strlen (p) > MAXPATHLEN)
-       return 0;
-      strcpy (expandedPathname, t);
-      strcat (expandedPathname, p);
-      p = expandedPathname;
-      /* Now p points to the pathname with emacs dir prefix.  */
-    }    
-  else if (*p != '/')  /* relative pathname */
-    strcat (mfn, ":");
-               
-  if (*p == '/')
-    p++;
-
-  pe = p + strlen (p);
-  while (p < pe)
-    {
-      q = strchr (p, '/');
-      if (q)
-       {
-         if (q - p == 2 && *p == '.' && *(p+1) == '.')
-           {
-             if (strlen (mfn) + 1 >= mfnbuflen)
-               return 0;
-             strcat (mfn, ":");
-           }
-         else
-           {
-             if (strlen (mfn) + (q - p) + 1 >= mfnbuflen)
-               return 0;
-             strncat (mfn, p, q - p);
-             strcat (mfn, ":");
-           }
-         p = q + 1;
-       }
-      else
-       {
-         if (strlen (mfn) + (pe - p) >= mfnbuflen)
-           return 0;
-         strncat (mfn, p, pe - p);
-         p = pe;
-       }
-    }
-       
-  return 1;
-}
-
-/* The following functions with "sys_" prefix are stubs to Unix
-   functions that have already been implemented by CW or MPW.  The
-   calls to them in Emacs source course are #define'd to call the sys_
-   versions by the header files s-mac.h.  In these stubs pathnames are
-   converted between their Unix and Mac forms.  */
-/* Unix Epoch is Jan 1, 1970 while Mac Epoch is Jan 1, 1904: 66 years
-   + 17 leap days */
-#define MAC_UNIX_EPOCH_DIFF  ((365L * 66 + 17) * 24 * 60 * 60)
-
-/* CW Epoch is Jan 1, 1900 (aaarghhhhh!); remember, 1900 is not a leap
-   year! */
-#define CW_UNIX_EPOCH_DIFF ((365L * 70 + 17) * 24 * 60 * 60)
-
-/* Define our own stat function for both MrC and CW.  The reason for
-   doing this: "stat" is both the name of a struct and function name:
-   we can't #define stat to something else to
-   redirect Emacs's calls to our own version that converts Unix style
-   filenames to Mac style filename because all sorts of compilation
-   errors will be generated if stat is #define'd to be something else.  */
-
-int
-stat (const char *path, struct stat *buf)
-{
-  char MacPathname[MAXPATHLEN+1];
-  CInfoPBRec cipb;
-       
-  if (Unix2MacPathname (path, MacPathname, MAXPATHLEN+1) == 0)
-    return -1;
-
-  c2pstr (MacPathname);
-  cipb.hFileInfo.ioNamePtr = MacPathname;
-  cipb.hFileInfo.ioVRefNum = 0;
-  cipb.hFileInfo.ioDirID = 0;
-  cipb.hFileInfo.ioFDirIndex = 0;  /* set to 0 to get information about specific dir or file */
-  
-  errno = PBGetCatInfo (&cipb, false);
-  if (errno == -43) /* -43: fnfErr defined in Errors.h */
-    errno = ENOENT;
-  if (errno != noErr)
-    return -1;
-
-  if (cipb.hFileInfo.ioFlAttrib & 0x10)
-    {  /* bit 4 = 1 for directories */
-      buf->st_mode = S_IFDIR | S_IREAD | S_IEXEC;
-      if (!(cipb.hFileInfo.ioFlAttrib & 0x1))  /* bit 1 = 1 for locked files/directories */
-       buf->st_mode |= S_IWRITE;
-      buf->st_ino = cipb.dirInfo.ioDrDirID;
-      buf->st_dev = cipb.dirInfo.ioVRefNum;
-      buf->st_size = cipb.dirInfo.ioDrNmFls;  /* size of dir = number of files and dirs */
-      buf->st_atime = buf->st_mtime = cipb.dirInfo.ioDrMdDat - MAC_UNIX_EPOCH_DIFF;
-      buf->st_ctime = cipb.dirInfo.ioDrCrDat - MAC_UNIX_EPOCH_DIFF;
-    }
-  else
-    {
-      buf->st_mode = S_IFREG | S_IREAD;
-      if (!(cipb.hFileInfo.ioFlAttrib & 0x1))  /* bit 1 = 1 for locked files/directories */
-       buf->st_mode |= S_IWRITE;
-      if (cipb.hFileInfo.ioFlFndrInfo.fdType == 'APPL')
-       buf->st_mode |= S_IEXEC;
-      buf->st_ino = cipb.hFileInfo.ioDirID;
-      buf->st_dev = cipb.hFileInfo.ioVRefNum;
-      buf->st_size = cipb.hFileInfo.ioFlLgLen;
-      buf->st_atime = buf->st_mtime = cipb.hFileInfo.ioFlMdDat - MAC_UNIX_EPOCH_DIFF;
-      buf->st_ctime = cipb.hFileInfo.ioFlCrDat - MAC_UNIX_EPOCH_DIFF;
-    }
-  buf->st_nlink = 1;
-  buf->st_uid = getuid ();
-  buf->st_gid = getgid ();
-  buf->st_rdev = 0;
-
-  return 0;
-}
-
-#if __MRC__
-
-/* CW defines fstat in stat.mac.c while MPW does not provide this
-   function.  Without the information of how to get from a file
-   descriptor in MPW StdCLib to a Mac OS file spec, it should be hard
-   to implement this function.  Fortunately, there is only one place
-   where this function is called in our configuration: in fileio.c,
-   where only the st_dev and st_ino fields are used to determine
-   whether two fildes point to different i-nodes to prevent copying
-   a file onto itself equal.  What we have here probably needs
-   improvement.  */
-int
-fstat (int fildes, struct stat *buf)
-{
-  buf->st_dev = 0;
-  buf->st_ino = fildes;
-  return 0;  /* success */
-}
-
-#endif  /* __MRC__ */
-
-/* From Think Reference code example */
-int
-mkdir (const char *dirname, int mode)
-{
-#pragma unused (mode)
-
-  HFileParam hfpb;
-  char MacPathname[MAXPATHLEN+1];
-       
-  if (Unix2MacPathname (dirname, MacPathname, MAXPATHLEN+1) == 0)
-    return -1;
-
-  c2pstr (MacPathname);
-  hfpb.ioNamePtr = MacPathname;
-  hfpb.ioVRefNum = 0; /*ignored unless name is invalid */
-  hfpb.ioDirID = 0;  /*parent is the root */
-  
-  /* Just return the Mac OSErr code for now.  */
-  errno = PBDirCreate ((HParmBlkPtr) &hfpb, false);
-  return errno == noErr ? 0 : -1;
-}
-
-int
-rmdir (const char *dirname)
-{
-  HFileParam hfpb;
-  char MacPathname[MAXPATHLEN+1];
-       
-  if (Unix2MacPathname (dirname, MacPathname, MAXPATHLEN+1) == 0)
-    return -1;
-
-  c2pstr (MacPathname);
-  hfpb.ioNamePtr = MacPathname;
-  hfpb.ioVRefNum = 0; /*ignored unless name is invalid */
-  hfpb.ioDirID = 0;  /*parent is the root */
-  
-  errno = PBHDelete ((HParmBlkPtr) &hfpb, false);
-  return errno == noErr ? 0 : -1;
-}
-
-#ifdef __MRC__
-
-/* No implementation yet. */
-int
-execvp (const char *path, ...)
-{
-  return -1;
-}
-
-#endif /* __MRC__ */
-
-int
-utime (const char *path, const struct utimbuf *times)
-{
-  char MacPathname[MAXPATHLEN+1];
-  CInfoPBRec cipb;
-       
-  if (Unix2MacPathname (path, MacPathname, MAXPATHLEN+1) == 0)
-    return -1;
-
-  c2pstr (MacPathname);
-  cipb.hFileInfo.ioNamePtr = MacPathname;
-  cipb.hFileInfo.ioVRefNum = 0;
-  cipb.hFileInfo.ioDirID = 0;
-  /* Set to 0 to get information about specific dir or file.  */
-  cipb.hFileInfo.ioFDirIndex = 0;
-  
-  errno = PBGetCatInfo (&cipb, false);
-  if (errno != noErr)
-    return -1;
-
-  if (cipb.hFileInfo.ioFlAttrib & 0x10)
-    {  /* bit 4 = 1 for directories */
-      if (times)
-       cipb.dirInfo.ioDrMdDat = times->modtime + MAC_UNIX_EPOCH_DIFF;
-      else
-       GetDateTime (&cipb.dirInfo.ioDrMdDat);
-    }
-  else
-    {
-      if (times)
-       cipb.hFileInfo.ioFlMdDat = times->modtime + MAC_UNIX_EPOCH_DIFF;
-      else
-       GetDateTime (&cipb.hFileInfo.ioFlMdDat);
-    }
-
-  errno = PBSetCatInfo (&cipb, false);
-  return errno == noErr ? 0 : -1;
-}
-
-#define F_OK 0
-#define X_OK 1
-#define W_OK 2
-
-/* Like stat, but test for access mode in hfpb.ioFlAttrib.  */
-int
-access (const char *path, int mode)
-{
-  char MacPathname[MAXPATHLEN+1];
-  CInfoPBRec cipb;
-       
-  if (Unix2MacPathname (path, MacPathname, MAXPATHLEN+1) == 0)
-    return -1;
-
-  c2pstr (MacPathname);
-  cipb.hFileInfo.ioNamePtr = MacPathname;
-  cipb.hFileInfo.ioVRefNum = 0;
-  cipb.hFileInfo.ioDirID = 0;
-  cipb.hFileInfo.ioFDirIndex = 0;  /* set to 0 to get information about specific dir or file */
-  
-  errno = PBGetCatInfo (&cipb, false);
-  if (errno != noErr)
-    return -1;
-
-  if (mode == F_OK)  /* got this far, file exists */
-    return 0;
-
-  if (mode & X_OK)
-    if (cipb.hFileInfo.ioFlAttrib & 0x10)  /* path refers to a directory */
-      return 0;
-    else
-      {
-       if (cipb.hFileInfo.ioFlFndrInfo.fdType == 'APPL')
-         return 0;
-       else
-         return -1;
-      }
-
-  if (mode & W_OK)
-    return (cipb.hFileInfo.ioFlAttrib & 0x1) ? -1 : 0;  /* don't allow if lock bit on */
-
-  return -1;
-}
-
-#define DEV_NULL_FD 0x10000
-
-#undef open
-int
-sys_open (const char *path, int oflag)
-{
-  char MacPathname[MAXPATHLEN+1];
-       
-  if (strcmp (path, "/dev/null") == 0)
-    return DEV_NULL_FD;  /* some bogus fd to be ignored in write */
-
-  if (Unix2MacPathname (path, MacPathname, MAXPATHLEN+1) == 0)
-    return -1;
-  else
-    return open (MacPathname, oflag);
-}
-
-#undef creat
-int
-sys_creat (const char *path, mode_t mode)
-{
-  char MacPathname[MAXPATHLEN+1];
-       
-  if (Unix2MacPathname (path, MacPathname, MAXPATHLEN+1) == 0)
-    return -1;
-  else
-    return creat (MacPathname, mode);
-}
-
-#undef unlink
-int
-sys_unlink (const char *path)
-{
-  char MacPathname[MAXPATHLEN+1];
-       
-  if (Unix2MacPathname (path, MacPathname, MAXPATHLEN+1) == 0)
-    return -1;
-  else
-    return unlink (MacPathname);
-}
-
-#undef read
-int
-sys_read (int fildes, char *buf, int count)
-{
-  if (fildes == 0)
-    {  /* if stdin, call (non-echoing) "getch" in console.h */
-      if (MacKeyPending ())
-       {  /* don't wait for a key if none has been pressed */
-         *buf = MacGetChar ();
-         return 1;
-       }
-      else
-       return 0;
-    }
-  else
-    return read (fildes, buf, count);
-}
-
-#undef write
-int
-sys_write (int fildes, char *buf, int count)
-{
-  if (fildes == DEV_NULL_FD)
-    return count;
-  else
-    return write (fildes, buf, count);
-}
-
-#undef rename
-int
-sys_rename (const char * old_name, const char * new_name)
-{
-  char MacOldName[MAXPATHLEN+1], MacNewName[MAXPATHLEN+1];
-       
-  if (strcmp (old_name, new_name) == 0)
-    return 0;
-
-  if (Unix2MacPathname (old_name, MacOldName, MAXPATHLEN+1) == 0)
-    return 1;
-               
-  if (Unix2MacPathname (new_name, MacNewName, MAXPATHLEN+1) == 0)
-    return 1;
-
-  return rename (MacOldName, MacNewName);
-}
-
-#undef fopen
-extern FILE *fopen (const char *name, const char *mode);
-FILE 
-sys_fopen (const char *name, const char *mode)
-{
-  char MacPathname[MAXPATHLEN+1];
-       
-  if (Unix2MacPathname (name, MacPathname, MAXPATHLEN+1) == 0)
-    return 0;
-  else
-    return fopen (MacPathname, mode);
-}
-
-#include <Events.h>
-
-long targetTicks = 0;
-
-#ifdef __MRC__
-__sigfun alarm_signal_func = (__sigfun) 0;
-#elif __MWERKS__
-__signal_func_ptr alarm_signal_func = (__signal_func_ptr) 0;
-#else
-You lose!!!
-#endif
-
-/* These functions simulate SIG_ALRM.  The stub for function signal
-   stores the signal handler function in alarm_signal_func if a
-   SIG_ALRM is encountered.  CheckAlarm is called in mac_read_socket,
-   which emacs calls periodically.  A pending alarm is represented by
-   a non-zero targetTicks value.  CheckAlarm calls the handler
-   function pointed to by alarm_signal_func if one has been set up and
-   an alarm is pending.  */
-void
-CheckAlarm ()
-{
-  if (targetTicks && TickCount () > targetTicks)
-    {
-      targetTicks = 0;
-      if (alarm_signal_func)
-       (*alarm_signal_func)(SIGALRM);
-    }
-}
-
-/* Called in sys_select to wait for an alarm signal to arrive.  */
-int
-pause ()
-{
-  unsigned long finalTick;
-  
-  if (!targetTicks)  /* no alarm pending */
-    return -1;
-
-  while (TickCount () <= targetTicks)
-    Delay (1UL, &finalTick);  /* wait for 1/60 second before trying again */
-  
-  targetTicks = 0;
-  if (alarm_signal_func)
-    (*alarm_signal_func)(SIGALRM);
-  
-  return 0;
-}
-
-int
-alarm (int seconds)
-{
-  long remaining = targetTicks ? (TickCount () - targetTicks) / 60 : 0;
-       
-  targetTicks = seconds ? TickCount () + 60 * seconds : 0;
-       
-  return (remaining < 0) ? 0 : (unsigned int) remaining;
-}
-
-#undef signal
-#ifdef __MRC__
-extern __sigfun signal (int signal, __sigfun signal_func);
-__sigfun
-sys_signal (int signal_num, __sigfun signal_func)
-#elif __MWERKS__
-extern __signal_func_ptr signal (int signal, __signal_func_ptr signal_func);
-__signal_func_ptr
-sys_signal (int signal_num, __signal_func_ptr signal_func)
-#else
-     You lose!!!
-#endif
-{
-  if (signal_num != SIGALRM)
-    return signal (signal_num, signal_func);
-  else
-    {
-#ifdef __MRC__
-      __sigfun old_signal_func;                
-#elif __MWERKS__
-      __signal_func_ptr old_signal_func;               
-#else
-      You lose!!!
-#endif
-       old_signal_func = alarm_signal_func;
-      alarm_signal_func = signal_func;
-      return old_signal_func;
-    }
-}
-
-/* The time functions adjust time values according to the difference
-   between the Unix and CW epoches. */
-
-#undef gmtime
-extern struct tm *gmtime (const time_t *);
-struct tm 
-sys_gmtime (const time_t *timer)
-{
-  time_t unixTime = *timer + CW_UNIX_EPOCH_DIFF;
-  
-  return gmtime (&unixTime);
-}
-
-#undef localtime
-extern struct tm *localtime (const time_t *);
-struct tm *
-sys_localtime (const time_t *timer)
-{
-  time_t unixTime = *timer + CW_UNIX_EPOCH_DIFF;
-  
-  return localtime (&unixTime);
-}
-
-#undef ctime
-extern char *ctime (const time_t *);
-char *
-sys_ctime (const time_t *timer)
-{
-  time_t unixTime = *timer + CW_UNIX_EPOCH_DIFF;
-  
-  return ctime (&unixTime);
-}
-
-#undef time
-extern time_t time (time_t *);
-time_t
-sys_time (time_t *timer)
-{
-  time_t macTime = time (NULL) - CW_UNIX_EPOCH_DIFF;
-
-  if (timer)
-    *timer = macTime;
-    
-  return macTime;
-}
-
-/* no subprocesses, empty wait */
-int
-wait (int pid)
-{
-  return 0;
-}
-
-void
-croak (char *badfunc)
-{
-  printf ("%s not yet implemented\r\n", badfunc);
-  exit (1);
-}
-
-char *
-index (const char * str, int chr)
-{
-  return strchr (str, chr);
-}
-
-char *e[] = { 0 };
-char **environ = &e[0];
-
-char *
-mktemp (char *template)
-{
-  int len, k;
-  static seqnum = 0;
-  
-  len = strlen (template);
-  k = len - 1;
-  while (k >= 0 && template[k] == 'X')
-    k--;
-  
-  k++;  /* make k index of first 'X' */
-  
-  if (k < len)
-    {
-      /* Zero filled, number of digits equal to the number of X's.  */
-      sprintf (&template[k], "%0*d", len-k, seqnum++);
-  
-      return template;
-    }
-  else
-    return 0;  
-}
-
-/* Emulate getpwuid, getpwnam and others.  */
-
-#define PASSWD_FIELD_SIZE 256
-
-static char myPasswdName[PASSWD_FIELD_SIZE];
-static char myPasswdDir[MAXPATHLEN+1];
-
-static struct passwd myPasswd = 
-{
-  myPasswdName,
-  myPasswdDir,
-};
-
-/* Initialized by main () in macterm.c to pathname of emacs directory.  */
-char emacsPasswdDir[MAXPATHLEN+1];
-
-void
-InitEmacsPasswdDir ()
-{
-  int found = false;
-
-  if (getwd (emacsPasswdDir) && getwd (myPasswdDir))
-    {  
-      /* Need pathname of first ancestor that begins with `emacs' since
-        Mac emacs application is somewhere in the emacs-20.3 tree.  */
-      int len = strlen (emacsPasswdDir);
-      /* J points to the "/" following the directory name being compared.  */
-      int j = len - 1;
-      int i = j - 1;
-      while (i >= 0 && !found)
-       {
-         while (i >= 0 && emacsPasswdDir[i] != '/')
-           i--;
-         if (emacsPasswdDir[i] == '/' && i+5 < len)
-           found = (strncmp (&(emacsPasswdDir[i+1]), "emacs", 5) == 0);
-         if (found)
-           emacsPasswdDir[j+1] = '\0';
-         else
-           {
-             j = i;
-             i = j - 1;
-           }
-       }
-    }
-  
-  if (!found)
-    {  /* setting to "/" probably won't work,
-         but set it to something anyway.  */
-      strcpy (emacsPasswdDir, "/");
-      strcpy (myPasswdDir, "/");
-    }
-}
-
-static struct passwd emacsPasswd = 
-{
-  "emacs",
-  emacsPasswdDir,
-};
-
-static int myPasswdInited = 0;
-
-static void
-InitMyPasswd ()
-{
-  char **ownerName;
-
-  /* Note: myPasswdDir initialized in InitEmacsPasswdDir to directory
-     where Emacs was started. */
-
-  ownerName = (char **) GetResource ('STR ',-16096);
-  if (ownerName)
-    {
-      HLock (ownerName);
-      BlockMove ((unsigned char *) *ownerName,
-                (unsigned char *) myPasswdName, *ownerName[0] + 1);
-      HUnlock (ownerName);
-      p2cstr ((unsigned char *) myPasswdName);
-    }
-  else
-    myPasswdName[0] = 0;
-}
-
-struct passwd *
-getpwuid (uid_t uid)
-{
-  if (!myPasswdInited)
-    {  
-      InitMyPasswd ();
-      myPasswdInited = 1;
-    }
-  
-  return &myPasswd;
-}
-
-struct passwd *
-getpwnam (const char *name)
-{
-  if (strcmp (name, "emacs") == 0)
-       return &emacsPasswd;
-
-  if (!myPasswdInited)
-    {  
-      InitMyPasswd ();
-      myPasswdInited = 1;
-    }
-  
-  return &myPasswd;
-}
-
-/* The functions fork, kill, sigsetmask, sigblock, request_sigio,
-   setpgrp, setpriority, and unrequest_sigio are defined to be empty
-   as in msdos.c.  */
-
-int
-fork ()
-{
-  return -1;
-}
-
-int
-kill (int x, int y)
-{
-  return -1;
-}
-
-int
-sigsetmask (int x)
-{
-  return 0;
-}
-
-int
-sigblock (int mask)
-{
-  return 0;
-} 
-
-void
-request_sigio (void)
-{
-}
-
-int
-setpgrp ()
-{
-  return 0;
-}
-
-void
-unrequest_sigio (void)
-{
-}
-
-/* djgpp does not implement pipe either.  */
-int
-pipe (int _fildes[2])
-{
-  errno = EACCES;
-  return -1;
-}
-
-/* Hard and symbolic links.  */
-int
-symlink (const char *name1, const char *name2)
-{
-  errno = ENOENT;
-  return -1;
-}
-
-int
-link (const char *name1, const char *name2)
-{
-  errno = ENOENT;
-  return -1;
-}
-
-int
-lstat (const char *path, struct stat *sb)
-{
-  return stat (path, sb);
-}
-
-int
-readlink (const char *path, char *buf, int bufsiz)
-{
-  errno = ENOENT;
-  return -1;
-}
-
-mode_t
-umask (mode_t numask)
-{
-  static mode_t mask = 022;
-  mode_t oldmask = mask;
-  mask = numask;
-  return oldmask;
-}
-
-int
-chmod (const char *path, mode_t mode)
-{
-  /* say it always succeed for now */
-  return 0;
-}
-
-int
-dup (int oldd)
-{
-#ifdef __MRC__
-  return fcntl (oldd, F_DUPFD, 0);
-#elif __MWERKS__
-  /* current implementation of fcntl in fcntl.mac.c simply returns old
-     descriptor */
-  return fcntl (oldd, F_DUPFD);
-#else
-You lose!!!
-#endif
-}
-
-/* This is from the original sysdep.c.  Emulate BSD dup2.  First close
-   newd if it already exists.  Then, attempt to dup oldd.  If not
-   successful, call dup2 recursively until we are, then close the
-   unsuccessful ones.  */
-int
-dup2 (int oldd, int newd)
-{
-  int fd, ret;
-  
-  close (newd);
-
-  fd = dup (oldd);
-  if (fd == -1)
-    return -1;
-  if (fd == newd)
-    return newd;
-  ret = dup2 (oldd, newd);
-  close (fd);
-  return ret;
-}
-
-/* let it fail for now */
-char *
-sbrk (int incr)
-{
-  return (char *) -1;
-}
-
-int
-fsync (int fd)
-{
-  return 0;
-}
-
-int
-ioctl (int d, int request, void *argp)
-{
-  return -1;
-}
-
-#ifdef __MRC__
-int
-isatty (int fildes)
-{
-  if (fildes >=0 && fildes <= 2)
-    return 1;
-  else
-    return 0;
-}
-
-int
-getgid ()
-{
-  return 100;
-}
-
-int
-getegid ()
-{
-  return 100;
-}
-
-int
-getuid ()
-{
-  return 200;
-}
-
-int
-geteuid ()
-{
-  return 200;
-}
-
-unsigned int
-sleep (unsigned int seconds)
-{
-  unsigned long finalTick;
-
-  Delay (seconds * 60UL, &finalTick);
-  return (0);
-}
-#endif /* __MRC__ */
-
-#ifdef __MWERKS__
-#undef getpid
-int
-getpid ()
-{
-  return 9999;
-}
-#endif /* __MWERKS__ */
-
-/* Return the path to the directory in which Emacs can create
-   temporary files.  The MacOS "temporary items" directory cannot be
-   used because it removes the file written by a process when it
-   exits.  In that sense it's more like "/dev/null" than "/tmp" (but
-   again not exactly).  And of course Emacs needs to read back the
-   files written by its subprocesses.  So here we write the files to a
-   directory "Emacs" in the Preferences Folder.  This directory is
-   created if it does not exist.  */
-static char *
-GetTempDirName ()
-{
-  static char *TempDirName = NULL;
-  short vRefNum;
-  long dirID;
-  OSErr err;
-  Str255 dirName, fullPath;
-  CInfoPBRec cpb;
-  char unixDirName[MAXPATHLEN+1];
-  DIR *dir;
-  
-  /* Cache directory name with pointer TempDirName.
-     Look for it only the first time.  */
-  if (!TempDirName)
-    {
-      err = FindFolder (kOnSystemDisk, kPreferencesFolderType,
-                       kCreateFolder, &vRefNum, &dirID);
-      if (err != noErr)
-       return NULL;
-
-      *fullPath = '\0';
-      cpb.dirInfo.ioNamePtr = dirName;
-      cpb.dirInfo.ioDrParID = dirID;
-    
-      /* Standard ref num to full path name loop */
-      do {
-       cpb.dirInfo.ioVRefNum = vRefNum;
-       cpb.dirInfo.ioFDirIndex = -1;
-       cpb.dirInfo.ioDrDirID = cpb.dirInfo.ioDrParID;
-      
-       err = PBGetCatInfo (&cpb, false);
-      
-       p2cstr (dirName);
-       strcat (dirName, ":");
-       if (strlen (fullPath) + strlen (dirName) <= MAXPATHLEN)
-         {
-           strcat (dirName, fullPath);
-           strcpy (fullPath, dirName);
-         }
-       else
-         return NULL;
-      }
-      while (cpb.dirInfo.ioDrDirID != fsRtDirID && err == noErr);
-
-      if (strlen (fullPath) + 6 <= MAXPATHLEN)
-       strcat (fullPath, "Emacs:");
-      else
-       return NULL;
-
-      if (Mac2UnixPathname (fullPath, unixDirName, MAXPATHLEN+1) == 0)
-       return NULL;
-    
-      dir = opendir (unixDirName);  /* check whether temp directory exists */
-      if (dir)
-       closedir (dir);
-      else if (mkdir (unixDirName, 0700) != 0)  /* create it if not */
-       return NULL;
-
-      TempDirName = (char *) malloc (strlen (unixDirName) + 1);
-      strcpy (TempDirName, unixDirName);
-    }
-
-  return TempDirName;
-}
-
-char *
-getenv (const char * name)
-{
-  if (strcmp (name, "TERM") == 0)
-    return "vt100";
-  else if (strcmp (name, "TERMCAP") == 0)
-    /* for debugging purpose when code was still outputting to dumb terminal */
-    return "d0|vt100|vt100-am|vt100am|dec vt100:do=[do]:co#100:li#32:cl=[cl]:sf=[sf]:km:\
-:le=[le]:bs:am:cm=[cm-%d,%d]:nd=[nd]:up=[up]:ce=[ce]:cd=[cd]:so=[so]:se=[se]:\
-:us=[us]:ue=[ue]:md=[md]:mr=[mr]:mb=[mb]:me=[me]:is=[is]:\
-:rf=/usr/share/lib/tabset/vt100:rs=[rs]:ks=[ks]:ke=[ke]:\
-:ku=\\036:kd=\\037:kr=\\035:kl=\\034:kb=[kb]:ho=[ho]:k1=[k1]:k2=[k2]:k3=[k3]:k4=[k4]:\
-:pt:sr=[sr]:vt#3:xn:sc=[sc]:rc=[rc]:cs=[cs-%d,%d]";
-  else if (strcmp (name, "TMPDIR") == 0)
-    return GetTempDirName ();
-  else
-    return (NULL);
-}
-
-#ifdef __MRC__
-/* see Interfaces&Libraries:Interfaces:CIncludes:signal.h */
-char *sys_siglist[] =
-{
-  "Zero is not a signal!!!",
-  "Abort",  /* 1 */
-  "Interactive user interrupt",  /* 2 */  "BAD",
-  "Floating point exception",  /* 4 */  "BAD", "BAD", "BAD",
-  "Illegal instruction",  /* 8 */  "BAD", "BAD", "BAD", "BAD", "BAD", "BAD", "BAD",
-  "Segment violation",  /* 16 */  "BAD", "BAD", "BAD", "BAD", "BAD", "BAD", "BAD", "BAD", "BAD", "BAD", "BAD", "BAD", "BAD", "BAD", "BAD",
-  "Terminal"  /* 32 */
-};
-#elif __MWERKS__
-char *sys_siglist[] =
-{
-  "Zero is not a signal!!!",
-  "Abort",
-  "Floating point exception",
-  "Illegal instruction",
-  "Interactive user interrupt",
-  "Segment violation",
-  "Terminal"
-};
-#else
-You lose!!!
-#endif
-
-#ifdef __MRC__
-#include <utsname.h>
-
-int
-uname (struct utsname *name)
-{
-  char **systemName;
-  systemName = GetString (-16413);  /* IM - Resource Manager Reference */
-  if (systemName)
-    {
-      BlockMove (*systemName, name->nodename, (*systemName)[0]+1);
-      p2cstr (name->nodename);
-    }
-  else
-    return -1;
-}
-#endif
-
-#include <Processes.h>
-#include <EPPC.h>
-
-/* Event class of HLE sent to subprocess.  */
-const OSType kEmacsSubprocessSend = 'ESND';
-/* Event class of HLE sent back from subprocess.  */
-const OSType kEmacsSubprocessReply = 'ERPY';
-
-char *
-mystrchr (char *s, char c)
-{
-  while (*s && *s != c)
-    {
-      if (*s == '\\')
-       s++;
-      s++;
-    }
-
-  if (*s)
-    {
-      *s = '\0';
-      return s;
-    }
-  else
-    return NULL;
-}
-
-char *
-mystrtok (char *s)
-{      
-  while (*s)
-    s++;
-
-  return s + 1;
-}
-
-void
-mystrcpy (char *to, char *from)
-{
-  while (*from)
-    {
-      if (*from == '\\')
-       from++;
-      *to++ = *from++;
-    }
-  *to = '\0';
-}
-
-/* Start a Mac subprocess.  Arguments for it is passed in argv (null
-   terminated).  The process should run with the default directory
-   "workdir", read input from "infn", and write output and error to
-   "outfn" and "errfn", resp.  The Process Manager call
-   LaunchApplication is used to start the subprocess.  We use high
-   level events as the mechanism to pass arguments to the subprocess
-   and to make Emacs wait for the subprocess to terminate and pass
-   back a result code.  The bulk of the code here packs the arguments
-   into one message to be passed together with the high level event.
-   Emacs also sometimes starts a subprocess using a shell to perform
-   wildcard filename expansion.  Since we don't really have a shell on
-   the Mac, this case is detected and the starting of the shell is
-   by-passed.  We really need to add code here to do filename
-   expansion to support such functionality. */
-int
-run_mac_command (argv, workdir, infn, outfn, errfn)
-     unsigned char **argv;
-     const char *workdir;
-     const char *infn, *outfn, errfn;
-{
-  char macappname[MAXPATHLEN+1], macworkdir[MAXPATHLEN+1];
-  char macinfn[MAXPATHLEN+1], macoutfn[MAXPATHLEN+1], macerrfn[MAXPATHLEN+1];
-  int paramlen, argc, newargc, j, retries;
-  char **newargv, *param, *p;
-  OSErr iErr;
-  FSSpec spec;
-  LaunchParamBlockRec lpbr;
-  EventRecord sendEvent, replyEvent;
-  RgnHandle cursorRegionHdl;
-  TargetID targ;
-  unsigned long refCon, len;
-       
-  if (Unix2MacPathname (workdir, macworkdir, MAXPATHLEN+1) == 0)
-    return -1;
-  if (Unix2MacPathname (infn, macinfn, MAXPATHLEN+1) == 0)
-    return -1;
-  if (Unix2MacPathname (outfn, macoutfn, MAXPATHLEN+1) == 0)
-    return -1;
-  if (Unix2MacPathname (errfn, macerrfn, MAXPATHLEN+1) == 0)
-    return -1;
-  
-  paramlen = strlen (macworkdir) + strlen (macinfn) + strlen (macoutfn) + strlen (macerrfn) + 4;
-  /* count nulls at end of strings */
-
-  argc = 0;
-  while (argv[argc])
-    argc++;
-
-  if (argc == 0)
-    return -1;
-
-  /* If a subprocess is invoked with a shell, we receive 3 arguments of the form:
-     "<path to emacs bins>/sh" "-c" "<path to emacs bins>/<command> <command args>" */
-  j = strlen (argv[0]);
-  if (j >= 3 && strcmp (argv[0]+j-3, "/sh") == 0 && argc == 3 && strcmp (argv[1], "-c") == 0)
-    {
-      char *command, *t, tempmacpathname[MAXPATHLEN+1];
-    
-      /* The arguments for the command in argv[2] are separated by spaces.  Count them and put
-        the count in newargc.  */
-      command = (char *) alloca (strlen (argv[2])+2);
-      strcpy (command, argv[2]);
-      if (command[strlen (command) - 1] != ' ')
-       strcat (command, " ");
-    
-      t = command;
-      newargc = 0;
-      t = mystrchr (t, ' ');
-      while (t)
-       {
-         newargc++;
-         t = mystrchr (t+1, ' ');
-       }
-    
-      newargv = (char **) alloca (sizeof (char *) * newargc);
-    
-      t = command;
-      for (j = 0; j < newargc; j++)
-       {
-         newargv[j] = (char *) alloca (strlen (t) + 1);
-         mystrcpy (newargv[j], t);
-
-         t = mystrtok (t);
-         paramlen += strlen (newargv[j]) + 1;
-       }
-    
-      if (strncmp (newargv[0], "~emacs/", 7) == 0)
-       {
-         if (Unix2MacPathname (newargv[0], tempmacpathname, MAXPATHLEN+1) == 0)
-           return -1;
-       }
-      else
-       {  /* sometimes Emacs call "sh" without a path for the command */
-#if 0
-         char *t = (char *) alloca (strlen (newargv[0]) + 7 + 1);
-         strcpy (t, "~emacs/");
-         strcat (t, newargv[0]);
-#endif
-         Lisp_Object path;
-         openp (Vexec_path, build_string (newargv[0]), EXEC_SUFFIXES, &path, 1);
-
-         if (NILP (path))
-           return -1;
-         if (Unix2MacPathname (XSTRING (path)->data, tempmacpathname, MAXPATHLEN+1) == 0)
-           return -1;
-       }
-      strcpy (macappname, tempmacpathname);
-    }
-  else
-    {      
-      if (Unix2MacPathname (argv[0], macappname, MAXPATHLEN+1) == 0)
-       return -1;
-
-      newargv = (char **) alloca (sizeof (char *) * argc);
-      newargc = argc;  
-      for (j = 1; j < argc; j++)
-       {
-         if (strncmp (argv[j], "~emacs/", 7) == 0)
-           {
-             char *t = strchr (argv[j], ' ');
-             if (t)
-               {
-                 char tempcmdname[MAXPATHLEN+1], tempmaccmdname[MAXPATHLEN+1];
-                 strncpy (tempcmdname, argv[j], t-argv[j]);
-                 tempcmdname[t-argv[j]] = '\0';
-                 if (Unix2MacPathname (tempcmdname, tempmaccmdname, MAXPATHLEN+1) == 0)
-                   return -1;
-                 newargv[j] = (char *) alloca (strlen (tempmaccmdname) + strlen (t) + 1);
-                 strcpy (newargv[j], tempmaccmdname);
-                 strcat (newargv[j], t);
-               }
-             else
-               {
-                 char tempmaccmdname[MAXPATHLEN+1];
-                 if (Unix2MacPathname (argv[j], tempmaccmdname, MAXPATHLEN+1) == 0)
-                   return -1;
-                 newargv[j] = (char *) alloca (strlen (tempmaccmdname)+1);
-                 strcpy (newargv[j], tempmaccmdname);
-               }
-           }
-         else
-           newargv[j] = argv[j];  
-         paramlen += strlen (newargv[j]) + 1;
-       }
-    }
-
-  /* After expanding all the arguments, we now know the length of the parameter block to be
-     sent to the subprocess as a message attached to the HLE. */
-  param = (char *) malloc (paramlen + 1);
-  if (!param)
-    return -1;
-
-  p = param;
-  *p++ = newargc;  /* first byte of message contains number of arguments for command */
-  strcpy (p, macworkdir);
-  p += strlen (macworkdir);
-  *p++ = '\0';  /* null terminate strings sent so it's possible to use strcpy over there */
-  strcpy (p, macinfn);
-  p += strlen (macinfn);
-  *p++ = '\0';  
-  strcpy (p, macoutfn);
-  p += strlen (macoutfn);
-  *p++ = '\0';  
-  strcpy (p, macerrfn);
-  p += strlen (macerrfn);
-  *p++ = '\0';  
-  for (j = 1; j < newargc; j++) {
-    strcpy (p, newargv[j]);
-    p += strlen (newargv[j]);
-    *p++ = '\0';  
-  }
-  
-  c2pstr (macappname);
-  
-  iErr = FSMakeFSSpec (0, 0, macappname, &spec);
-  
-  if (iErr != noErr) {
-    free (param);
-    return -1;
-  }
-
-  lpbr.launchBlockID = extendedBlock;
-  lpbr.launchEPBLength = extendedBlockLen;
-  lpbr.launchControlFlags = launchContinue + launchNoFileFlags;
-  lpbr.launchAppSpec = &spec;
-  lpbr.launchAppParameters = NULL;
-
-  iErr = LaunchApplication (&lpbr);  /* call the subprocess */
-  if (iErr != noErr) {
-    free (param);
-    return -1;
-  }
-
-  sendEvent.what = kHighLevelEvent;
-  sendEvent.message = kEmacsSubprocessSend;  /* Event ID stored in "where" unused */
-
-  retries = 3;
-  do {  /* OS may think current subprocess has terminated if previous one terminated recently */
-    iErr = PostHighLevelEvent (&sendEvent, &lpbr.launchProcessSN, 0, param, paramlen + 1, receiverIDisPSN);
-  }
-  while (iErr == sessClosedErr && retries-- > 0);
-
-  if (iErr != noErr) {
-    free (param);
-    return -1;
-  }
-
-  cursorRegionHdl = NewRgn ();
-       
-  /* Wait for the subprocess to finish, when it will send us a ERPY high level event */
-  while (1)
-    if (WaitNextEvent (highLevelEventMask, &replyEvent, 180, cursorRegionHdl) && replyEvent.message == kEmacsSubprocessReply)
-      break;
-  
-  /* The return code is sent through the refCon */
-  iErr = AcceptHighLevelEvent (&targ, &refCon, NULL, &len);
-  if (iErr != noErr) {
-    DisposeHandle ((Handle) cursorRegionHdl);
-    free (param);
-    return -1;
-  }
-  
-  DisposeHandle ((Handle) cursorRegionHdl);
-  free (param);
-
-  return refCon;
-}
-
-DIR *
-opendir (const char *dirname)
-{
-  char MacPathname[MAXPATHLEN+1];
-  DIR *dirp;
-  CInfoPBRec cipb;
-  int len;
-
-  dirp = (DIR *) malloc (sizeof (DIR));
-  if (!dirp)
-    return 0;
-
-  /* Handle special case when dirname is "/": sets up for readir to
-     get all mount volumes. */
-  if (strcmp (dirname, "/") == 0) {
-    dirp->getting_volumes = 1;  /* special all mounted volumes DIR struct */
-    dirp->current_index = 1;  /* index for first volume */
-    return dirp;
-  }
-
-  /* Handle typical cases: not accessing all mounted volumes. */
-  if (Unix2MacPathname (dirname, MacPathname, MAXPATHLEN+1) == 0)
-    return 0;
-
-  /* Emacs calls opendir without the trailing '/', Mac needs trailing ':' */
-  len = strlen (MacPathname);
-  if (MacPathname[len - 1] != ':' && len < MAXPATHLEN)
-    strcat (MacPathname, ":");
-
-  c2pstr (MacPathname);
-  cipb.hFileInfo.ioNamePtr = MacPathname;  /* using full pathname so vRefNum and dirID ignored */
-  cipb.hFileInfo.ioVRefNum = 0;
-  cipb.hFileInfo.ioDirID = 0;
-  cipb.hFileInfo.ioFDirIndex = 0;  /* set to 0 to get information about specific dir or file */
-  
-  errno = PBGetCatInfo (&cipb, false);
-  if (errno != noErr) {
-    errno = ENOENT;
-    return 0;
-  }
-
-  if (!(cipb.hFileInfo.ioFlAttrib & 0x10))  /* bit 4 = 1 for directories */
-    return 0;  /* not a directory */
-
-  dirp->dir_id = cipb.dirInfo.ioDrDirID;  /* used later in readdir */
-  dirp->getting_volumes = 0;
-  dirp->current_index = 1;  /* index for first file/directory */
-  
-  return dirp;
-}
-
-int
-closedir (DIR *dp)
-{
-  free (dp);
-
-  return 0;
-}
-
-struct dirent *
-readdir (DIR *dp)
-{
-  HParamBlockRec HPBlock;
-  CInfoPBRec cipb;
-  static struct dirent s_dirent;
-  static Str255 s_name;
-  int done;
-
-  /* Handle the root directory containing the mounted volumes.  Call
-     PBHGetVInfo specifying an index to obtain the info for a volume.
-     PBHGetVInfo returns an error when it receives an index beyond the
-     last volume, at which time we should return a nil dirent struct
-     pointer. */
-  if (dp->getting_volumes) {
-    HPBlock.volumeParam.ioNamePtr = s_name;
-    HPBlock.volumeParam.ioVRefNum = 0;
-    HPBlock.volumeParam.ioVolIndex = dp->current_index;
-                
-    errno = PBHGetVInfo (&HPBlock, false);
-    if (errno != noErr) {
-      errno = ENOENT;
-      return 0;
-    }
-                        
-    p2cstr (s_name);
-    strcat (s_name, "/");  /* need "/" for stat to work correctly */
-
-    dp->current_index++;
-
-    s_dirent.d_ino = cipb.dirInfo.ioDrDirID;
-    s_dirent.d_name = s_name;
-  
-    return &s_dirent;
-  }
-  else {
-    cipb.hFileInfo.ioVRefNum = 0;
-    cipb.hFileInfo.ioNamePtr = s_name;  /* location to receive filename returned */
-
-    /* return only visible files */
-    done = false;
-    while (!done) {
-      cipb.hFileInfo.ioDirID = dp->dir_id;  /* directory ID found by opendir */
-      cipb.hFileInfo.ioFDirIndex = dp->current_index;
-
-      errno = PBGetCatInfo (&cipb, false);
-      if (errno != noErr) {
-        errno = ENOENT;
-        return 0;
-      }
-
-      /* insist on an visibile entry */
-      if (cipb.hFileInfo.ioFlAttrib & 0x10)  /* directory? */
-        done = !(cipb.dirInfo.ioDrUsrWds.frFlags & fInvisible);
-      else
-        done = !(cipb.hFileInfo.ioFlFndrInfo.fdFlags & fInvisible);
-
-      dp->current_index++;
-    }
-
-    p2cstr (s_name);
-
-    s_dirent.d_ino = cipb.dirInfo.ioDrDirID;  /* value unimportant: non-zero for valid file */
-    s_dirent.d_name = s_name;
-  
-    return &s_dirent;
-  }
-}
-
-char *
-getwd (char *path)
-{
-  char MacPathname[MAXPATHLEN+1];
-  Str255 directoryName;
-  OSErr errno;
-  CInfoPBRec cipb;
-
-  MacPathname[0] = '\0';
-  directoryName[0] = '\0';
-  cipb.dirInfo.ioDrParID = 0;
-  cipb.dirInfo.ioNamePtr = directoryName;  /* empty string = default directory */
-
-  do {
-    cipb.dirInfo.ioVRefNum = 0;
-    cipb.dirInfo.ioFDirIndex = -1;
-    cipb.dirInfo.ioDrDirID = cipb.dirInfo.ioDrParID;  /* go up to parent each time */
-
-    errno = PBGetCatInfo (&cipb, false);
-    if (errno != noErr) {
-      errno = ENOENT;
-      return 0;
-    }
-
-    p2cstr (directoryName);
-    strcat (directoryName, ":");
-    strcat (directoryName, MacPathname);  /* attach to front since going up directory tree */
-    strcpy (MacPathname, directoryName);
-  } while (cipb.dirInfo.ioDrDirID != fsRtDirID);  /* until volume's root directory */
-
-  if (Mac2UnixPathname (MacPathname, path, MAXPATHLEN+1) == 0)
-    return 0;
-  else
-    return path;
-}
 
-#endif /* macintosh */
+/* arch-tag: edb43589-4e09-4544-b325-978b5b121dcf
+   (do not change this comment) */