Version 3.16
[bpt/emacs.git] / src / sysdep.c
index d53b7d9..eae493b 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, 1986, 1987, 1988, 1993, 1994, 1995, 1999, 2000, 2001,
+                 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -15,40 +16,46 @@ GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with GNU Emacs; see the file COPYING.  If not, write to
-the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA.  */
+the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA.  */
 
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
 
-#include "config.h"
 #include <signal.h>
+#include <stdio.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 "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
+#include <sys/param.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 sys_read
@@ -66,26 +73,10 @@ Lisp_Object Vx_bitmap_file_path;
 #undef fwrite
 #endif
 
-#ifdef TRY_AGAIN
-#ifndef HAVE_H_ERRNO
-extern int h_errno;
-#endif
-#endif /* TRY_AGAIN */
-
-#include <stdio.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <errno.h>
 
-/* Get _POSIX_VDISABLE, if it is available.  */
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-
 #ifdef HAVE_SETPGID
 #if !defined (USG) || defined (BSD_PGRPS)
 #undef setpgrp
@@ -139,17 +130,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>
@@ -196,6 +183,7 @@ extern int quit_char;
 #define _P_WAIT 0
 int _CRTAPI1 _spawnlp (int, const char *, const char *, ...);
 int _CRTAPI1 _getpid (void);
+extern char *getwd (char *);
 #endif
 
 #ifdef NONSYSTEM_DIR_LIBRARY
@@ -240,22 +228,17 @@ static int baud_convert[] =
 
 #ifdef HAVE_SPEED_T
 #include <termios.h>
-extern speed_t ospeed;
 #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
 
+int emacs_ospeed;
+
 /* The file descriptor for Emacs's input terminal.
    Under Unix, this is normally zero except when using X;
    under VMS, we place the input channel number here.  */
@@ -272,6 +255,81 @@ void hft_reset ();
 
 SIGMASKTYPE sigprocmask_set;
 
+
+#ifndef HAVE_GET_CURRENT_DIR_NAME
+
+/* Return the current working directory.  Returns NULL on errors.
+   Any other returned value must be freed with free. This is used
+   only when get_current_dir_name is not defined on the system.  */
+char*
+get_current_dir_name ()
+{
+  char *buf;
+  char *pwd;
+  struct stat dotstat, pwdstat;
+  /* If PWD is accurate, use it instead of calling getwd.  PWD is
+     sometimes a nicer name, and using it may avoid a fatal error if a
+     parent directory is searchable but not readable.  */
+    if ((pwd = getenv ("PWD")) != 0
+      && (IS_DIRECTORY_SEP (*pwd) || (*pwd && IS_DEVICE_SEP (pwd[1])))
+      && stat (pwd, &pwdstat) == 0
+      && stat (".", &dotstat) == 0
+      && dotstat.st_ino == pwdstat.st_ino
+      && dotstat.st_dev == pwdstat.st_dev
+#ifdef MAXPATHLEN
+      && strlen (pwd) < MAXPATHLEN
+#endif
+      )
+    {
+      buf = (char *) malloc (strlen (pwd) + 1);
+      if (!buf)
+        return NULL;
+      strcpy (buf, pwd);
+    }
+#ifdef HAVE_GETCWD
+  else
+    {
+      size_t buf_size = 1024;
+      buf = (char *) malloc (buf_size);
+      if (!buf)
+        return NULL;
+      for (;;)
+        {
+          if (getcwd (buf, buf_size) == buf)
+            break;
+          if (errno != ERANGE)
+            {
+              int tmp_errno = errno;
+              free (buf);
+              errno = tmp_errno;
+              return NULL;
+            }
+          buf_size *= 2;
+          buf = (char *) realloc (buf, buf_size);
+          if (!buf)
+            return NULL;
+        }
+    }
+#else
+  else
+    {
+      /* We need MAXPATHLEN here.  */
+      buf = (char *) malloc (MAXPATHLEN + 1);
+      if (!buf)
+        return NULL;
+      if (getwd (buf) == NULL)
+        {
+          int tmp_errno = errno;
+          free (buf);
+          errno = tmp_errno;
+          return NULL;
+        }
+    }
+#endif
+  return buf;
+}
+#endif
+
 \f
 /* Specify a different file descriptor for further input operations.  */
 
@@ -328,8 +386,12 @@ discard_tty_input ()
    the terminal.  */
 
 void
+#ifdef PROTOTYPES
+stuff_char (char c)
+#else
 stuff_char (c)
      char c;
+#endif
 {
   if (read_socket_hook)
     return;
@@ -348,32 +410,32 @@ void
 init_baud_rate ()
 {
   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,
                &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);
+      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
@@ -385,23 +447,23 @@ init_baud_rate ()
 #else
       ioctl (input_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)
        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;
 }
@@ -479,14 +541,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);
@@ -538,7 +602,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;
@@ -585,6 +649,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
@@ -611,6 +682,15 @@ child_setup_tty (out)
   s.main.c_cflag = (s.main.c_cflag & ~CBAUD) | B9600; /* baud rate sanity */
 #endif /* HPUX */
 
+#ifdef SIGNALS_VIA_CHARACTERS
+  /* the QUIT and INTR character are used in process_send_signal
+     so set them here to something useful.  */
+  if (s.main.c_cc[VQUIT] == CDISABLE)
+    s.main.c_cc[VQUIT] = '\\'&037;     /* Control-\ */
+  if (s.main.c_cc[VINTR] == CDISABLE)
+    s.main.c_cc[VINTR] = 'C'&037;      /* Control-C */
+#endif /* not SIGNALS_VIA_CHARACTERS */
+
 #ifdef AIX
 /* AIX enhanced edit loses NULs, so disable it */
 #ifndef IBMR2AIX
@@ -621,22 +701,16 @@ child_setup_tty (out)
      don't ignore break, but don't signal either, so it looks like NUL.  */
   s.main.c_iflag &= ~IGNBRK;
   s.main.c_iflag &= ~BRKINT;
+  /* rms: Formerly it set s.main.c_cc[VINTR] to 0377 here
+     unconditionally.  Then a SIGNALS_VIA_CHARACTERS conditional
+     would force it to 0377.  That looks like duplicated code.  */
+#ifndef SIGNALS_VIA_CHARACTERS
   /* QUIT and INTR work better as signals, so disable character forms */
-  s.main.c_cc[VINTR] = 0377;
-#ifdef SIGNALS_VIA_CHARACTERS
-  /* the QUIT and INTR character are used in process_send_signal
-     so set them here to something useful.  */
-  if (s.main.c_cc[VQUIT] == 0377)
-    s.main.c_cc[VQUIT] = '\\'&037;     /* Control-\ */
-  if (s.main.c_cc[VINTR] == 0377)
-    s.main.c_cc[VINTR] = 'C'&037;      /* Control-C */
-#else /* no TIOCGPGRP or no TIOCGLTC or no TIOCGETC */
-  /* QUIT and INTR work better as signals, so disable character forms */
-  s.main.c_cc[VQUIT] = 0377;
-  s.main.c_cc[VINTR] = 0377;
+  s.main.c_cc[VQUIT] = CDISABLE;
+  s.main.c_cc[VINTR] = CDISABLE;
   s.main.c_lflag &= ~ISIG;
 #endif /* no TIOCGPGRP or no TIOCGLTC or no TIOCGETC */
-  s.main.c_cc[VEOL] = 0377;
+  s.main.c_cc[VEOL] = CDISABLE;
   s.main.c_cflag = (s.main.c_cflag & ~CBAUD) | B9600; /* baud rate sanity */
 #endif /* AIX */
 
@@ -751,12 +825,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;
@@ -789,9 +861,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:
@@ -802,7 +874,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");
@@ -832,7 +904,7 @@ sys_subshell ()
 
 #ifdef SET_EMACS_PRIORITY
       {
-       extern int emacs_priority;
+       extern EMACS_INT emacs_priority;
 
        if (emacs_priority < 0)
          nice (-emacs_priority);
@@ -840,8 +912,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));
@@ -854,7 +941,7 @@ sys_subshell ()
       if (pid == -1)
        write (1, "Can't execute subshell", 22);
 #else   /* not WINDOWSNT */
-      execlp (sh, sh, 0);
+      execlp (sh, sh, (char *) 0);
       write (1, "Can't execute subshell", 22);
       _exit (1);
 #endif  /* not WINDOWSNT */
@@ -873,8 +960,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)
@@ -977,7 +1064,7 @@ unrequest_sigio ()
 }
 
 #else /* not FASYNC, not STRIDE */
+
 #ifdef _CX_UX
 
 #include <termios.h>
@@ -1011,6 +1098,7 @@ unrequest_sigio ()
 }
 
 #else /* ! _CX_UX */
+#ifndef MSDOS
 
 void
 request_sigio ()
@@ -1020,7 +1108,7 @@ request_sigio ()
 
   croak ("request_sigio");
 }
+
 void
 unrequest_sigio ()
 {
@@ -1029,7 +1117,8 @@ unrequest_sigio ()
 
   croak ("unrequest_sigio");
 }
+
+#endif /* MSDOS */
 #endif /* _CX_UX */
 #endif /* STRIDE */
 #endif /* FASYNC */
@@ -1231,7 +1320,7 @@ emacs_set_tty (fd, settings, flushp)
       || ioctl (fd, TIOCLSET, &settings->lmode) < 0)
     return -1;
 #endif
-  
+
   /* We have survived the tempest.  */
   return 0;
 }
@@ -1271,38 +1360,28 @@ 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 ()
 {
   struct emacs_tty tty;
 
-#ifdef macintosh
-  Vwindow_system = intern ("mac");
-  Vwindow_system_version = make_number (1);
-
-/* 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
@@ -1396,7 +1475,7 @@ 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
@@ -1472,10 +1551,10 @@ nil means don't delete them until `list-processes' is run.");
       tty.main.c_line = 0;
       tty.main.c_iflag &= ~ASCEDIT;
 #else
-      tty.main.c_cc[VSTRT] = 255;
-      tty.main.c_cc[VSTOP] = 255;
-      tty.main.c_cc[VSUSP] = 255;
-      tty.main.c_cc[VDSUSP] = 255;
+      tty.main.c_cc[VSTRT] = CDISABLE;
+      tty.main.c_cc[VSTOP] = CDISABLE;
+      tty.main.c_cc[VSUSP] = CDISABLE;
+      tty.main.c_cc[VDSUSP] = CDISABLE;
 #endif /* IBMR2AIX */
       if (flow_control)
        {
@@ -1537,7 +1616,7 @@ nil means don't delete them until `list-processes' is run.");
         anything, and leaving it in breaks the meta key.  Go figure.  */
       tty.lmode &= ~LLITOUT;
 #endif
-      
+
 #ifdef BSD4_1
       lmode = tty.lmode;
 #endif
@@ -1662,7 +1741,7 @@ nil means don't delete them until `list-processes' is run.");
 
 /* 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 ()
 {
@@ -1698,7 +1777,7 @@ get_frame_size (widthp, heightp)
 #ifdef TIOCGSIZE
 
   /* SunOS - style.  */
-  struct ttysize size;  
+  struct ttysize size;
 
   if (ioctl (input_fd, TIOCGSIZE, &size) == -1)
     *widthp = *heightp = 0;
@@ -1711,10 +1790,16 @@ get_frame_size (widthp, heightp)
 #else
 #ifdef VMS
 
+  /* Use a fresh channel since the current one may have stale info
+     (for example, from prior to a suspend); and to avoid a dependency
+     in the init sequence.  */
+  int chan;
   struct sensemode tty;
-  
-  SYS$QIOW (0, input_fd, IO$_SENSEMODE, &tty, 0, 0,
-           &tty.class, 12, 0, 0, 0, 0);
+
+  SYS$ASSIGN (&input_dsc, &chan, 0, 0);
+  SYS$QIOW (0, chan, IO$_SENSEMODE, &tty, 0, 0,
+            &tty.class, 12, 0, 0, 0, 0);
+  SYS$DASSGN (chan);
   *widthp = tty.scr_wid;
   *heightp = tty.scr_len;
 
@@ -1755,7 +1840,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;
 
@@ -1776,7 +1861,7 @@ void
 reset_sys_modes ()
 {
   struct frame *sf;
-  
+
   if (noninteractive)
     {
       fflush (stdout);
@@ -1797,13 +1882,13 @@ reset_sys_modes ()
     return;
 #endif
   sf = SELECTED_FRAME ();
-  cursor_to (FRAME_HEIGHT (sf) - 1, 0);
-  clear_end_of_line (FRAME_WIDTH (sf));
+  cursor_to (FRAME_LINES (sf) - 1, 0);
+  clear_end_of_line (FRAME_COLS (sf));
   /* clear_end_of_line may move the cursor */
-  cursor_to (FRAME_HEIGHT (sf) - 1, 0);
+  cursor_to (FRAME_LINES (sf) - 1, 0);
 #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;
 
@@ -1886,13 +1971,13 @@ 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
@@ -1924,7 +2009,7 @@ void
 init_vms_input ()
 {
   int status;
-  
+
   if (input_fd == 0)
     {
       status = SYS$ASSIGN (&input_dsc, &input_fd, 0, 0);
@@ -2000,7 +2085,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);
@@ -2031,7 +2118,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 */
        {
@@ -2046,7 +2133,7 @@ wait_for_kbd_input ()
            {
              update_mode_lines++;
              prepare_menu_bars ();
-             redisplay_preserve_echo_area ();
+             redisplay_preserve_echo_area (18);
            }
        }
     }
@@ -2125,7 +2212,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);
@@ -2225,7 +2312,8 @@ start_of_text ()
  *     will be patched by unexec to the correct value.
  *
  */
+
+#ifndef start_of_data
 char *
 start_of_data ()
 {
@@ -2248,44 +2336,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. */
@@ -2305,6 +2357,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 ()
 {
@@ -2372,7 +2430,9 @@ init_system_name ()
        if (hp)
          {
            char *fqdn = (char *) hp->h_name;
+#if 0
            char *p;
+#endif
 
            if (!index (fqdn, '.'))
              {
@@ -2446,7 +2506,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 = '-';
   }
@@ -2490,6 +2550,7 @@ select_alarm ()
 #else /* not BSD4_1 */
   signal (SIGALRM, SIG_IGN);
 #endif /* not BSD4_1 */
+  SIGNAL_THREAD_CHECK (SIGALRM);
   if (read_alarm_should_throw)
     longjmp (read_alarm_throw, 1);
 }
@@ -2552,7 +2613,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;
@@ -2599,7 +2660,7 @@ sys_select (nfds, rfds, wfds, efds, timeout)
       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)
@@ -2617,10 +2678,10 @@ sys_select (nfds, rfds, wfds, efds, timeout)
            pause ();
        }
       (*local_timeout) -= SELECT_PAUSE;
-      
+
       /* Reset the old alarm if there was one.  */
       turn_on_atimers (1);
-      
+
       if (*local_timeout == 0)  /* Stop on timer being cleared */
        break;
     }
@@ -2631,48 +2692,37 @@ sys_select (nfds, rfds, wfds, efds, timeout)
 /* Read keyboard input into the standard buffer,
    waiting for at least one character.  */
 
-/* Make all keyboard buffers much bigger when using a window system.  */
-#ifdef HAVE_WINDOW_SYSTEM
-#define BUFFER_SIZE_FACTOR 16
-#else
-#define BUFFER_SIZE_FACTOR 1
-#endif
-
 void
 read_input_waiting ()
 {
-  struct input_event e;
   int nread, i;
   extern int quit_char;
 
   if (read_socket_hook)
     {
-      struct input_event buf[256];
+      struct input_event hold_quit;
+
+      EVENT_INIT (hold_quit);
+      hold_quit.kind = NO_EVENT;
 
       read_alarm_should_throw = 0;
       if (! setjmp (read_alarm_throw))
-       nread = (*read_socket_hook) (0, buf, 256, 1);
+       nread = (*read_socket_hook) (0, 1, &hold_quit);
       else
        nread = -1;
 
-      /* Scan the chars for C-g and store them in kbd_buffer.  */
-      for (i = 0; i < nread; i++)
-       {
-         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
-             && buf[i].code == quit_char)
-           break;
-       }
+      if (hold_quit.kind != NO_EVENT)
+       kbd_buffer_store_event (&hold_quit);
     }
   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++)
@@ -2797,10 +2847,16 @@ 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) && !defined(SYNC_INPUT)
   /* 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.  */
+  /* It's not clear why the comment above says "mostly works better".  --Stef
+     When SYNC_INPUT is set, we don't want SA_RESTART because we need to poll
+     for pending input so we need long-running syscalls to be interrupted
+     after a signal that sets the interrupt_input_pending flag.  */
   new_action.sa_flags = SA_RESTART;
 #else
   new_action.sa_flags = 0;
@@ -2853,7 +2909,7 @@ sys_sigsetmask (sigset_t new_mask)
 
 #endif /* POSIX_SIGNALS */
 \f
-#if !defined HAVE_STRSIGNAL && !defined SYS_SIGLIST_DECLARED
+#if !defined HAVE_STRSIGNAL && !HAVE_DECL_SYS_SIGLIST
 static char *my_sys_siglist[NSIG];
 # ifdef sys_siglist
 #  undef sys_siglist
@@ -2869,7 +2925,7 @@ init_signals ()
   sigfillset (&full_mask);
 #endif
 
-#if !defined HAVE_STRSIGNAL && !defined SYS_SIGLIST_DECLARED
+#if !defined HAVE_STRSIGNAL && !HAVE_DECL_SYS_SIGLIST
   if (! initialized)
     {
 # ifdef SIGABRT
@@ -3029,7 +3085,7 @@ init_signals ()
       sys_siglist[SIGXFSZ] = "File size limit exceeded";
 # endif
     }
-#endif /* !defined HAVE_STRSIGNAL && !defined SYS_SIGLIST_DECLARED */
+#endif /* !defined HAVE_STRSIGNAL && !defined HAVE_DECL_SYS_SIGLIST */
 }
 \f
 #ifndef HAVE_RANDOM
@@ -3241,18 +3297,19 @@ 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));
+        && (errno == EINTR))
+    QUIT;
   return (rtnval);
 }
 
@@ -3283,16 +3340,17 @@ emacs_read (fildes, buf, nbyte)
      unsigned int nbyte;
 {
   register int rtnval;
-  
+
   while ((rtnval = read (fildes, buf, nbyte)) == -1
-        && (errno == EINTR));
+        && (errno == EINTR))
+    QUIT;
   return (rtnval);
 }
 
 int
 emacs_write (fildes, buf, nbyte)
      int fildes;
-     char *buf;
+     const char *buf;
      unsigned int nbyte;
 {
   register int rtnval, bytes_written;
@@ -3306,7 +3364,15 @@ emacs_write (fildes, buf, nbyte)
       if (rtnval == -1)
        {
          if (errno == EINTR)
-           continue;
+           {
+#ifdef SYNC_INPUT
+             /* I originally used `QUIT' but that might causes files to
+                be truncated if you hit C-g in the middle of it.  --Stef  */
+             if (interrupt_input_pending)
+               handle_async_input ();
+#endif
+             continue;
+           }
          else
            return (bytes_written ? bytes_written : -1);
        }
@@ -3356,7 +3422,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 != '/')
@@ -3420,7 +3489,7 @@ dup2 (oldd, newd)
      int newd;
 {
   register int fd, ret;
-  
+
   emacs_close (newd);
 
 #ifdef F_DUPFD
@@ -3449,7 +3518,7 @@ dup2 (oldd, newd)
 #ifndef VMS
 #ifndef HAVE_GETTIMEOFDAY
 #ifdef HAVE_TIMEVAL
+
 /* ARGSUSED */
 int
 gettimeofday (tp, tzp)
@@ -3458,18 +3527,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)
  */
@@ -3661,7 +3730,7 @@ readdirver (dirp)
 \f
 int
 set_file_times (filename, atime, mtime)
-     char *filename;
+     const char *filename;
      EMACS_TIME atime, mtime;
 {
 #ifdef HAVE_UTIMES
@@ -3750,7 +3819,8 @@ mkdir (dpath, dmode)
       wait_for_termination (cpid);
     }
 
-  if (synch_process_death != 0 || synch_process_retcode != 0)
+  if (synch_process_death != 0 || synch_process_retcode != 0
+      || synch_process_termsig != 0)
     {
       errno = EIO;             /* We don't know why, but */
       return -1;               /* /bin/mkdir failed */
@@ -3796,7 +3866,8 @@ rmdir (dpath)
       wait_for_termination (cpid);
     }
 
-  if (synch_process_death != 0 || synch_process_retcode != 0)
+  if (synch_process_death != 0 || synch_process_retcode != 0
+      || synch_process_termsig != 0)
     {
       errno = EIO;             /* We don't know why, but */
       return -1;               /* /bin/rmdir failed */
@@ -3810,7 +3881,6 @@ rmdir (dpath)
 \f
 /* Functions for VMS */
 #ifdef VMS
-#include "vms-pwd.h"
 #include <acldef.h>
 #include <chpdef.h>
 #include <jpidef.h>
@@ -3836,7 +3906,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.)
  */
@@ -3877,7 +3947,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)
@@ -3891,7 +3961,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))
@@ -3956,7 +4026,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))
 
@@ -4018,7 +4088,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 */
@@ -4059,7 +4129,7 @@ sys_translate_vms (vfile)
            *targ++ = '.';
            *targ++ = '.';
            break;
-           
+
          default:
            *targ++ = *vfile;
            break;
@@ -4152,7 +4222,7 @@ sys_translate_unix (ufile)
       ufile++;
     }
   *targ = '\0';
-  
+
   return utbuf;
 }
 
@@ -4174,7 +4244,7 @@ getwd (pathname)
     }
   strcpy (pathname, ptr);
   xfree (ptr);
-  
+
  return pathname;
 }
 
@@ -4511,7 +4581,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
@@ -4568,7 +4638,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 */
@@ -4632,7 +4702,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 */
@@ -4925,7 +4995,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];
 
@@ -5093,7 +5163,7 @@ hft_init ()
 
   /* 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;
@@ -5306,1542 +5376,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 *) xmalloc (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__
-#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 *) xmalloc (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) {
-    xfree (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)
-    {
-      xfree (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) {
-    xfree (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);
-    xfree (param);
-    return -1;
-  }
-  
-  DisposeHandle ((Handle) cursorRegionHdl);
-  xfree (param);
-
-  return refCon;
-}
-
-DIR *
-opendir (const char *dirname)
-{
-  char MacPathname[MAXPATHLEN+1];
-  DIR *dirp;
-  CInfoPBRec cipb;
-  int len;
-
-  dirp = (DIR *) xmalloc (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)
-{
-  xfree (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) */