Replace bcopy, bzero, bcmp by memcpy, memmove, memset, memcmp
[bpt/emacs.git] / src / sysdep.c
index 1d43a59..cfa0efa 100644 (file)
@@ -1,14 +1,14 @@
 /* Interfaces to system-dependent kernel and library entries.
    Copyright (C) 1985, 1986, 1987, 1988, 1993, 1994, 1995, 1999, 2000, 2001,
-                 2002, 2003, 2004, 2005, 2006, 2007, 2008
+                 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
                  Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
-GNU Emacs is free software; you can redistribute it and/or modify
+GNU Emacs is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 3, or (at your option)
-any later version.
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
 
 GNU Emacs is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -16,30 +16,30 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 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., 51 Franklin Street, Fifth Floor,
-Boston, MA 02110-1301, USA.  */
+along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #ifdef HAVE_CONFIG_H
 #include <config.h>
 #endif
 
+#include <ctype.h>
 #include <signal.h>
 #include <stdio.h>
 #include <setjmp.h>
+#ifdef HAVE_PWD_H
+#include <pwd.h>
+#include <grp.h>
+#endif /* HAVE_PWD_H */
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif /* HAVE_LIMITS_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 /* 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
 
 /* The w32 build defines select stuff in w32.h, which is included by
    sys/select.h (included below).   */
@@ -58,19 +58,12 @@ extern void srandom P_ ((unsigned int));
 #endif
 #endif /* not WINDOWSNT */
 
-/* Does anyone other than VMS need this? */
-#ifndef fwrite
-#define sys_fwrite fwrite
-#else
-#undef fwrite
-#endif
-
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <errno.h>
 
 #ifdef HAVE_SETPGID
-#if !defined (USG) || defined (BSD_PGRPS)
+#if !defined (USG)
 #undef setpgrp
 #define setpgrp setpgid
 #endif
@@ -87,44 +80,11 @@ extern void srandom P_ ((unsigned int));
 #include "msdos.h"
 #include <sys/param.h>
 
-#if __DJGPP__ > 1
 extern int etext;
 extern unsigned start __asm__ ("start");
 #endif
-#endif
-
-#ifndef USE_CRT_DLL
-#ifndef errno
-extern int errno;
-#endif
-#endif
-
-#ifdef VMS
-#include <rms.h>
-#include <ttdef.h>
-#include <tt2def.h>
-#include <iodef.h>
-#include <ssdef.h>
-#include <descrip.h>
-#include <fibdef.h>
-#include <atrdef.h>
-#include <ctype.h>
-#include <string.h>
-#ifdef __GNUC__
-#include <sys/file.h>
-#else
-#include <file.h>
-#endif
-#undef F_SETFL
-#ifndef RAB$C_BID
-#include <rab.h>
-#endif
-#define MAXIOSIZE (32 * PAGESIZE) /* Don't I/O more than 32 blocks at a time */
-#endif /* VMS */
 
-#ifndef VMS
 #include <sys/file.h>
-#endif /* not VMS */
 
 #ifdef HAVE_FCNTL_H
 #include <fcntl.h>
@@ -137,23 +97,9 @@ extern int errno;
 #include "systty.h"
 #include "syswait.h"
 
-#ifdef BROKEN_TIOCGWINSZ
-#undef TIOCGWINSZ
-#undef TIOCSWINSZ
-#endif
-
 #if defined (USG)
 #include <sys/utsname.h>
 #include <memory.h>
-#if defined (TIOCGWINSZ)
-#ifdef NEED_SIOCTL
-#include <sys/sioctl.h>
-#endif
-#ifdef NEED_PTEM_H
-#include <sys/stream.h>
-#include <sys/ptem.h>
-#endif
-#endif /* TIOCGWINSZ */
 #endif /* USG */
 
 extern int quit_char;
@@ -168,19 +114,20 @@ extern int quit_char;
 #include "process.h"
 #include "cm.h"  /* for reset_sys_modes */
 
+/* For serial_configure and serial_open.  */
+extern Lisp_Object QCport, QCspeed, QCprocess;
+extern Lisp_Object QCbytesize, QCstopbits, QCparity, Qodd, Qeven;
+extern Lisp_Object QCflowcontrol, Qhw, Qsw, QCsummary;
+
 #ifdef WINDOWSNT
 #include <direct.h>
 /* In process.h which conflicts with the local copy.  */
 #define _P_WAIT 0
-int _CRTAPI1 _spawnlp (int, const char *, const char *, ...);
-int _CRTAPI1 _getpid (void);
+int _cdecl _spawnlp (int, const char *, const char *, ...);
+int _cdecl _getpid (void);
 extern char *getwd (char *);
 #endif
 
-#ifdef NONSYSTEM_DIR_LIBRARY
-#include "ndir.h"
-#endif /* NONSYSTEM_DIR_LIBRARY */
-
 #include "syssignal.h"
 #include "systime.h"
 #ifdef HAVE_UTIME_H
@@ -203,19 +150,11 @@ struct utimbuf {
 #define LPASS8 0
 #endif
 
-#ifdef BSD4_1
-#define LNOFLSH 0100000
-#endif
-
-static int baud_convert[] =
-#ifdef BAUD_CONVERT
-  BAUD_CONVERT;
-#else
+static const int baud_convert[] =
   {
     0, 50, 75, 110, 135, 150, 200, 300, 600, 1200,
     1800, 2400, 4800, 9600, 19200, 38400
   };
-#endif
 
 #ifdef HAVE_SPEED_T
 #include <termios.h>
@@ -230,12 +169,7 @@ static int baud_convert[] =
 
 int emacs_ospeed;
 
-void croak P_ ((char *)) NO_RETURN;
-
-#ifdef AIXHFT
-void hft_init P_ ((struct tty_display_info *));
-void hft_reset P_ ((struct tty_display_info *));
-#endif
+void croak (char *) NO_RETURN;
 
 /* Temporary used by `sigblock' when defined in terms of signprocmask.  */
 
@@ -248,7 +182,7 @@ SIGMASKTYPE sigprocmask_set;
    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 ()
+get_current_dir_name (void)
 {
   char *buf;
   char *pwd;
@@ -320,7 +254,7 @@ get_current_dir_name ()
 /* Discard pending input on all input descriptors.  */
 
 void
-discard_tty_input ()
+discard_tty_input (void)
 {
 #ifndef WINDOWSNT
   struct emacs_tty buf;
@@ -328,12 +262,6 @@ discard_tty_input ()
   if (noninteractive)
     return;
 
-#ifdef VMS
-  end_kbd_input ();
-  SYS$QIOW (0, fileno (CURTTY()->input), IO$_READVBLK|IO$M_PURGE, input_iosb, 0, 0,
-           &buf.main, 0, 0, terminator_mask, 0, 0);
-  queue_kbd_input ();
-#else /* not VMS */
 #ifdef MSDOS    /* Demacs 1.1.1 91/10/16 HIRANO Satoshi */
   while (dos_keyread () != -1)
     ;
@@ -350,7 +278,6 @@ discard_tty_input ()
       }
   }
 #endif /* not MSDOS */
-#endif /* not VMS */
 #endif /* not WINDOWSNT */
 }
 
@@ -388,20 +315,13 @@ init_baud_rate (int fd)
 #ifdef DOS_NT
     emacs_ospeed = 15;
 #else  /* not DOS_NT */
-#ifdef VMS
-      struct sensemode sg;
-
-      SYS$QIOW (0, fd, IO$_SENSEMODE, &sg, 0, 0,
-               &sg.class, 12, 0, 0, 0, 0 );
-      emacs_ospeed = sg.xmit_baud;
-#else /* not VMS */
 #ifdef HAVE_TERMIOS
       struct termios sg;
 
       sg.c_cflag = B9600;
       tcgetattr (fd, &sg);
       emacs_ospeed = cfgetospeed (&sg);
-#else /* neither VMS nor TERMIOS */
+#else /* not TERMIOS */
 #ifdef HAVE_TERMIO
       struct termio sg;
 
@@ -412,7 +332,7 @@ init_baud_rate (int fd)
       ioctl (fd, TCGETA, &sg);
 #endif
       emacs_ospeed = sg.c_cflag & CBAUD;
-#else /* neither VMS nor TERMIOS nor TERMIO */
+#else /* neither TERMIOS nor TERMIO */
       struct sgttyb sg;
 
       sg.sg_ospeed = B9600;
@@ -421,7 +341,6 @@ init_baud_rate (int fd)
       emacs_ospeed = sg.sg_ospeed;
 #endif /* not HAVE_TERMIO */
 #endif /* not HAVE_TERMIOS */
-#endif /* not VMS */
 #endif /* not DOS_NT */
     }
 
@@ -434,8 +353,7 @@ init_baud_rate (int fd)
 \f
 /*ARGSUSED*/
 void
-set_exclusive_use (fd)
-     int fd;
+set_exclusive_use (int fd)
 {
 #ifdef FIOCLEX
   ioctl (fd, FIOCLEX, 0);
@@ -445,13 +363,10 @@ set_exclusive_use (fd)
 \f
 #ifndef subprocesses
 
-wait_without_blocking ()
+void
+wait_without_blocking (void)
 {
-#ifdef BSD_SYSTEM
-  wait3 (0, WNOHANG | WUNTRACED, 0);
-#else
   croak ("wait_without_blocking");
-#endif
   synch_process_alive = 0;
 }
 
@@ -461,26 +376,19 @@ int wait_debugging;   /* Set nonzero to make following function work under dbx
                         (at least for bsd).  */
 
 SIGTYPE
-wait_for_termination_signal ()
+wait_for_termination_signal (void)
 {}
 
 /* Wait for subprocess with process id `pid' to terminate and
    make sure it will get eliminated (not remain forever as a zombie) */
 
 void
-wait_for_termination (pid)
-     int pid;
+wait_for_termination (int pid)
 {
   while (1)
     {
 #ifdef subprocesses
-#ifdef VMS
-      int status;
-
-      status = SYS$FORCEX (&pid, 0, 0);
-      break;
-#else /* not VMS */
-#if defined (BSD_SYSTEM) || (defined (HPUX) && !defined (HPUX_5))
+#if defined (BSD_SYSTEM) || defined (HPUX)
       /* Note that kill returns -1 even if the process is just a zombie now.
         But inevitably a SIGCHLD interrupt should be generated
         and child_sig will do wait3 and make the process go away. */
@@ -500,7 +408,10 @@ wait_for_termination (pid)
       else
        sigpause (SIGEMPTYMASK);
 #else /* not BSD_SYSTEM, and not HPUX version >= 6 */
-#ifdef POSIX_SIGNALS    /* would this work for GNU/Linux as well? */
+#ifdef WINDOWSNT
+      wait (0);
+      break;
+#else /* not WINDOWSNT */
       sigblock (sigmask (SIGCHLD));
       errno = 0;
       if (kill (pid, 0) == -1 && errno == ESRCH)
@@ -510,46 +421,10 @@ wait_for_termination (pid)
        }
 
       sigsuspend (&empty_mask);
-#else /* not POSIX_SIGNALS */
-#ifdef HAVE_SYSV_SIGPAUSE
-      sighold (SIGCHLD);
-      if (0 > kill (pid, 0))
-       {
-         sigrelse (SIGCHLD);
-         break;
-       }
-      sigpause (SIGCHLD);
-#else /* not HAVE_SYSV_SIGPAUSE */
-#ifdef WINDOWSNT
-      wait (0);
-      break;
-#else /* not WINDOWSNT */
-      if (0 > kill (pid, 0))
-       break;
-      /* Using sleep instead of pause avoids timing error.
-        If the inferior dies just before the sleep,
-        we lose just one second.  */
-      sleep (1);
 #endif /* not WINDOWSNT */
-#endif /* not HAVE_SYSV_SIGPAUSE */
-#endif /* not POSIX_SIGNALS */
 #endif /* not BSD_SYSTEM, and not HPUX version >= 6 */
-#endif /* not VMS */
 #else /* not subprocesses */
-#if __DJGPP__ > 1
       break;
-#else /* not __DJGPP__ > 1 */
-#ifndef BSD4_1
-      if (kill (pid, 0) < 0)
-       break;
-      wait (0);
-#else /* BSD4_1 */
-      int status;
-      status = wait (0);
-      if (status == pid || status == -1)
-       break;
-#endif /* BSD4_1 */
-#endif /* not __DJGPP__ > 1*/
 #endif /* not subprocesses */
     }
 }
@@ -562,8 +437,7 @@ wait_for_termination (pid)
  */
 
 void
-flush_pending_output (channel)
-     int channel;
+flush_pending_output (int channel)
 {
 #ifdef HAVE_TERMIOS
   /* If we try this, we get hit with SIGTTIN, because
@@ -583,15 +457,13 @@ flush_pending_output (channel)
 #endif
 }
 \f
-#ifndef VMS
 /*  Set up the terminal at the other end of a pseudo-terminal that
     we will be controlling an inferior through.
     It should not echo or do line-editing, since that is done
     in Emacs.  No padding needed for insertion into an Emacs buffer.  */
 
 void
-child_setup_tty (out)
-     int out;
+child_setup_tty (int out)
 {
 #ifndef DOS_NT
   struct emacs_tty s;
@@ -602,18 +474,18 @@ child_setup_tty (out)
   s.main.c_oflag |= OPOST;     /* Enable output postprocessing */
   s.main.c_oflag &= ~ONLCR;    /* Disable map of NL to CR-NL on output */
 #ifdef NLDLY
+  /* http://lists.gnu.org/archive/html/emacs-devel/2008-05/msg00406.html
+     Some versions of GNU Hurd do not have FFDLY?  */
+#ifdef FFDLY
   s.main.c_oflag &= ~(NLDLY|CRDLY|TABDLY|BSDLY|VTDLY|FFDLY);
                                /* No output delays */
+#else
+  s.main.c_oflag &= ~(NLDLY|CRDLY|TABDLY|BSDLY|VTDLY);
+                               /* No output delays */
+#endif
 #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
@@ -625,14 +497,6 @@ child_setup_tty (out)
 #endif
   s.main.c_oflag &= ~TAB3;     /* Disable tab expansion */
   s.main.c_cflag = (s.main.c_cflag & ~CSIZE) | CS8; /* Don't strip 8th bit */
-#if 0
-  /* Said to be unnecessary:  */
-  s.main.c_cc[VMIN] = 1;       /* minimum number of characters to accept  */
-  s.main.c_cc[VTIME] = 0;      /* wait forever for at least 1 character  */
-#endif
-
-  s.main.c_lflag |= ICANON;    /* Enable erase/kill and eof processing */
-  s.main.c_cc[VEOF] = 04;      /* insure that EOF is Control-D */
   s.main.c_cc[VERASE] = CDISABLE;      /* disable erase processing */
   s.main.c_cc[VKILL] = CDISABLE;       /* disable kill processing */
 
@@ -650,11 +514,6 @@ child_setup_tty (out)
 #endif /* not SIGNALS_VIA_CHARACTERS */
 
 #ifdef AIX
-/* AIX enhanced edit loses NULs, so disable it */
-#ifndef IBMR2AIX
-  s.main.c_line = 0;
-  s.main.c_iflag &= ~ASCEDIT;
-#endif
   /* Also, PTY overloads NUL and BREAK.
      don't ignore break, but don't signal either, so it looks like NUL.  */
   s.main.c_iflag &= ~IGNBRK;
@@ -662,16 +521,21 @@ child_setup_tty (out)
   /* 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[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] = CDISABLE;
   s.main.c_cflag = (s.main.c_cflag & ~CBAUD) | B9600; /* baud rate sanity */
 #endif /* AIX */
 
+  /* We used to enable ICANON (and set VEOF to 04), but this leads to
+     problems where process.c wants to send EOFs every once in a while
+     to force the output, which leads to weird effects when the
+     subprocess has disabled ICANON and ends up seeing those spurious
+     extra EOFs.  So we don't send EOFs any more in
+     process.c:send_process, and instead we disable ICANON by default,
+     so if a subsprocess sets up ICANON, it's his problem (or the Elisp
+     package that talks to it) to deal with lines that are too long.  */
+  s.main.c_lflag &= ~ICANON;   /* Disable line editing and eof processing */
+  s.main.c_cc[VMIN] = 1;
+  s.main.c_cc[VTIME] = 0;
+
 #else /* not HAVE_TERMIO */
 
   s.main.sg_flags &= ~(ECHO | CRMOD | ANYP | ALLDELAY | RAW | LCASE
@@ -685,13 +549,8 @@ child_setup_tty (out)
 
   EMACS_SET_TTY (out, &s, 0);
 
-#ifdef BSD4_1
-  if (interrupt_input)
-    reset_sigio (0);
-#endif /* BSD4_1 */
 #endif /* not DOS_NT */
 }
-#endif /* not VMS */
 
 #endif /* subprocesses */
 \f
@@ -699,58 +558,17 @@ child_setup_tty (out)
 struct save_signal
 {
   int code;
-  SIGTYPE (*handler) P_ ((int));
+  SIGTYPE (*handler) (int);
 };
 
-static void save_signal_handlers P_ ((struct save_signal *));
-static void restore_signal_handlers P_ ((struct save_signal *));
+static void save_signal_handlers (struct save_signal *);
+static void restore_signal_handlers (struct save_signal *);
 
 /* Suspend the Emacs process; give terminal to its superior.  */
 
 void
-sys_suspend ()
+sys_suspend (void)
 {
-#ifdef VMS
-  /* "Foster" parentage allows emacs to return to a subprocess that attached
-     to the current emacs as a cheaper than starting a whole new process.  This
-     is set up by KEPTEDITOR.COM.  */
-  unsigned long parent_id, foster_parent_id;
-  char *fpid_string;
-
-  fpid_string = getenv ("EMACS_PARENT_PID");
-  if (fpid_string != NULL)
-    {
-      sscanf (fpid_string, "%x", &foster_parent_id);
-      if (foster_parent_id != 0)
-       parent_id = foster_parent_id;
-      else
-       parent_id = getppid ();
-    }
-  else
-    parent_id = getppid ();
-
-  xfree (fpid_string);         /* On VMS, this was malloc'd */
-
-  if (parent_id && parent_id != 0xffffffff)
-    {
-      SIGTYPE (*oldsig)() = (int) signal (SIGINT, SIG_IGN);
-      int status = LIB$ATTACH (&parent_id) & 1;
-      signal (SIGINT, oldsig);
-      return status;
-    }
-  else
-    {
-      struct {
-       int     l;
-       char    *a;
-      } d_prompt;
-      d_prompt.l = sizeof ("Emacs: ");         /* Our special prompt */
-      d_prompt.a = "Emacs: ";                  /* Just a reminder */
-      LIB$SPAWN (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &d_prompt, 0);
-      return 1;
-    }
-  return -1;
-#else
 #if defined (SIGTSTP) && !defined (MSDOS)
 
   {
@@ -759,28 +577,19 @@ sys_suspend ()
   }
 
 #else /* No SIGTSTP */
-#ifdef USG_JOBCTRL /* If you don't know what this is don't mess with it */
-  ptrace (0, 0, 0, 0);         /* set for ptrace - caught by csh */
-  kill (getpid (), SIGQUIT);
-
-#else /* No SIGTSTP or USG_JOBCTRL */
-
 /* On a system where suspending is not implemented,
    instead fork a subshell and let it talk directly to the terminal
    while we wait.  */
   sys_subshell ();
 
-#endif /* no USG_JOBCTRL */
 #endif /* no SIGTSTP */
-#endif /* not VMS */
 }
 
 /* Fork a subshell.  */
 
 void
-sys_subshell ()
+sys_subshell (void)
 {
-#ifndef VMS
 #ifdef DOS_NT  /* Demacs 1.1.2 91/10/20 Manabu Higashida */
   int st;
   char oldwd[MAXPATHLEN+1]; /* Fixed length is safe on MSDOS.  */
@@ -814,17 +623,15 @@ sys_subshell ()
   dir = expand_and_dir_to_file (Funhandled_file_name_directory (dir), Qnil);
   str = (unsigned char *) alloca (SCHARS (dir) + 2);
   len = SCHARS (dir);
-  bcopy (SDATA (dir), str, len);
+  memcpy (str, SDATA (dir), len);
   if (str[len - 1] != '/') str[len++] = '/';
   str[len] = 0;
  xyzzy:
 
 #ifdef DOS_NT
   pid = 0;
-#if __DJGPP__ > 1
   save_signal_handlers (saved_handlers);
   synch_process_alive = 1;
-#endif /* __DJGPP__ > 1 */
 #else
   pid = vfork ();
   if (pid == -1)
@@ -880,10 +687,6 @@ sys_subshell ()
        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));
-#endif
 #else /* not MSDOS */
 #ifdef  WINDOWSNT
       /* Waits for process completion */
@@ -900,7 +703,7 @@ sys_subshell ()
     }
 
   /* Do this now if we did not do it before.  */
-#if !defined (MSDOS) || __DJGPP__ == 1
+#ifndef MSDOS
   save_signal_handlers (saved_handlers);
   synch_process_alive = 1;
 #endif
@@ -910,24 +713,21 @@ sys_subshell ()
 #endif
   restore_signal_handlers (saved_handlers);
   synch_process_alive = 0;
-#endif /* !VMS */
 }
 
 static void
-save_signal_handlers (saved_handlers)
-     struct save_signal *saved_handlers;
+save_signal_handlers (struct save_signal *saved_handlers)
 {
   while (saved_handlers->code)
     {
       saved_handlers->handler
-       = (SIGTYPE (*) P_ ((int))) signal (saved_handlers->code, SIG_IGN);
+        = (SIGTYPE (*) (int)) signal (saved_handlers->code, SIG_IGN);
       saved_handlers++;
     }
 }
 
 static void
-restore_signal_handlers (saved_handlers)
-     struct save_signal *saved_handlers;
+restore_signal_handlers (struct save_signal *saved_handlers)
 {
   while (saved_handlers->code)
     {
@@ -964,8 +764,7 @@ unrequest_sigio (void)
 int old_fcntl_flags[MAXDESC];
 
 void
-init_sigio (fd)
-     int fd;
+init_sigio (int fd)
 {
 #ifdef FASYNC
   old_fcntl_flags[fd] = fcntl (fd, F_GETFL, 0) & ~FASYNC;
@@ -975,8 +774,7 @@ init_sigio (fd)
 }
 
 void
-reset_sigio (fd)
-     int fd;
+reset_sigio (int fd)
 {
 #ifdef FASYNC
   fcntl (fd, F_SETFL, old_fcntl_flags[fd]);
@@ -988,7 +786,7 @@ reset_sigio (fd)
 /* XXX Yeah, but you need it for SIGIO, don't you? */
 
 void
-request_sigio ()
+request_sigio (void)
 {
   if (noninteractive)
     return;
@@ -1003,7 +801,7 @@ request_sigio ()
 
 void
 unrequest_sigio (void)
-{ 
+{
   if (noninteractive)
     return;
 
@@ -1023,7 +821,7 @@ unrequest_sigio (void)
 #ifndef MSDOS
 
 void
-request_sigio ()
+request_sigio (void)
 {
   if (noninteractive || read_socket_hook)
     return;
@@ -1032,7 +830,7 @@ request_sigio ()
 }
 
 void
-unrequest_sigio ()
+unrequest_sigio (void)
 {
   if (noninteractive || read_socket_hook)
     return;
@@ -1044,65 +842,7 @@ unrequest_sigio ()
 #endif /* FASYNC */
 #endif /* F_SETFL */
 #endif /* SIGIO */
-\f
-/* Saving and restoring the process group of Emacs's terminal.  */
-
-#ifdef BSD_PGRPS
-
-/* The process group of which Emacs was a member when it initially
-   started.
-
-   If Emacs was in its own process group (i.e. inherited_pgroup ==
-   getpid ()), then we know we're running under a shell with job
-   control (Emacs would never be run as part of a pipeline).
-   Everything is fine.
-
-   If Emacs was not in its own process group, then we know we're
-   running under a shell (or a caller) that doesn't know how to
-   separate itself from Emacs (like sh).  Emacs must be in its own
-   process group in order to receive SIGIO correctly.  In this
-   situation, we put ourselves in our own pgroup, forcibly set the
-   tty's pgroup to our pgroup, and make sure to restore and reinstate
-   the tty's pgroup just like any other terminal setting.  If
-   inherited_group was not the tty's pgroup, then we'll get a
-   SIGTTmumble when we try to change the tty's pgroup, and a CONT if
-   it goes foreground in the future, which is what should happen.
-
-   This variable is initialized in emacs.c.  */
-int inherited_pgroup;
-
-/* Split off the foreground process group to Emacs alone.  When we are
-   in the foreground, but not started in our own process group,
-   redirect the tty device handle FD to point to our own process
-   group.  We need to be in our own process group to receive SIGIO
-   properly.  */
-static void
-narrow_foreground_group (int fd)
-{
-  int me = getpid ();
-
-  setpgrp (0, inherited_pgroup);
-#if 0
-  /* XXX inherited_pgroup should not be zero here, but GTK seems to
-     mess this up. */
-  if (! inherited_pgroup)
-    abort ();                   /* Should not happen. */
-#endif
-  if (inherited_pgroup != me)
-      EMACS_SET_TTY_PGRP (fd, &me); /* XXX This only works on the controlling tty. */
-  setpgrp (0, me);
-}
-
-/* Set the tty to our original foreground group.  */
-static void
-widen_foreground_group (int fd)
-{
-  if (inherited_pgroup != getpid ())
-    EMACS_SET_TTY_PGRP (fd, &inherited_pgroup);
-  setpgrp (0, inherited_pgroup);
-}
 
-#endif /* BSD_PGRPS */
 \f
 /* Getting and setting emacs_tty structures.  */
 
@@ -1110,14 +850,12 @@ widen_foreground_group (int fd)
    Return zero if all's well, or -1 if we ran into an error we
    couldn't deal with.  */
 int
-emacs_get_tty (fd, settings)
-     int fd;
-     struct emacs_tty *settings;
+emacs_get_tty (int fd, struct emacs_tty *settings)
 {
   /* Retrieve the primary parameters - baud rate, character size, etcetera.  */
 #ifdef HAVE_TCATTR
   /* We have those nifty POSIX tcmumbleattr functions.  */
-  bzero (&settings->main, sizeof (settings->main));
+  memset (&settings->main, 0, sizeof (settings->main));
   if (tcgetattr (fd, &settings->main) < 0)
     return -1;
 
@@ -1127,14 +865,6 @@ emacs_get_tty (fd, settings)
   if (ioctl (fd, TCGETA, &settings->main) < 0)
     return -1;
 
-#else
-#ifdef VMS
-  /* Vehemently Monstrous System?  :-)  */
-  if (! (SYS$QIOW (0, fd, IO$_SENSEMODE, settings, 0, 0,
-                  &settings->main.class, 12, 0, 0, 0, 0)
-        & 1))
-    return -1;
-
 #else
 #ifndef DOS_NT
   /* I give up - I hope you have the BSD ioctls.  */
@@ -1142,7 +872,6 @@ emacs_get_tty (fd, settings)
     return -1;
 #endif /* not DOS_NT */
 #endif
-#endif
 #endif
 
   /* Suivant - Do we have to get struct ltchars data?  */
@@ -1168,10 +897,7 @@ emacs_get_tty (fd, settings)
    Return 0 if all went well, and -1 if anything failed.  */
 
 int
-emacs_set_tty (fd, settings, flushp)
-     int fd;
-     struct emacs_tty *settings;
-     int flushp;
+emacs_set_tty (int fd, struct emacs_tty *settings, int flushp)
 {
   /* Set the primary parameters - baud rate, character size, etcetera.  */
 #ifdef HAVE_TCATTR
@@ -1196,7 +922,7 @@ emacs_set_tty (fd, settings, flushp)
       {
        struct termios new;
 
-       bzero (&new, sizeof (new));
+       memset (&new, 0, sizeof (new));
        /* Get the current settings, and see if they're what we asked for.  */
        tcgetattr (fd, &new);
        /* We cannot use memcmp on the whole structure here because under
@@ -1219,14 +945,6 @@ emacs_set_tty (fd, settings, flushp)
   if (ioctl (fd, flushp ? TCSETAF : TCSETAW, &settings->main) < 0)
     return -1;
 
-#else
-#ifdef VMS
-  /* Vehemently Monstrous System?  :-)  */
-  if (! (SYS$QIOW (0, fd, IO$_SETMODE, &input_iosb, 0, 0,
-                  &settings->main.class, 12, 0, 0, 0, 0)
-        & 1))
-    return -1;
-
 #else
 #ifndef DOS_NT
   /* I give up - I hope you have the BSD ioctls.  */
@@ -1234,7 +952,6 @@ emacs_set_tty (fd, settings, flushp)
     return -1;
 #endif /* not DOS_NT */
 
-#endif
 #endif
 #endif
 
@@ -1257,12 +974,6 @@ emacs_set_tty (fd, settings, flushp)
 
 \f
 
-#ifdef BSD4_1
-/* BSD 4.1 needs to keep track of the lmode bits in order to start
-   sigio.  */
-int lmode;
-#endif
-
 #ifdef F_SETOWN
 int old_fcntl_owner[MAXDESC];
 #endif /* F_SETOWN */
@@ -1271,15 +982,11 @@ int old_fcntl_owner[MAXDESC];
    but if so, this does no harm,
    and using the same name avoids wasting the other one's space.  */
 
-#ifdef nec_ews_svr4
-extern char *_sobuf ;
-#else
-#if defined (USG) || defined (DGUX)
+#if defined (USG)
 unsigned char _sobuf[BUFSIZ+8];
 #else
 char _sobuf[BUFSIZ];
 #endif
-#endif
 
 #ifdef HAVE_LTCHARS
 static struct ltchars new_ltchars = {-1,-1,-1,-1,-1,-1};
@@ -1302,18 +1009,10 @@ init_all_sys_modes (void)
 /* Initialize the terminal mode on the given tty device. */
 
 void
-init_sys_modes (tty_out)
-     struct tty_display_info *tty_out;
+init_sys_modes (struct tty_display_info *tty_out)
 {
   struct emacs_tty tty;
 
-#ifdef VMS
-#if 0
-  static int oob_chars[2] = {0, 1 << 7}; /* catch C-g's */
-  extern int (*interrupt_signal) ();
-#endif
-#endif
-
   Vtty_erase_char = Qnil;
 
   if (noninteractive)
@@ -1321,51 +1020,10 @@ init_sys_modes (tty_out)
 
   if (!tty_out->output)
     return;                     /* The tty is suspended. */
-  
-#ifdef VMS
-  if (!input_ef)
-    input_ef = get_kbd_event_flag ();
-    /* LIB$GET_EF (&input_ef); */
-  SYS$CLREF (input_ef);
-  waiting_for_ast = 0;
-  if (!timer_ef)
-    timer_ef = get_timer_event_flag ();
-    /* LIB$GET_EF (&timer_ef); */
-  SYS$CLREF (timer_ef);
-#if 0
-  if (!process_ef)
-    {
-      LIB$GET_EF (&process_ef);
-      SYS$CLREF (process_ef);
-    }
-  if (input_ef / 32 != process_ef / 32)
-    croak ("Input and process event flags in different clusters.");
-#endif
-  if (input_ef / 32 != timer_ef / 32)
-    croak ("Input and timer event flags in different clusters.");
-#if 0
-  input_eflist = ((unsigned) 1 << (input_ef % 32)) |
-    ((unsigned) 1 << (process_ef % 32));
-#endif
-  timer_eflist = ((unsigned) 1 << (input_ef % 32)) |
-    ((unsigned) 1 << (timer_ef % 32));
-#ifndef VMS4_4
-  sys_access_reinit ();
-#endif
-#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 (Vinitial_window_system, Qnil))
-#endif
-    narrow_foreground_group (fileno (tty_out->input));
-#endif
 
   if (! tty_out->old_tty)
     tty_out->old_tty = (struct emacs_tty *) xmalloc (sizeof (struct emacs_tty));
-      
+
   EMACS_GET_TTY (fileno (tty_out->input), tty_out->old_tty);
 
   tty = *tty_out->old_tty;
@@ -1423,7 +1081,7 @@ init_sys_modes (tty_out)
          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
@@ -1441,8 +1099,8 @@ init_sys_modes (tty_out)
   tty.main.c_cc[VSWTCH] = CDISABLE;    /* Turn off shell layering use
                                           of C-z */
 #endif /* VSWTCH */
-  
-#if defined (mips) || defined (HAVE_TCATTR)
+
+#if defined (__mips__) || defined (HAVE_TCATTR)
 #ifdef VSUSP
   tty.main.c_cc[VSUSP] = CDISABLE;     /* Turn off mips handling of C-z.  */
 #endif /* VSUSP */
@@ -1485,22 +1143,11 @@ init_sys_modes (tty_out)
     }
 #endif /* mips or HAVE_TCATTR */
 
-#ifdef SET_LINE_DISCIPLINE
-  /* Need to explicitly request TERMIODISC line discipline or
-     Ultrix's termios does not work correctly.  */
-  tty.main.c_line = SET_LINE_DISCIPLINE;
-#endif
 #ifdef AIX
-#ifndef IBMR2AIX
-  /* AIX enhanced edit loses NULs, so disable it.  */
-  tty.main.c_line = 0;
-  tty.main.c_iflag &= ~ASCEDIT;
-#else
   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 (tty_out->flow_control)
     {
 #ifdef VSTART
@@ -1518,16 +1165,6 @@ init_sys_modes (tty_out)
   tty.main.c_iflag &= ~BRKINT;
 #endif
 #else /* if not HAVE_TERMIO */
-#ifdef VMS
-  tty.main.tt_char |= TT$M_NOECHO;
-  if (meta_key)
-    tty.main.tt_char |= TT$M_EIGHTBIT;
-  if (tty_out->flow_control)
-    tty.main.tt_char |= TT$M_TTSYNC;
-  else
-    tty.main.tt_char &= ~TT$M_TTSYNC;
-  tty.main.tt2_char |= TT2$M_PASTHRU | TT2$M_XON;
-#else /* not VMS (BSD, that is) */
 #ifndef DOS_NT
   XSETINT (Vtty_erase_char, tty.main.sg_erase);
   tty.main.sg_flags &= ~(ECHO | CRMOD | XTABS);
@@ -1535,7 +1172,6 @@ init_sys_modes (tty_out)
     tty.main.sg_flags |= ANYP;
   tty.main.sg_flags |= interrupt_input ? RAW : CBREAK;
 #endif /* not DOS_NT */
-#endif /* not VMS (BSD, that is) */
 #endif /* not HAVE_TERMIO */
 
   /* If going to use CBREAK mode, we must request C-g to interrupt
@@ -1554,17 +1190,8 @@ init_sys_modes (tty_out)
       tty.tchars.t_startc = '\021';
       tty.tchars.t_stopc = '\023';
     }
-  
+
   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
 
 #endif /* HAVE_TCHARS */
 #endif /* not HAVE_TERMIO */
@@ -1575,7 +1202,7 @@ init_sys_modes (tty_out)
 #ifdef MSDOS   /* Demacs 1.1.2 91/10/20 Manabu Higashida, MW Aug 1993 */
   if (!tty_out->term_initted)
     internal_terminal_init ();
-  dos_ttraw ();
+  dos_ttraw (tty_out);
 #endif
 
   EMACS_SET_TTY (fileno (tty_out->input), &tty, 0);
@@ -1590,34 +1217,12 @@ init_sys_modes (tty_out)
   if (!tty_out->flow_control) ioctl (fileno (tty_out->input), TIOCSTART, 0);
 #endif
 
-#if defined (HAVE_TERMIOS) || defined (HPUX9)
+#if defined (HAVE_TERMIOS) || defined (HPUX)
 #ifdef TCOON
   if (!tty_out->flow_control) tcflow (fileno (tty_out->input), TCOON);
 #endif
 #endif
 
-#ifdef AIXHFT
-  hft_init (tty_out);
-#ifdef IBMR2AIX
-  {
-    /* IBM's HFT device usually thinks a ^J should be LF/CR.  We need it
-       to be only LF.  This is the way that is done. */
-    struct termio tty;
-    
-    if (ioctl (1, HFTGETID, &tty) != -1)
-      write (1, "\033[20l", 5);
-  }
-#endif
-#endif /* AIXHFT */
-
-#ifdef VMS
-/*  Appears to do nothing when in PASTHRU mode.
-      SYS$QIOW (0, fileno (tty_out->input), IO$_SETMODE|IO$M_OUTBAND, 0, 0, 0,
-               interrupt_signal, oob_chars, 0, 0, 0, 0);
-*/
-  queue_kbd_input (0);
-#endif /* VMS */
-
 #ifdef F_SETFL
 #ifdef F_GETOWN                /* F_SETFL does not imply existence of F_GETOWN */
   if (interrupt_input)
@@ -1639,14 +1244,6 @@ init_sys_modes (tty_out)
 #endif /* F_GETOWN */
 #endif /* F_SETFL */
 
-#ifdef BSD4_1
-  if (interrupt_input)
-    init_sigio (fileno (tty_out->input));
-#endif
-
-#ifdef VMS  /* VMS sometimes has this symbol but lacks setvbuf.  */
-#undef _IOFBF
-#endif
 #ifdef _IOFBF
   /* This symbol is defined on recent USG systems.
      Someone says without this call USG won't really buffer the file
@@ -1673,9 +1270,8 @@ init_sys_modes (tty_out)
 
   if (tty_out->term_initted && no_redraw_on_reenter)
     {
-      /* XXX This seems wrong on multi-tty. */
-      if (display_completed)
-       direct_output_forward_char (0);
+      /* We used to call "direct_output_forward_char(0)" here,
+        but it's not clear why, since it may not do anything anyway.  */
     }
   else
     {
@@ -1683,7 +1279,8 @@ init_sys_modes (tty_out)
       frame_garbaged = 1;
       FOR_EACH_FRAME (tail, frame)
         {
-          if (FRAME_TERMCAP_P (XFRAME (frame))
+          if ((FRAME_TERMCAP_P (XFRAME (frame))
+              || FRAME_MSDOS_P (XFRAME (frame)))
               && FRAME_TTY (XFRAME (frame)) == tty_out)
             FRAME_GARBAGED_P (XFRAME (frame)) = 1;
         }
@@ -1739,22 +1336,6 @@ get_tty_size (int fd, int *widthp, int *heightp)
       *heightp = size.ts_lines;
     }
 
-#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$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;
-
 #else
 #ifdef MSDOS
   *widthp = ScreenCols ();
@@ -1763,7 +1344,6 @@ get_tty_size (int fd, int *widthp, int *heightp)
   *widthp = 0;
   *heightp = 0;
 #endif
-#endif /* not VMS */
 #endif /* not SunOS-style */
 #endif /* not BSD-style */
 }
@@ -1772,8 +1352,7 @@ get_tty_size (int fd, int *widthp, int *heightp)
    to HEIGHT and WIDTH.  This is used mainly with ptys.  */
 
 int
-set_window_size (fd, height, width)
-     int fd, height, width;
+set_window_size (int fd, int height, int width)
 {
 #ifdef TIOCSWINSZ
 
@@ -1821,8 +1400,7 @@ reset_all_sys_modes (void)
    bottom of the frame, turn off interrupt-driven I/O, etc.  */
 
 void
-reset_sys_modes (tty_out)
-     struct tty_display_info *tty_out;
+reset_sys_modes (struct tty_display_info *tty_out)
 {
   if (noninteractive)
     {
@@ -1834,11 +1412,11 @@ reset_sys_modes (tty_out)
 
   if (!tty_out->output)
     return;                     /* The tty is suspended. */
-  
+
   /* Go to and clear the last line of the terminal. */
 
   cmgoto (tty_out, FrameRows (tty_out) - 1, 0);
-  
+
   /* Code adapted from tty_clear_end_of_line. */
   if (tty_out->TS_clr_line)
     {
@@ -1848,36 +1426,23 @@ reset_sys_modes (tty_out)
     {                  /* have to do it the hard way */
       int i;
       tty_turn_off_insert (tty_out);
-      
+
       for (i = curX (tty_out); i < FrameCols (tty_out) - 1; i++)
         {
           fputc (' ', tty_out->output);
         }
     }
-  
+
   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
-       do the LF only.  Now, we need to reset it. */
-    struct termio tty;
-
-    if (ioctl (1, HFTGETID, &tty) != -1)
-      write (1, "\033[20h", 5);
-  }
-#endif
 
   if (tty_out->terminal->reset_terminal_modes_hook)
     tty_out->terminal->reset_terminal_modes_hook (tty_out->terminal);
 
 #ifdef BSD_SYSTEM
-#ifndef BSD4_1
   /* Avoid possible loss of output when changing terminal modes.  */
   fsync (fileno (tty_out->output));
 #endif
-#endif
 
 #ifdef F_SETFL
 #ifdef F_SETOWN                /* F_SETFL does not imply existence of F_SETOWN */
@@ -1893,10 +1458,6 @@ reset_sys_modes (tty_out)
          fcntl (fileno (tty_out->input), F_GETFL, 0) & ~O_NDELAY);
 #endif
 #endif /* F_SETFL */
-#ifdef BSD4_1
-  if (interrupt_input)
-    reset_sigio (fileno (tty_out->input));
-#endif /* BSD4_1 */
 
   if (tty_out->old_tty)
     while (EMACS_SET_TTY (fileno (tty_out->input),
@@ -1907,20 +1468,6 @@ reset_sys_modes (tty_out)
   dos_ttcooked ();
 #endif
 
-#ifdef SET_LINE_DISCIPLINE
-  /* Ultrix's termios *ignores* any line discipline except TERMIODISC.
-     A different old line discipline is therefore not restored, yet.
-     Restore the old line discipline by hand.  */
-  ioctl (0, TIOCSETD, &tty_out->old_tty.main.c_line);
-#endif
-
-#ifdef AIXHFT
-  hft_reset ();
-#endif
-
-#ifdef BSD_PGRPS
-  widen_foreground_group (fileno (tty_out->input));
-#endif
 }
 \f
 #ifdef HAVE_PTYS
@@ -1928,8 +1475,7 @@ reset_sys_modes (tty_out)
 /* Set up the proper status flags for use of a pty.  */
 
 void
-setup_pty (fd)
-     int fd;
+setup_pty (int fd)
 {
   /* I'm told that TOICREMOTE does not mean control chars
      "can't be sent" but rather that they don't have
@@ -1955,7 +1501,7 @@ setup_pty (fd)
      Since the latter lossage is more benign, we may as well
      lose that way.  -- cph */
 #ifdef FIONBIO
-#if defined(SYSV_PTYS) || defined(UNIX98_PTYS)
+#if defined(UNIX98_PTYS)
   {
     int on = 1;
     ioctl (fd, FIONBIO, &on);
@@ -1965,385 +1511,102 @@ setup_pty (fd)
 }
 #endif /* HAVE_PTYS */
 \f
-#ifdef VMS
+#if !defined(CANNOT_DUMP) || !defined(SYSTEM_MALLOC)
+/* Some systems that cannot dump also cannot implement these.  */
 
-/* Assigning an input channel is done at the start of Emacs execution.
-   This is called each time Emacs is resumed, also, but does nothing
-   because input_chain is no longer zero.  */
+/*
+ *     Return the address of the start of the text segment prior to
+ *     doing an unexec.  After unexec the return value is undefined.
+ *     See crt0.c for further explanation and _start.
+ *
+ */
 
-void
-init_vms_input ()
+#if !(defined (__NetBSD__) && defined (__ELF__))
+#ifndef HAVE_TEXT_START
+char *
+start_of_text (void)
 {
-  int status;
-
-  if (fileno (CURTTY ()->input)) == 0)
-    {
-      status = SYS$ASSIGN (&input_dsc, &fileno (CURTTY ()->input)), 0, 0);
-      if (! (status & 1))
-       LIB$STOP (status);
-    }
+#ifdef TEXT_START
+  return ((char *) TEXT_START);
+#else
+  extern int _start ();
+  return ((char *) _start);
+#endif /* TEXT_START */
 }
+#endif /* not HAVE_TEXT_START */
+#endif
 
-/* Deassigning the input channel is done before exiting.  */
+/*
+ *     Return the address of the start of the data segment prior to
+ *     doing an unexec.  After unexec the return value is undefined.
+ *     See crt0.c for further information and definition of data_start.
+ *
+ *     Apparently, on BSD systems this is etext at startup.  On
+ *     USG systems (swapping) this is highly mmu dependent and
+ *     is also dependent on whether or not the program is running
+ *     with shared text.  Generally there is a (possibly large)
+ *     gap between end of text and start of data with shared text.
+ *
+ *     On Uniplus+ systems with shared text, data starts at a
+ *     fixed address.  Each port (from a given oem) is generally
+ *     different, and the specific value of the start of data can
+ *     be obtained via the UniPlus+ specific "uvar" system call,
+ *     however the method outlined in crt0.c seems to be more portable.
+ *
+ *     Probably what will have to happen when a USG unexec is available,
+ *     at least on UniPlus, is temacs will have to be made unshared so
+ *     that text and data are contiguous.  Then once loadup is complete,
+ *     unexec will produce a shared executable where the data can be
+ *     at the normal shared text boundary and the startofdata variable
+ *     will be patched by unexec to the correct value.
+ *
+ */
 
-void
-stop_vms_input ()
+#ifndef start_of_data
+char *
+start_of_data (void)
 {
-  return SYS$DASSGN (fileno (CURTTY ()->input)));
-}
-
-short input_buffer;
-
-/* Request reading one character into the keyboard buffer.
-   This is done as soon as the buffer becomes empty.  */
+#ifdef DATA_START
+  return ((char *) DATA_START);
+#else
+#ifdef ORDINARY_LINK
+  /*
+   * This is a hack.  Since we're not linking crt0.c or pre_crt0.c,
+   * data_start isn't defined.  We take the address of environ, which
+   * is known to live at or near the start of the system crt0.c, and
+   * we don't sweat the handful of bytes that might lose.
+   */
+  extern char **environ;
 
-void
-queue_kbd_input ()
-{
-  int status;
-  extern kbd_input_ast ();
-
-  waiting_for_ast = 0;
-  stop_input = 0;
-  status = SYS$QIO (0, fileno (CURTTY()->input), IO$_READVBLK,
-                   &input_iosb, kbd_input_ast, 1,
-                   &input_buffer, 1, 0, terminator_mask, 0, 0);
+  return ((char *) &environ);
+#else
+  extern int data_start;
+  return ((char *) &data_start);
+#endif /* ORDINARY_LINK */
+#endif /* DATA_START */
 }
+#endif /* start_of_data */
+#endif /* NEED_STARTS (not CANNOT_DUMP or not SYSTEM_MALLOC) */
+\f
+/* init_system_name sets up the string for the Lisp function
+   system-name to return. */
+
+extern Lisp_Object Vsystem_name;
 
-int input_count;
+#ifdef HAVE_SOCKETS
+#include <sys/socket.h>
+#include <netdb.h>
+#endif /* HAVE_SOCKETS */
 
-/* Ast routine that is called when keyboard input comes in
-   in accord with the SYS$QIO above.  */
+#ifdef TRY_AGAIN
+#ifndef HAVE_H_ERRNO
+extern int h_errno;
+#endif
+#endif /* TRY_AGAIN */
 
 void
-kbd_input_ast ()
+init_system_name (void)
 {
-  register int c = -1;
-  int old_errno = errno;
-  extern EMACS_TIME *input_available_clear_time;
-
-  if (waiting_for_ast)
-    SYS$SETEF (input_ef);
-  waiting_for_ast = 0;
-  input_count++;
-#ifdef ASTDEBUG
-  if (input_count == 25)
-    exit (1);
-  printf ("Ast # %d,", input_count);
-  printf (" iosb = %x, %x, %x, %x",
-         input_iosb.offset, input_iosb.status, input_iosb.termlen,
-         input_iosb.term);
-#endif
-  if (input_iosb.offset)
-    {
-      c = input_buffer;
-#ifdef ASTDEBUG
-      printf (", char = 0%o", c);
-#endif
-    }
-#ifdef ASTDEBUG
-  printf ("\n");
-  fflush (stdout);
-  sleep (1);
-#endif
-  if (! stop_input)
-    queue_kbd_input ();
-  if (c >= 0)
-    {
-      struct input_event e;
-      EVENT_INIT (e);
-
-      e.kind = ASCII_KEYSTROKE_EVENT;
-      XSETINT (e.code, c);
-      e.frame_or_window = selected_frame;
-      kbd_buffer_store_event (&e);
-    }
-  if (input_available_clear_time)
-    EMACS_SET_SECS_USECS (*input_available_clear_time, 0, 0);
-  errno = old_errno;
-}
-
-/* Wait until there is something in kbd_buffer.  */
-
-void
-wait_for_kbd_input ()
-{
-  extern int have_process_input, process_exited;
-
-  /* If already something, avoid doing system calls.  */
-  if (detect_input_pending ())
-    {
-      return;
-    }
-  /* Clear a flag, and tell ast routine above to set it.  */
-  SYS$CLREF (input_ef);
-  waiting_for_ast = 1;
-  /* Check for timing error: ast happened while we were doing that.  */
-  if (!detect_input_pending ())
-    {
-      /* No timing error: wait for flag to be set.  */
-      set_waiting_for_input (0);
-      SYS$WFLOR (input_ef, input_eflist);
-      clear_waiting_for_input ();
-      if (!detect_input_pending ())
-       /* Check for subprocess input availability */
-       {
-         int dsp = have_process_input || process_exited;
-
-         SYS$CLREF (process_ef);
-         if (have_process_input)
-           process_command_input ();
-         if (process_exited)
-           process_exit ();
-         if (dsp)
-           {
-             update_mode_lines++;
-             prepare_menu_bars ();
-             redisplay_preserve_echo_area (18);
-           }
-       }
-    }
-  waiting_for_ast = 0;
-}
-
-/* Get rid of any pending QIO, when we are about to suspend
-   or when we want to throw away pending input.
-   We wait for a positive sign that the AST routine has run
-   and therefore there is no I/O request queued when we return.
-   SYS$SETAST is used to avoid a timing error.  */
-
-void
-end_kbd_input ()
-{
-#ifdef ASTDEBUG
-  printf ("At end_kbd_input.\n");
-  fflush (stdout);
-  sleep (1);
-#endif
-  if (LIB$AST_IN_PROG ())  /* Don't wait if suspending from kbd_buffer_store_event! */
-    {
-      SYS$CANCEL (fileno (CURTTY()->input));
-      return;
-    }
-
-  SYS$SETAST (0);
-  /* Clear a flag, and tell ast routine above to set it.  */
-  SYS$CLREF (input_ef);
-  waiting_for_ast = 1;
-  stop_input = 1;
-  SYS$CANCEL (fileno (CURTTY()->input));
-  SYS$SETAST (1);
-  SYS$WAITFR (input_ef);
-  waiting_for_ast = 0;
-}
-
-/* Wait for either input available or time interval expiry.  */
-
-void
-input_wait_timeout (timeval)
-     int timeval;              /* Time to wait, in seconds */
-{
-  int time [2];
-  static int zero = 0;
-  static int large = -10000000;
-
-  LIB$EMUL (&timeval, &large, &zero, time);      /* Convert to VMS format */
-
-  /* If already something, avoid doing system calls.  */
-  if (detect_input_pending ())
-    {
-      return;
-    }
-  /* Clear a flag, and tell ast routine above to set it.  */
-  SYS$CLREF (input_ef);
-  waiting_for_ast = 1;
-  /* Check for timing error: ast happened while we were doing that.  */
-  if (!detect_input_pending ())
-    {
-      /* No timing error: wait for flag to be set.  */
-      SYS$CANTIM (1, 0);
-      if (SYS$SETIMR (timer_ef, time, 0, 1) & 1) /* Set timer */
-       SYS$WFLOR (timer_ef, timer_eflist);       /* Wait for timer expiry or input */
-    }
-  waiting_for_ast = 0;
-}
-
-/* The standard `sleep' routine works some other way
-   and it stops working if you have ever quit out of it.
-   This one continues to work.  */
-
-sys_sleep (timeval)
-     int 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);
-  if (SYS$SETIMR (timer_ef, time, 0, 1) & 1) /* Set timer */
-    SYS$WAITFR (timer_ef);       /* Wait for timer expiry only */
-}
-
-void
-init_sigio (fd)
-     int fd;
-{
-  request_sigio ();
-}
-
-reset_sigio (fd)
-     int fd;
-{
-  unrequest_sigio ();
-}
-
-void
-request_sigio ()
-{
-  if (noninteractive)
-    return;
-  croak ("request sigio");
-}
-
-void
-unrequest_sigio ()
-{
-  if (noninteractive)
-    return;
-  croak ("unrequest sigio");
-}
-
-#endif /* VMS */
-\f
-/* Note that VMS compiler won't accept defined (CANNOT_DUMP).  */
-#ifndef CANNOT_DUMP
-#define NEED_STARTS
-#endif
-
-#ifndef SYSTEM_MALLOC
-#ifndef NEED_STARTS
-#define NEED_STARTS
-#endif
-#endif
-
-#ifdef NEED_STARTS
-/* Some systems that cannot dump also cannot implement these.  */
-
-/*
- *     Return the address of the start of the text segment prior to
- *     doing an unexec.  After unexec the return value is undefined.
- *     See crt0.c for further explanation and _start.
- *
- */
-
-#if !(defined (__NetBSD__) && defined (__ELF__))
-#ifndef HAVE_TEXT_START
-char *
-start_of_text ()
-{
-#ifdef TEXT_START
-  return ((char *) TEXT_START);
-#else
-  extern int _start ();
-  return ((char *) _start);
-#endif /* TEXT_START */
-}
-#endif /* not HAVE_TEXT_START */
-#endif
-
-/*
- *     Return the address of the start of the data segment prior to
- *     doing an unexec.  After unexec the return value is undefined.
- *     See crt0.c for further information and definition of data_start.
- *
- *     Apparently, on BSD systems this is etext at startup.  On
- *     USG systems (swapping) this is highly mmu dependent and
- *     is also dependent on whether or not the program is running
- *     with shared text.  Generally there is a (possibly large)
- *     gap between end of text and start of data with shared text.
- *
- *     On Uniplus+ systems with shared text, data starts at a
- *     fixed address.  Each port (from a given oem) is generally
- *     different, and the specific value of the start of data can
- *     be obtained via the UniPlus+ specific "uvar" system call,
- *     however the method outlined in crt0.c seems to be more portable.
- *
- *     Probably what will have to happen when a USG unexec is available,
- *     at least on UniPlus, is temacs will have to be made unshared so
- *     that text and data are contiguous.  Then once loadup is complete,
- *     unexec will produce a shared executable where the data can be
- *     at the normal shared text boundary and the startofdata variable
- *     will be patched by unexec to the correct value.
- *
- */
-
-#ifndef start_of_data
-char *
-start_of_data ()
-{
-#ifdef DATA_START
-  return ((char *) DATA_START);
-#else
-#ifdef ORDINARY_LINK
-  /*
-   * This is a hack.  Since we're not linking crt0.c or pre_crt0.c,
-   * data_start isn't defined.  We take the address of environ, which
-   * is known to live at or near the start of the system crt0.c, and
-   * we don't sweat the handful of bytes that might lose.
-   */
-  extern char **environ;
-
-  return ((char *) &environ);
-#else
-  extern int data_start;
-  return ((char *) &data_start);
-#endif /* ORDINARY_LINK */
-#endif /* DATA_START */
-}
-#endif /* start_of_data */
-#endif /* NEED_STARTS (not CANNOT_DUMP or not SYSTEM_MALLOC) */
-\f
-/* init_system_name sets up the string for the Lisp function
-   system-name to return. */
-
-#ifdef BSD4_1
-#include <whoami.h>
-#endif
-
-extern Lisp_Object Vsystem_name;
-
-#ifndef BSD4_1
-#ifndef VMS
-#ifdef HAVE_SOCKETS
-#include <sys/socket.h>
-#include <netdb.h>
-#endif /* HAVE_SOCKETS */
-#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 ()
-{
-#ifdef BSD4_1
-  Vsystem_name = build_string (sysname);
-#else
-#ifdef VMS
-  char *sp, *end;
-  if ((sp = egetenv ("SYS$NODE")) == 0)
-    Vsystem_name = build_string ("vax-vms");
-  else if ((end = index (sp, ':')) == 0)
-    Vsystem_name = build_string (sp);
-  else
-    Vsystem_name = make_string (sp, end - sp);
-#else
 #ifndef HAVE_GETHOSTNAME
   struct utsname uts;
   uname (&uts);
@@ -2383,7 +1646,7 @@ init_system_name ()
         struct addrinfo hints;
         int ret;
 
-        memset (&hints, 0, sizeof(hints));
+        memset (&hints, 0, sizeof (hints));
         hints.ai_socktype = SOCK_STREAM;
         hints.ai_flags = AI_CANONNAME;
 
@@ -2439,9 +1702,6 @@ init_system_name ()
        if (hp)
          {
            char *fqdn = (char *) hp->h_name;
-#if 0
-           char *p;
-#endif
 
            if (!index (fqdn, '.'))
              {
@@ -2456,66 +1716,12 @@ init_system_name ()
                  fqdn = *alias;
              }
            hostname = fqdn;
-#if 0
-           /* Convert the host name to lower case.  */
-           /* Using ctype.h here would introduce a possible locale
-              dependence that is probably wrong for hostnames.  */
-           p = hostname;
-           while (*p)
-             {
-               if (*p >= 'A' && *p <= 'Z')
-                 *p += 'a' - 'A';
-               p++;
-             }
-#endif
          }
 #endif /* !HAVE_GETADDRINFO */
       }
 #endif /* HAVE_SOCKETS */
-  /* We used to try using getdomainname here,
-     but NIIBE Yutaka <gniibe@etl.go.jp> says that
-     getdomainname gets the NIS/YP domain which often is not the same
-     as in Internet domain name.  */
-#if 0 /* Turned off because sysinfo is not really likely to return the
-        correct Internet domain.  */
-#if (HAVE_SYSINFO && defined (SI_SRPC_DOMAIN))
-  if (! index (hostname, '.'))
-    {
-      /* The hostname is not fully qualified.  Append the domain name.  */
-
-      int hostlen = strlen (hostname);
-      int domain_size = 256;
-
-      for (;;)
-       {
-         char *domain = (char *) alloca (domain_size + 1);
-         char *fqdn = (char *) alloca (hostlen + 1 + domain_size + 1);
-         int sys_domain_size = sysinfo (SI_SRPC_DOMAIN, domain, domain_size);
-         if (sys_domain_size <= 0)
-           break;
-         if (domain_size < sys_domain_size)
-           {
-             domain_size = sys_domain_size;
-             continue;
-           }
-         strcpy (fqdn, hostname);
-         if (domain[0] == '.')
-           strcpy (fqdn + hostlen, domain);
-         else if (domain[0] != 0)
-           {
-             fqdn[hostlen] = '.';
-             strcpy (fqdn + hostlen + 1, domain);
-           }
-         hostname = fqdn;
-         break;
-       }
-    }
-#endif /* HAVE_SYSINFO && defined (SI_SRPC_DOMAIN) */
-#endif /* 0 */
   Vsystem_name = build_string (hostname);
 #endif /* HAVE_GETHOSTNAME */
-#endif /* VMS */
-#endif /* BSD4_1 */
   {
     unsigned char *p;
     for (p = SDATA (Vsystem_name); *p; p++)
@@ -2525,7 +1731,6 @@ init_system_name ()
 }
 \f
 #ifndef MSDOS
-#ifndef VMS
 #if !defined (HAVE_SELECT)
 
 #include "sysselect.h"
@@ -2553,15 +1758,11 @@ jmp_buf read_alarm_throw;
 
 int read_alarm_should_throw;
 
-SIGTYPE
-select_alarm ()
+void
+select_alarm (int ignore)
 {
   select_alarmed = 1;
-#ifdef BSD4_1
-  sigrelse (SIGALRM);
-#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);
@@ -2570,13 +1771,12 @@ select_alarm ()
 #ifndef WINDOWSNT
 /* Only rfds are checked.  */
 int
-sys_select (nfds, rfds, wfds, efds, timeout)
-     int nfds;
-     SELECT_TYPE *rfds, *wfds, *efds;
-     EMACS_TIME *timeout;
+sys_select (int nfds,
+           SELECT_TYPE *rfds, SELECT_TYPE *wfds, SELECT_TYPE *efds,
+           EMACS_TIME *timeout)
 {
   /* XXX This needs to be updated for multi-tty support.  Is there
-     anybody who needs to emulate select these days?  */ 
+     anybody who needs to emulate select these days?  */
  int ravail = 0;
   SELECT_TYPE orfds;
   int timeoutval;
@@ -2707,7 +1907,7 @@ sys_select (nfds, rfds, wfds, efds, timeout)
    waiting for at least one character.  */
 
 void
-read_input_waiting ()
+read_input_waiting (void)
 {
   /* XXX This needs to be updated for multi-tty support.  Is there
      anybody who needs to emulate select these days?  */
@@ -2769,110 +1969,23 @@ read_input_waiting ()
 #endif
 
 #endif /* not HAVE_SELECT */
-#endif /* not VMS */
 #endif /* not MSDOS */
 \f
-#ifdef BSD4_1
-void
-init_sigio (fd)
-     int fd;
-{
-  if (noninteractive)
-    return;
-  lmode = LINTRUP | lmode;
-  ioctl (fd, TIOCLSET, &lmode);
-}
-
-void
-reset_sigio (fd)
-     int fd;
-{
-  if (noninteractive)
-    return;
-  lmode = ~LINTRUP & lmode;
-  ioctl (fd, TIOCLSET, &lmode);
-}
-
-void
-request_sigio ()
-{
-  if (noninteractive)
-    return;
-  sigrelse (SIGTINT);
-
-  interrupts_deferred = 0;
-}
-
-void
-unrequest_sigio ()
-{
-  if (noninteractive)
-    return;
-  sighold (SIGTINT);
-
-  interrupts_deferred = 1;
-}
-
-/* still inside #ifdef BSD4_1 */
-#ifdef subprocesses
-
-int sigheld; /* Mask of held signals */
-
-void
-sigholdx (signum)
-     int signum;
-{
-  sigheld |= sigbit (signum);
-  sighold (signum);
-}
-
-void
-sigisheld (signum)
-     int signum;
-{
-  sigheld |= sigbit (signum);
-}
-
-void
-sigunhold (signum)
-     int signum;
-{
-  sigheld &= ~sigbit (signum);
-  sigrelse (signum);
-}
-
-void
-sigfree ()    /* Free all held signals */
-{
-  int i;
-  for (i = 0; i < NSIG; i++)
-    if (sigheld & sigbit (i))
-      sigrelse (i);
-  sigheld = 0;
-}
-
-int
-sigbit (i)
-{
-  return 1 << (i - 1);
-}
-#endif /* subprocesses */
-#endif /* BSD4_1 */
-\f
 /* POSIX signals support - DJB */
 /* Anyone with POSIX signals should have ANSI C declarations */
 
-#ifdef POSIX_SIGNALS
-
 sigset_t empty_mask, full_mask;
 
+#ifndef WINDOWSNT
+
 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;
-#if defined (SA_RESTART) && ! defined (BROKEN_SA_RESTART) && !defined(SYNC_INPUT)
+  new_action.sa_flags = 0;
+#if defined (SA_RESTART)
   /* Emacs mostly works better with restartable system services. If this
      flag exists, we probably want to turn it on here.
      However, on some systems this resets the timeout of `select'
@@ -2882,14 +1995,19 @@ sys_signal (int signal_number, signal_handler_t action)
      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;
+  /* Non-interactive keyboard input goes through stdio, where we always
+     want restartable system calls.  */
+# if defined (BROKEN_SA_RESTART) || defined(SYNC_INPUT)
+  if (noninteractive)
+# endif
+    new_action.sa_flags = SA_RESTART;
 #endif
   sigaction (signal_number, &new_action, &old_action);
   return (old_action.sa_handler);
 }
 
+#endif /* WINDOWSNT */
+
 #ifndef __GNUC__
 /* If we're compiling with GCC, we don't need this function, since it
    can be written as a macro.  */
@@ -2932,7 +2050,6 @@ sys_sigsetmask (sigset_t new_mask)
   return (old_mask);
 }
 
-#endif /* POSIX_SIGNALS */
 \f
 #if !defined HAVE_STRSIGNAL && !HAVE_DECL_SYS_SIGLIST
 static char *my_sys_siglist[NSIG];
@@ -2943,12 +2060,10 @@ static char *my_sys_siglist[NSIG];
 #endif
 
 void
-init_signals ()
+init_signals (void)
 {
-#ifdef POSIX_SIGNALS
   sigemptyset (&empty_mask);
   sigfillset (&full_mask);
-#endif
 
 #if !defined HAVE_STRSIGNAL && !HAVE_DECL_SYS_SIGLIST
   if (! initialized)
@@ -3151,8 +2266,7 @@ init_signals ()
 #endif /* !RAND_BITS */
 
 void
-seed_random (arg)
-     long arg;
+seed_random (long int arg)
 {
 #ifdef HAVE_RANDOM
   srandom ((unsigned int)arg);
@@ -3170,7 +2284,7 @@ seed_random (arg)
  * This suffices even for a 64-bit architecture with a 15-bit rand.
  */
 long
-get_random ()
+get_random (void)
 {
   long val = random ();
 #if VALBITS > RAND_BITS
@@ -3187,112 +2301,6 @@ get_random ()
 #endif /* need at least 2 */
   return val & ((1L << VALBITS) - 1);
 }
-\f
-#ifdef VMS
-
-#ifdef getenv
-/* If any place else asks for the TERM variable,
-   allow it to be overridden with the EMACS_TERM variable
-   before attempting to translate the logical name TERM.  As a last
-   resort, ask for VAX C's special idea of the TERM variable.  */
-#undef getenv
-char *
-sys_getenv (name)
-     char *name;
-{
-  register char *val;
-  static char buf[256];
-  static struct dsc$descriptor_s equiv
-    = {sizeof (buf), DSC$K_DTYPE_T, DSC$K_CLASS_S, buf};
-  static struct dsc$descriptor_s d_name
-    = {0, DSC$K_DTYPE_T, DSC$K_CLASS_S, 0};
-  short eqlen;
-
-  if (!strcmp (name, "TERM"))
-    {
-      val = (char *) getenv ("EMACS_TERM");
-      if (val)
-       return val;
-    }
-
-  d_name.dsc$w_length = strlen (name);
-  d_name.dsc$a_pointer = name;
-  if (LIB$SYS_TRNLOG (&d_name, &eqlen, &equiv) == 1)
-    {
-      char *str = (char *) xmalloc (eqlen + 1);
-      bcopy (buf, str, eqlen);
-      str[eqlen] = '\0';
-      /* This is a storage leak, but a pain to fix.  With luck,
-        no one will ever notice.  */
-      return str;
-    }
-  return (char *) getenv (name);
-}
-#endif /* getenv */
-
-#ifdef abort
-/* Since VMS doesn't believe in core dumps, the only way to debug this beast is
-   to force a call on the debugger from within the image. */
-#undef abort
-sys_abort ()
-{
-  reset_all_sys_modes ();
-  LIB$SIGNAL (SS$_DEBUG);
-}
-#endif /* abort */
-#endif /* VMS */
-\f
-#ifdef VMS
-#ifdef LINK_CRTL_SHARE
-#ifdef SHARABLE_LIB_BUG
-/* Variables declared noshare and initialized in sharable libraries
-   cannot be shared.  The VMS linker incorrectly forces you to use a private
-   version which is uninitialized... If not for this "feature", we
-   could use the C library definition of sys_nerr and sys_errlist. */
-int sys_nerr = 35;
-char *sys_errlist[] =
-  {
-    "error 0",
-    "not owner",
-    "no such file or directory",
-    "no such process",
-    "interrupted system call",
-    "i/o error",
-    "no such device or address",
-    "argument list too long",
-    "exec format error",
-    "bad file number",
-    "no child process",
-    "no more processes",
-    "not enough memory",
-    "permission denied",
-    "bad address",
-    "block device required",
-    "mount devices busy",
-    "file exists",
-    "cross-device link",
-    "no such device",
-    "not a directory",
-    "is a directory",
-    "invalid argument",
-    "file table overflow",
-    "too many open files",
-    "not a typewriter",
-    "text file busy",
-    "file too big",
-    "no space left on device",
-    "illegal seek",
-    "read-only file system",
-    "too many links",
-    "broken pipe",
-    "math argument",
-    "result too large",
-    "I/O stream empty",
-    "vax/vms specific error code nontranslatable error"
-  };
-#endif /* SHARABLE_LIB_BUG */
-#endif /* LINK_CRTL_SHARE */
-#endif /* VMS */
 
 #ifndef HAVE_STRERROR
 #ifndef WINDOWSNT
@@ -3311,17 +2319,10 @@ strerror (errnum)
 #endif /* ! HAVE_STRERROR */
 \f
 int
-emacs_open (path, oflag, mode)
-     const char *path;
-     int oflag, mode;
+emacs_open (const char *path, int oflag, int mode)
 {
   register int rtnval;
 
-#ifdef BSD4_1
-  if (oflag & O_CREAT)
-    return creat (path, mode);
-#endif
-
   while ((rtnval = open (path, oflag, mode)) == -1
         && (errno == EINTR))
     QUIT;
@@ -3329,21 +2330,11 @@ emacs_open (path, oflag, mode)
 }
 
 int
-emacs_close (fd)
-     int fd;
+emacs_close (int fd)
 {
   int did_retry = 0;
   register int rtnval;
 
-#if defined (MAC_OSX) && defined (HAVE_CARBON)
-  {
-    extern int mac_try_close_socket P_ ((int));
-
-    if (mac_try_close_socket (fd))
-      return 0;
-  }
-#endif
-
   while ((rtnval = close (fd)) == -1
         && (errno == EINTR))
     did_retry = 1;
@@ -3358,10 +2349,7 @@ emacs_close (fd)
 }
 
 int
-emacs_read (fildes, buf, nbyte)
-     int fildes;
-     char *buf;
-     unsigned int nbyte;
+emacs_read (int fildes, char *buf, unsigned int nbyte)
 {
   register int rtnval;
 
@@ -3372,10 +2360,7 @@ emacs_read (fildes, buf, nbyte)
 }
 
 int
-emacs_write (fildes, buf, nbyte)
-     int fildes;
-     const char *buf;
-     unsigned int nbyte;
+emacs_write (int fildes, const char *buf, unsigned int nbyte)
 {
   register int rtnval, bytes_written;
 
@@ -3392,10 +2377,7 @@ emacs_write (fildes, buf, nbyte)
 #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 ();
-              if (pending_atimers)
-                do_pending_atimers ();
+             process_pending_signals ();
 #endif
              continue;
            }
@@ -3439,11 +2421,10 @@ emacs_write (fildes, buf, nbyte)
 #ifndef HAVE_GETWD
 
 char *
-getwd (pathname)
-     char *pathname;
+getwd (char *pathname)
 {
   char *npath, *spath;
-  extern char *getcwd ();
+  extern char *getcwd (char *, size_t);
 
   BLOCK_INPUT;                 /* getcwd uses malloc */
   spath = npath = getcwd ((char *) 0, MAXPATHLEN);
@@ -3472,9 +2453,8 @@ getwd (pathname)
 
 #ifndef HAVE_RENAME
 
-rename (from, to)
-     const char *from;
-     const char *to;
+int
+rename (const char *from, const char *to)
 {
   if (access (from, 0) == 0)
     {
@@ -3489,18 +2469,16 @@ rename (from, to)
 #endif
 
 
-#ifdef HPUX
-#ifndef HAVE_PERROR
+#if defined(HPUX) && !defined(HAVE_PERROR)
 
 /* HPUX curses library references perror, but as far as we know
    it won't be called.  Anyway this definition will do for now.  */
 
-perror ()
+void
+perror (void)
 {
 }
-
-#endif /* not HAVE_PERROR */
-#endif /* HPUX */
+#endif /* HPUX and not HAVE_PERROR */
 
 #ifndef HAVE_DUP2
 
@@ -3510,9 +2488,8 @@ perror ()
  *     until we are, then close the unsuccessful ones.
  */
 
-dup2 (oldd, newd)
-     int oldd;
-     int newd;
+int
+dup2 (int oldd, int newd)
 {
   register int fd, ret;
 
@@ -3541,17 +2518,14 @@ dup2 (oldd, newd)
  */
 
 #ifdef subprocesses
-#ifndef VMS
 #ifndef HAVE_GETTIMEOFDAY
 #ifdef HAVE_TIMEVAL
 
 /* ARGSUSED */
 int
-gettimeofday (tp, tzp)
-     struct timeval *tp;
-     struct timezone *tzp;
+gettimeofday (struct timeval *tp, struct timezone *tzp)
 {
-  extern long time ();
+  extern long time (long);
 
   tp->tv_sec = time ((long *)0);
   tp->tv_usec = 0;
@@ -3562,16 +2536,14 @@ gettimeofday (tp, tzp)
 
 #endif
 #endif
-#endif
-#endif /* subprocess && !HAVE_GETTIMEOFDAY && HAVE_TIMEVAL && !VMS */
+#endif /* subprocess && !HAVE_GETTIMEOFDAY && HAVE_TIMEVAL */
 
 /*
  *     This function will go away as soon as all the stubs fixed. (fnf)
  */
 
 void
-croak (badfunc)
-     char *badfunc;
+croak (char *badfunc)
 {
   printf ("%s not yet implemented\r\n", badfunc);
   reset_all_sys_modes ();
@@ -3586,178 +2558,24 @@ croak (badfunc)
 
 #include <dirent.h>
 
-#if defined (BROKEN_CLOSEDIR) || !defined (HAVE_CLOSEDIR)
+#if !defined (HAVE_CLOSEDIR)
 
 int
-closedir (dirp)
-     register DIR *dirp;              /* stream from opendir */
+closedir (DIR *dirp /* stream from opendir */)
 {
   int rtnval;
 
   rtnval = emacs_close (dirp->dd_fd);
-
-  /* Some systems (like Solaris) allocate the buffer and the DIR all
-     in one block.  Why in the world are we freeing this ourselves
-     anyway?  */
-#if ! (defined (sun) && defined (USG5_4))
-  xfree ((char *) dirp->dd_buf); /* directory block defined in <dirent.h> */
-#endif
   xfree ((char *) dirp);
 
   return rtnval;
 }
-#endif /* BROKEN_CLOSEDIR or not HAVE_CLOSEDIR */
+#endif /* not HAVE_CLOSEDIR */
 #endif /* SYSV_SYSTEM_DIR */
 
-#ifdef NONSYSTEM_DIR_LIBRARY
-
-DIR *
-opendir (filename)
-     char *filename;   /* name of directory */
-{
-  register DIR *dirp;          /* -> malloc'ed storage */
-  register int fd;             /* file descriptor for read */
-  struct stat sbuf;            /* result of fstat */
-
-  fd = emacs_open (filename, O_RDONLY, 0);
-  if (fd < 0)
-    return 0;
-
-  BLOCK_INPUT;
-  if (fstat (fd, &sbuf) < 0
-      || (sbuf.st_mode & S_IFMT) != S_IFDIR
-      || (dirp = (DIR *) xmalloc (sizeof (DIR))) == 0)
-    {
-      emacs_close (fd);
-      UNBLOCK_INPUT;
-      return 0;                /* bad luck today */
-    }
-  UNBLOCK_INPUT;
-
-  dirp->dd_fd = fd;
-  dirp->dd_loc = dirp->dd_size = 0;    /* refill needed */
-
-  return dirp;
-}
-
-void
-closedir (dirp)
-     register DIR *dirp;               /* stream from opendir */
-{
-  emacs_close (dirp->dd_fd);
-  xfree ((char *) dirp);
-}
-
-
-#ifndef VMS
-#define DIRSIZ 14
-struct olddir
-  {
-    ino_t od_ino;              /* inode */
-    char od_name[DIRSIZ];      /* filename */
-  };
-#endif /* not VMS */
-
-struct direct dir_static;      /* simulated directory contents */
-
-/* ARGUSED */
-struct direct *
-readdir (dirp)
-     register DIR *dirp;       /* stream from opendir */
-{
-#ifndef VMS
-  register struct olddir *dp;  /* -> directory data */
-#else /* VMS */
-  register struct dir$_name *dp; /* -> directory data */
-  register struct dir$_version *dv; /* -> version data */
-#endif /* VMS */
-
-  for (; ;)
-    {
-      if (dirp->dd_loc >= dirp->dd_size)
-       dirp->dd_loc = dirp->dd_size = 0;
-
-      if (dirp->dd_size == 0   /* refill buffer */
-         && (dirp->dd_size = emacs_read (dirp->dd_fd, dirp->dd_buf, DIRBLKSIZ)) <= 0)
-       return 0;
-
-#ifndef VMS
-      dp = (struct olddir *) &dirp->dd_buf[dirp->dd_loc];
-      dirp->dd_loc += sizeof (struct olddir);
-
-      if (dp->od_ino != 0)     /* not deleted entry */
-       {
-         dir_static.d_ino = dp->od_ino;
-         strncpy (dir_static.d_name, dp->od_name, DIRSIZ);
-         dir_static.d_name[DIRSIZ] = '\0';
-         dir_static.d_namlen = strlen (dir_static.d_name);
-         dir_static.d_reclen = sizeof (struct direct)
-           - MAXNAMLEN + 3
-             + dir_static.d_namlen - dir_static.d_namlen % 4;
-         return &dir_static;   /* -> simulated structure */
-       }
-#else /* VMS */
-      dp = (struct dir$_name *) dirp->dd_buf;
-      if (dirp->dd_loc == 0)
-       dirp->dd_loc = (dp->dir$b_namecount&1) ? dp->dir$b_namecount + 1
-         : dp->dir$b_namecount;
-      dv = (struct dir$_version *)&dp->dir$t_name[dirp->dd_loc];
-      dir_static.d_ino = dv->dir$w_fid_num;
-      dir_static.d_namlen = dp->dir$b_namecount;
-      dir_static.d_reclen = sizeof (struct direct)
-       - MAXNAMLEN + 3
-         + dir_static.d_namlen - dir_static.d_namlen % 4;
-      strncpy (dir_static.d_name, dp->dir$t_name, dp->dir$b_namecount);
-      dir_static.d_name[dir_static.d_namlen] = '\0';
-      dirp->dd_loc = dirp->dd_size; /* only one record at a time */
-      return &dir_static;
-#endif /* VMS */
-    }
-}
-
-#ifdef VMS
-/* readdirver is just like readdir except it returns all versions of a file
-   as separate entries.  */
-
-/* ARGUSED */
-struct direct *
-readdirver (dirp)
-     register DIR *dirp;       /* stream from opendir */
-{
-  register struct dir$_name *dp; /* -> directory data */
-  register struct dir$_version *dv; /* -> version data */
-
-  if (dirp->dd_loc >= dirp->dd_size - sizeof (struct dir$_name))
-    dirp->dd_loc = dirp->dd_size = 0;
-
-  if (dirp->dd_size == 0       /* refill buffer */
-      && (dirp->dd_size = sys_read (dirp->dd_fd, dirp->dd_buf, DIRBLKSIZ)) <= 0)
-    return 0;
-
-  dp = (struct dir$_name *) dirp->dd_buf;
-  if (dirp->dd_loc == 0)
-    dirp->dd_loc = (dp->dir$b_namecount & 1) ? dp->dir$b_namecount + 1
-                  : dp->dir$b_namecount;
-  dv = (struct dir$_version *) &dp->dir$t_name[dirp->dd_loc];
-  strncpy (dir_static.d_name, dp->dir$t_name, dp->dir$b_namecount);
-  sprintf (&dir_static.d_name[dp->dir$b_namecount], ";%d", dv->dir$w_version);
-  dir_static.d_namlen = strlen (dir_static.d_name);
-  dir_static.d_ino = dv->dir$w_fid_num;
-  dir_static.d_reclen = sizeof (struct direct) - MAXNAMLEN + 3
-                       + dir_static.d_namlen - dir_static.d_namlen % 4;
-  dirp->dd_loc = ((char *) (++dv) - dp->dir$t_name);
-  return &dir_static;
-}
-
-#endif /* VMS */
-
-#endif /* NONSYSTEM_DIR_LIBRARY */
-
 \f
 int
-set_file_times (filename, atime, mtime)
-     const char *filename;
-     EMACS_TIME atime, mtime;
+set_file_times (const char *filename, EMACS_TIME atime, EMACS_TIME mtime)
 {
 #ifdef HAVE_UTIMES
   struct timeval tv[2];
@@ -3793,14 +2611,8 @@ set_file_times (filename, atime, mtime)
 /*
  * Make a directory.
  */
-#ifdef MKDIR_PROTOTYPE
-MKDIR_PROTOTYPE
-#else
 int
-mkdir (dpath, dmode)
-     char *dpath;
-     int dmode;
-#endif
+mkdir (char *dpath, int dmode)
 {
   int cpid, status, fd;
   struct stat statbuf;
@@ -3858,8 +2670,7 @@ mkdir (dpath, dmode)
 
 #ifndef HAVE_RMDIR
 int
-rmdir (dpath)
-     char *dpath;
+rmdir (char *dpath)
 {
   int cpid, status, fd;
   struct stat statbuf;
@@ -3903,1477 +2714,887 @@ rmdir (dpath)
 }
 #endif /* !HAVE_RMDIR */
 
-
 \f
-/* Functions for VMS */
-#ifdef VMS
-#include <acldef.h>
-#include <chpdef.h>
-#include <jpidef.h>
-
-/* Return as a string the VMS error string pertaining to STATUS.
-   Reuses the same static buffer each time it is called.  */
-
-char *
-vmserrstr (status)
-     int status;               /* VMS status code */
-{
-  int bufadr[2];
-  short len;
-  static char buf[257];
-
-  bufadr[0] = sizeof buf - 1;
-  bufadr[1] = (int) buf;
-  if (! (SYS$GETMSG (status, &len, bufadr, 0x1, 0) & 1))
-    return "untranslatable VMS error status";
-  buf[len] = '\0';
-  return buf;
-}
-
-#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.)
- */
-
-#ifdef VMS4_4
-
-#define DESCRIPTOR(name,string) struct dsc$descriptor_s name = \
-       { strlen (string), DSC$K_DTYPE_T, DSC$K_CLASS_S, string }
-
-typedef union {
-    struct {
-       unsigned short s_buflen;
-       unsigned short s_code;
-       char *s_bufadr;
-       unsigned short *s_retlenadr;
-    } s;
-    int end;
-} item;
-#define buflen s.s_buflen
-#define code s.s_code
-#define bufadr s.s_bufadr
-#define retlenadr s.s_retlenadr
-
-#define R_OK 4 /* test for read permission */
-#define W_OK 2 /* test for write permission */
-#define X_OK 1 /* test for execute (search) permission */
-#define F_OK 0 /* test for presence of file */
-
-int
-sys_access (path, mode)
-     char *path;
-     int mode;
+#ifndef HAVE_MEMSET
+void *
+memset (void *b, int n, size_t length)
 {
-  static char *user = NULL;
-  char dir_fn[512];
-
-  /* translate possible directory spec into .DIR file name, so brain-dead
-   * 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)
-    return -1;
-  {
-    int stat;
-    int flags;
-    int acces;
-    unsigned short int dummy;
-    item itemlst[3];
-    static int constant = ACL$C_FILE;
-    DESCRIPTOR (path_desc, path);
-    DESCRIPTOR (user_desc, user);
-
-    flags = 0;
-    acces = 0;
-    if ((mode & X_OK) && ((stat = access (path, mode)) < 0 || mode == X_OK))
-      return stat;
-    if (mode & R_OK)
-      acces |= CHP$M_READ;
-    if (mode & W_OK)
-      acces |= CHP$M_WRITE;
-    itemlst[0].buflen = sizeof (int);
-    itemlst[0].code = CHP$_FLAGS;
-    itemlst[0].bufadr = (char *) &flags;
-    itemlst[0].retlenadr = &dummy;
-    itemlst[1].buflen = sizeof (int);
-    itemlst[1].code = CHP$_ACCESS;
-    itemlst[1].bufadr = (char *) &acces;
-    itemlst[1].retlenadr = &dummy;
-    itemlst[2].end = CHP$_END;
-    stat = SYS$CHECK_ACCESS (&constant, &path_desc, &user_desc, itemlst);
-    return stat == SS$_NORMAL ? 0 : -1;
-  }
+  unsigned char *p = b;
+  while (length-- > 0)
+    *p++ = n;
+  return b;
 }
+#endif /* !HAVE_MEMSET */
 
-#else /* not VMS4_4 */
-
-#include <prvdef.h>
-#define ACE$M_WRITE     2
-#define ACE$C_KEYID     1
-
-static unsigned short memid, grpid;
-static unsigned int uic;
-
-/* Called from init_sys_modes, so it happens not very often
-   but at least each time Emacs is loaded.  */
-void
-sys_access_reinit ()
+#ifndef HAVE_MEMCPY
+void *
+memcpy (void *b1, void *b2, size_t length)
 {
-  uic = 0;
+  unsigned char *p1 = b1, *p2 = b2;
+  while (length-- > 0)
+    *p1++ = *p2++;
+  return b1;
 }
+#endif /* !HAVE_MEMCPY */
 
-int
-sys_access (filename, type)
-     char * filename;
-     int type;
+#ifndef HAVE_MEMMOVE
+void *
+memmove (void *b1, void *b2, size_t length)
 {
-  struct FAB fab;
-  struct XABPRO xab;
-  int status, size, i, typecode, acl_controlled;
-  unsigned int *aclptr, *aclend, aclbuf[60];
-  union prvdef prvmask;
-
-  /* Get UIC and GRP values for protection checking.  */
-  if (uic == 0)
-    {
-      status = LIB$GETJPI (&JPI$_UIC, 0, 0, &uic, 0, 0);
-      if (! (status & 1))
-       return -1;
-      memid = uic & 0xFFFF;
-      grpid = uic >> 16;
-    }
-
-  if (type != 2)                /* not checking write access */
-    return access (filename, type);
-
-  /* Check write protection. */
-
-#define CHECKPRIV(bit)    (prvmask.bit)
-#define WRITABLE(field)  (! ((xab.xab$w_pro >> field) & XAB$M_NOWRITE))
-
-  /* Find privilege bits */
-  status = SYS$SETPRV (0, 0, 0, prvmask);
-  if (! (status & 1))
-    error ("Unable to find privileges: %s", vmserrstr (status));
-  if (CHECKPRIV (PRV$V_BYPASS))
-    return 0;                  /* BYPASS enabled */
-  fab = cc$rms_fab;
-  fab.fab$b_fac = FAB$M_GET;
-  fab.fab$l_fna = filename;
-  fab.fab$b_fns = strlen (filename);
-  fab.fab$l_xab = &xab;
-  xab = cc$rms_xabpro;
-  xab.xab$l_aclbuf = aclbuf;
-  xab.xab$w_aclsiz = sizeof (aclbuf);
-  status = SYS$OPEN (&fab, 0, 0);
-  if (! (status & 1))
-    return -1;
-  SYS$CLOSE (&fab, 0, 0);
-  /* Check system access */
-  if (CHECKPRIV (PRV$V_SYSPRV) && WRITABLE (XAB$V_SYS))
-    return 0;
-  /* Check ACL entries, if any */
-  acl_controlled = 0;
-  if (xab.xab$w_acllen > 0)
+  unsigned char *p1 = b1, *p2 = b2;
+  if (p1 < p2 || p1 >= p2 + length)
+    while (length-- > 0)
+      *p1++ = *p2++;
+  else
     {
-      aclptr = aclbuf;
-      aclend = &aclbuf[xab.xab$w_acllen / 4];
-      while (*aclptr && aclptr < aclend)
-       {
-         size = (*aclptr & 0xff) / 4;
-         typecode = (*aclptr >> 8) & 0xff;
-         if (typecode == ACE$C_KEYID)
-           for (i = size - 1; i > 1; i--)
-             if (aclptr[i] == uic)
-               {
-                 acl_controlled = 1;
-                 if (aclptr[1] & ACE$M_WRITE)
-                   return 0;   /* Write access through ACL */
-               }
-         aclptr = &aclptr[size];
-       }
-      if (acl_controlled)      /* ACL specified, prohibits write access */
-       return -1;
+      p1 += length;
+      p2 += length;
+      while (length-- > 0)
+       *--p1 = *--p2;
     }
-  /* No ACL entries specified, check normal protection */
-  if (WRITABLE (XAB$V_WLD))    /* World writable */
-    return 0;
-  if (WRITABLE (XAB$V_GRP) &&
-      (unsigned short) (xab.xab$l_uic >> 16) == grpid)
-    return 0;                  /* Group writable */
-  if (WRITABLE (XAB$V_OWN) &&
-      (xab.xab$l_uic & 0xFFFF) == memid)
-    return 0;                  /* Owner writable */
-
-  return -1;   /* Not writable */
+  return b1;
 }
-#endif /* not VMS4_4 */
-#endif /* access */
+#endif /* !HAVE_MEMCPY */
 
-static char vtbuf[NAM$C_MAXRSS+1];
-
-/* translate a vms file spec to a unix path */
-char *
-sys_translate_vms (vfile)
-     char * vfile;
+#ifndef HAVE_MEMCMP
+int
+memcmp (void *b1, void *b2, size_t length)
 {
-  char * p;
-  char * targ;
-
-  if (!vfile)
-    return 0;
-
-  targ = vtbuf;
-
-  /* leading device or logical name is a root directory */
-  if (p = strchr (vfile, ':'))
-    {
-      *targ++ = '/';
-      while (vfile < p)
-       *targ++ = *vfile++;
-      vfile++;
-      *targ++ = '/';
-    }
-  p = vfile;
-  if (*p == '[' || *p == '<')
-    {
-      while (*++vfile != *p + 2)
-       switch (*vfile)
-         {
-         case '.':
-           if (vfile[-1] == *p)
-             *targ++ = '.';
-           *targ++ = '/';
-           break;
-
-         case '-':
-           *targ++ = '.';
-           *targ++ = '.';
-           break;
-
-         default:
-           *targ++ = *vfile;
-           break;
-         }
-      vfile++;
-      *targ++ = '/';
-    }
-  while (*vfile)
-    *targ++ = *vfile++;
-
-  return vtbuf;
+  unsigned char *p1 = b1, *p2 = b2;
+  while (length-- > 0)
+    if (*p1++ != *p2++)
+      return p1[-1] < p2[-1] ? -1 : 1;
+  return 0;
 }
-
-static char utbuf[NAM$C_MAXRSS+1];
-
-/* translate a unix path to a VMS file spec */
+#endif /* !HAVE_MEMCMP */
+\f
+#ifndef HAVE_STRSIGNAL
 char *
-sys_translate_unix (ufile)
-     char * ufile;
+strsignal (int code)
 {
-  int slash_seen = 0;
-  char *p;
-  char * targ;
-
-  if (!ufile)
-    return 0;
-
-  targ = utbuf;
-
-  if (*ufile == '/')
-    {
-      ufile++;
-    }
+  char *signame = 0;
 
-  while (*ufile)
+  if (0 <= code && code < NSIG)
     {
-      switch (*ufile)
-       {
-       case '/':
-         if (slash_seen)
-           if (index (&ufile[1], '/'))
-             *targ++ = '.';
-           else
-             *targ++ = ']';
-         else
-           {
-             *targ++ = ':';
-             if (index (&ufile[1], '/'))
-               *targ++ = '[';
-             slash_seen = 1;
-           }
-         break;
-
-       case '.':
-         if (strncmp (ufile, "./", 2) == 0)
-           {
-             if (!slash_seen)
-               {
-                 *targ++ = '[';
-                 slash_seen = 1;
-               }
-             ufile++;          /* skip the dot */
-             if (index (&ufile[1], '/'))
-               *targ++ = '.';
-             else
-               *targ++ = ']';
-           }
-         else if (strncmp (ufile, "../", 3) == 0)
-           {
-             if (!slash_seen)
-               {
-                 *targ++ = '[';
-                 slash_seen = 1;
-               }
-             *targ++ = '-';
-             ufile += 2;       /* skip the dots */
-             if (index (&ufile[1], '/'))
-               *targ++ = '.';
-             else
-               *targ++ = ']';
-           }
-         else
-           *targ++ = *ufile;
-         break;
-
-       default:
-         *targ++ = *ufile;
-         break;
-       }
-      ufile++;
+      /* Cast to suppress warning if the table has const char *.  */
+      signame = (char *) sys_siglist[code];
     }
-  *targ = '\0';
 
-  return utbuf;
+  return signame;
 }
-
-char *
-getwd (pathname)
-     char *pathname;
+#endif /* HAVE_STRSIGNAL */
+\f
+#ifdef HAVE_TERMIOS
+/* For make-serial-process  */
+int
+serial_open (char *port)
 {
-  char *ptr, *val;
-  extern char *getcwd ();
-
-#define MAXPATHLEN 1024
+  int fd = -1;
 
-  ptr = xmalloc (MAXPATHLEN);
-  val = getcwd (ptr, MAXPATHLEN);
-  if (val == 0)
+  fd = emacs_open ((char*) port,
+                  O_RDWR
+#ifdef O_NONBLOCK
+                  | O_NONBLOCK
+#else
+                  | O_NDELAY
+#endif
+#ifdef O_NOCTTY
+                  | O_NOCTTY
+#endif
+                  , 0);
+  if (fd < 0)
     {
-      xfree (ptr);
-      return val;
+      error ("Could not open %s: %s",
+            port, emacs_strerror (errno));
     }
-  strcpy (pathname, ptr);
-  xfree (ptr);
+#ifdef TIOCEXCL
+  ioctl (fd, TIOCEXCL, (char *) 0);
+#endif
 
return pathname;
 return fd;
 }
+#endif /* TERMIOS  */
 
-int
-getppid ()
-{
-  long item_code = JPI$_OWNER;
-  unsigned long parent_id;
-  int status;
-
-  if (((status = LIB$GETJPI (&item_code, 0, 0, &parent_id)) & 1) == 0)
-    {
-      errno = EVMSERR;
-      vaxc$errno = status;
-      return -1;
-    }
-  return parent_id;
-}
+#ifdef HAVE_TERMIOS
 
-#undef getuid
-unsigned
-sys_getuid ()
+#if !defined (HAVE_CFMAKERAW)
+/* Workaround for targets which are missing cfmakeraw.  */
+/* Pasted from man page.  */
+static void
+cfmakeraw (struct termios *termios_p)
 {
-  return (getgid () << 16) | getuid ();
+    termios_p->c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
+    termios_p->c_oflag &= ~OPOST;
+    termios_p->c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
+    termios_p->c_cflag &= ~(CSIZE|PARENB);
+    termios_p->c_cflag |= CS8;
 }
+#endif /* !defined (HAVE_CFMAKERAW */
 
-#undef read
-int
-sys_read (fildes, buf, nbyte)
-     int fildes;
-     char *buf;
-     unsigned int nbyte;
+#if !defined (HAVE_CFSETSPEED)
+/* Workaround for targets which are missing cfsetspeed.  */
+static int
+cfsetspeed (struct termios *termios_p, speed_t vitesse)
 {
-  return read (fildes, buf, (nbyte < MAXIOSIZE ? nbyte : MAXIOSIZE));
+  return (cfsetispeed (termios_p, vitesse)
+         + cfsetospeed (termios_p, vitesse));
 }
+#endif
 
-#if 0
-int
-sys_write (fildes, buf, nbyte)
-     int fildes;
-     char *buf;
-     unsigned int nbyte;
+/* For serial-process-configure  */
+void
+serial_configure (struct Lisp_Process *p,
+                 Lisp_Object contact)
 {
-  register int nwrote, rtnval = 0;
+  Lisp_Object childp2 = Qnil;
+  Lisp_Object tem = Qnil;
+  struct termios attr;
+  int err = -1;
+  char summary[4] = "???"; /* This usually becomes "8N1".  */
 
-  while (nbyte > MAXIOSIZE && (nwrote = write (fildes, buf, MAXIOSIZE)) > 0) {
-    nbyte -= nwrote;
-    buf += nwrote;
-    rtnval += nwrote;
-  }
-  if (nwrote < 0)
-    return rtnval ? rtnval : -1;
-  if ((nwrote = write (fildes, buf, nbyte)) < 0)
-    return rtnval ? rtnval : -1;
-  return (rtnval + nwrote);
-}
-#endif /* 0 */
+  childp2 = Fcopy_sequence (p->childp);
 
-/*
- *     VAX/VMS VAX C RTL really loses. It insists that records
- *      end with a newline (carriage return) character, and if they
- *     don't it adds one (nice of it isn't it!)
- *
- *     Thus we do this stupidity below.
- */
+  /* Read port attributes and prepare default configuration.  */
+  err = tcgetattr (p->outfd, &attr);
+  if (err != 0)
+    error ("tcgetattr() failed: %s", emacs_strerror (errno));
+  cfmakeraw (&attr);
+#if defined (CLOCAL)
+  attr.c_cflag |= CLOCAL;
+#endif
+#if defined (CREAD)
+  attr.c_cflag |= CREAD;
+#endif
 
-#undef write
-int
-sys_write (fildes, buf, nbytes)
-     int fildes;
-     char *buf;
-     unsigned int nbytes;
-{
-  register char *p;
-  register char *e;
-  int sum = 0;
-  struct stat st;
+  /* Configure speed.  */
+  if (!NILP (Fplist_member (contact, QCspeed)))
+    tem = Fplist_get (contact, QCspeed);
+  else
+    tem = Fplist_get (p->childp, QCspeed);
+  CHECK_NUMBER (tem);
+  err = cfsetspeed (&attr, XINT (tem));
+  if (err != 0)
+    error ("cfsetspeed(%d) failed: %s", XINT (tem), emacs_strerror (errno));
+  childp2 = Fplist_put (childp2, QCspeed, tem);
+
+  /* Configure bytesize.  */
+  if (!NILP (Fplist_member (contact, QCbytesize)))
+    tem = Fplist_get (contact, QCbytesize);
+  else
+    tem = Fplist_get (p->childp, QCbytesize);
+  if (NILP (tem))
+    tem = make_number (8);
+  CHECK_NUMBER (tem);
+  if (XINT (tem) != 7 && XINT (tem) != 8)
+    error (":bytesize must be nil (8), 7, or 8");
+  summary[0] = XINT (tem) + '0';
+#if defined (CSIZE) && defined (CS7) && defined (CS8)
+  attr.c_cflag &= ~CSIZE;
+  attr.c_cflag |= ((XINT (tem) == 7) ? CS7 : CS8);
+#else
+  /* Don't error on bytesize 8, which should be set by cfmakeraw.  */
+  if (XINT (tem) != 8)
+    error ("Bytesize cannot be changed");
+#endif
+  childp2 = Fplist_put (childp2, QCbytesize, tem);
 
-  fstat (fildes, &st);
-  p = buf;
-  while (nbytes > 0)
+  /* Configure parity.  */
+  if (!NILP (Fplist_member (contact, QCparity)))
+    tem = Fplist_get (contact, QCparity);
+  else
+    tem = Fplist_get (p->childp, QCparity);
+  if (!NILP (tem) && !EQ (tem, Qeven) && !EQ (tem, Qodd))
+    error (":parity must be nil (no parity), `even', or `odd'");
+#if defined (PARENB) && defined (PARODD) && defined (IGNPAR) && defined (INPCK)
+  attr.c_cflag &= ~(PARENB | PARODD);
+  attr.c_iflag &= ~(IGNPAR | INPCK);
+  if (NILP (tem))
     {
-      int len, retval;
-
-      /* Handle fixed-length files with carriage control.  */
-      if (st.st_fab_rfm == FAB$C_FIX
-         && ((st.st_fab_rat & (FAB$M_FTN | FAB$M_CR)) != 0))
-       {
-         len = st.st_fab_mrs;
-         retval = write (fildes, p, min (len, nbytes));
-         if (retval != len)
-           return -1;
-         retval++;     /* This skips the implied carriage control */
-       }
-      else
-       {
-         e =  p + min (MAXIOSIZE, nbytes) - 1;
-         while (*e != '\n' && e > p) e--;
-         if (p == e)           /* Ok.. so here we add a newline... sigh. */
-           e = p + min (MAXIOSIZE, nbytes) - 1;
-         len = e + 1 - p;
-         retval = write (fildes, p, len);
-         if (retval != len)
-           return -1;
-       }
-      p += retval;
-      sum += retval;
-      nbytes -= retval;
+      summary[1] = 'N';
     }
-  return sum;
-}
-
-/* Create file NEW copying its attributes from file OLD.  If
-   OLD is 0 or does not exist, create based on the value of
-   vms_stmlf_recfm. */
-
-/* Protection value the file should ultimately have.
-   Set by create_copy_attrs, and use by rename_sansversions.  */
-static unsigned short int fab_final_pro;
-
-int
-creat_copy_attrs (old, new)
-     char *old, *new;
-{
-  struct FAB fab = cc$rms_fab;
-  struct XABPRO xabpro;
-  char aclbuf[256];    /* Choice of size is arbitrary.  See below. */
-  extern int vms_stmlf_recfm;
-
-  if (old)
+  else if (EQ (tem, Qeven))
     {
-      fab.fab$b_fac = FAB$M_GET;
-      fab.fab$l_fna = old;
-      fab.fab$b_fns = strlen (old);
-      fab.fab$l_xab = (char *) &xabpro;
-      xabpro = cc$rms_xabpro;
-      xabpro.xab$l_aclbuf = aclbuf;
-      xabpro.xab$w_aclsiz = sizeof aclbuf;
-      /* Call $OPEN to fill in the fab & xabpro fields. */
-      if (SYS$OPEN (&fab, 0, 0) & 1)
-       {
-         SYS$CLOSE (&fab, 0, 0);
-         fab.fab$l_alq = 0;    /* zero the allocation quantity */
-         if (xabpro.xab$w_acllen > 0)
-           {
-             if (xabpro.xab$w_acllen > sizeof aclbuf)
-               /* If the acl buffer was too short, redo open with longer one.
-                  Wouldn't need to do this if there were some system imposed
-                  limit on the size of an ACL, but I can't find any such. */
-               {
-                 xabpro.xab$l_aclbuf = (char *) alloca (xabpro.xab$w_acllen);
-                 xabpro.xab$w_aclsiz = xabpro.xab$w_acllen;
-                 if (SYS$OPEN (&fab, 0, 0) & 1)
-                   SYS$CLOSE (&fab, 0, 0);
-                 else
-                   old = 0;
-               }
-           }
-         else
-           xabpro.xab$l_aclbuf = 0;
-       }
-      else
-       old = 0;
+      summary[1] = 'E';
+      attr.c_cflag |= PARENB;
+      attr.c_iflag |= (IGNPAR | INPCK);
     }
-  fab.fab$l_fna = new;
-  fab.fab$b_fns = strlen (new);
-  if (!old)
+  else if (EQ (tem, Qodd))
     {
-      fab.fab$l_xab = 0;
-      fab.fab$b_rfm = vms_stmlf_recfm ? FAB$C_STMLF : FAB$C_VAR;
-      fab.fab$b_rat = FAB$M_CR;
+      summary[1] = 'O';
+      attr.c_cflag |= (PARENB | PARODD);
+      attr.c_iflag |= (IGNPAR | INPCK);
     }
+#else
+  /* Don't error on no parity, which should be set by cfmakeraw.  */
+  if (!NILP (tem))
+    error ("Parity cannot be configured");
+#endif
+  childp2 = Fplist_put (childp2, QCparity, tem);
 
-  /* Set the file protections such that we will be able to manipulate
-     this file.  Once we are done writing and renaming it, we will set
-     the protections back.  */
-  if (old)
-    fab_final_pro = xabpro.xab$w_pro;
+  /* Configure stopbits.  */
+  if (!NILP (Fplist_member (contact, QCstopbits)))
+    tem = Fplist_get (contact, QCstopbits);
   else
-    SYS$SETDFPROT (0, &fab_final_pro);
-  xabpro.xab$w_pro &= 0xff0f; /* set O:rewd for now. This is set back later. */
-
-  /* Create the new file with either default attrs or attrs copied
-     from old file. */
-  if (!(SYS$CREATE (&fab, 0, 0) & 1))
-    return -1;
-  SYS$CLOSE (&fab, 0, 0);
-  /* As this is a "replacement" for creat, return a file descriptor
-     opened for writing. */
-  return open (new, O_WRONLY);
-}
+    tem = Fplist_get (p->childp, QCstopbits);
+  if (NILP (tem))
+    tem = make_number (1);
+  CHECK_NUMBER (tem);
+  if (XINT (tem) != 1 && XINT (tem) != 2)
+    error (":stopbits must be nil (1 stopbit), 1, or 2");
+  summary[2] = XINT (tem) + '0';
+#if defined (CSTOPB)
+  attr.c_cflag &= ~CSTOPB;
+  if (XINT (tem) == 2)
+    attr.c_cflag |= CSTOPB;
+#else
+  /* Don't error on 1 stopbit, which should be set by cfmakeraw.  */
+  if (XINT (tem) != 1)
+    error ("Stopbits cannot be configured");
+#endif
+  childp2 = Fplist_put (childp2, QCstopbits, tem);
 
-#ifdef creat
-#undef creat
-#include <varargs.h>
-#ifdef __GNUC__
-#ifndef va_count
-#define va_count(X) ((X) = *(((int *) &(va_alist)) - 1))
+  /* Configure flowcontrol.  */
+  if (!NILP (Fplist_member (contact, QCflowcontrol)))
+    tem = Fplist_get (contact, QCflowcontrol);
+  else
+    tem = Fplist_get (p->childp, QCflowcontrol);
+  if (!NILP (tem) && !EQ (tem, Qhw) && !EQ (tem, Qsw))
+    error (":flowcontrol must be nil (no flowcontrol), `hw', or `sw'");
+#if defined (CRTSCTS)
+  attr.c_cflag &= ~CRTSCTS;
 #endif
+#if defined (CNEW_RTSCTS)
+  attr.c_cflag &= ~CNEW_RTSCTS;
 #endif
-
-int
-sys_creat (va_alist)
-     va_dcl
-{
-  va_list list_incrementer;
-  char *name;
-  int mode;
-  int rfd;                     /* related file descriptor */
-  int fd;                      /* Our new file descriptor */
-  int count;
-  struct stat st_buf;
-  char rfm[12];
-  char rat[15];
-  char mrs[13];
-  char fsz[13];
-  extern int vms_stmlf_recfm;
-
-  va_count (count);
-  va_start (list_incrementer);
-  name = va_arg (list_incrementer, char *);
-  mode = va_arg (list_incrementer, int);
-  if (count > 2)
-    rfd = va_arg (list_incrementer, int);
-  va_end (list_incrementer);
-  if (count > 2)
+#if defined (IXON) && defined (IXOFF)
+  attr.c_iflag &= ~(IXON | IXOFF);
+#endif
+  if (NILP (tem))
     {
-      /* Use information from the related file descriptor to set record
-        format of the newly created file. */
-      fstat (rfd, &st_buf);
-      switch (st_buf.st_fab_rfm)
-       {
-       case FAB$C_FIX:
-         strcpy (rfm, "rfm = fix");
-         sprintf (mrs, "mrs = %d", st_buf.st_fab_mrs);
-         strcpy (rat, "rat = ");
-         if (st_buf.st_fab_rat & FAB$M_CR)
-           strcat (rat, "cr");
-         else if (st_buf.st_fab_rat & FAB$M_FTN)
-           strcat (rat, "ftn");
-         else if (st_buf.st_fab_rat & FAB$M_PRN)
-           strcat (rat, "prn");
-         if (st_buf.st_fab_rat & FAB$M_BLK)
-           if (st_buf.st_fab_rat & (FAB$M_CR|FAB$M_FTN|FAB$M_PRN))
-             strcat (rat, ", blk");
-           else
-             strcat (rat, "blk");
-         return creat (name, 0, rfm, rat, mrs);
-
-       case FAB$C_VFC:
-         strcpy (rfm, "rfm = vfc");
-         sprintf (fsz, "fsz = %d", st_buf.st_fab_fsz);
-         strcpy (rat, "rat = ");
-         if (st_buf.st_fab_rat & FAB$M_CR)
-           strcat (rat, "cr");
-         else if (st_buf.st_fab_rat & FAB$M_FTN)
-           strcat (rat, "ftn");
-         else if (st_buf.st_fab_rat & FAB$M_PRN)
-           strcat (rat, "prn");
-         if (st_buf.st_fab_rat & FAB$M_BLK)
-           if (st_buf.st_fab_rat & (FAB$M_CR|FAB$M_FTN|FAB$M_PRN))
-             strcat (rat, ", blk");
-           else
-             strcat (rat, "blk");
-         return creat (name, 0, rfm, rat, fsz);
-
-       case FAB$C_STM:
-         strcpy (rfm, "rfm = stm");
-         break;
-
-       case FAB$C_STMCR:
-         strcpy (rfm, "rfm = stmcr");
-         break;
-
-       case FAB$C_STMLF:
-         strcpy (rfm, "rfm = stmlf");
-         break;
-
-       case FAB$C_UDF:
-         strcpy (rfm, "rfm = udf");
-         break;
-
-       case FAB$C_VAR:
-         strcpy (rfm, "rfm = var");
-         break;
-       }
-      strcpy (rat, "rat = ");
-      if (st_buf.st_fab_rat & FAB$M_CR)
-       strcat (rat, "cr");
-      else if (st_buf.st_fab_rat & FAB$M_FTN)
-       strcat (rat, "ftn");
-      else if (st_buf.st_fab_rat & FAB$M_PRN)
-       strcat (rat, "prn");
-      if (st_buf.st_fab_rat & FAB$M_BLK)
-       if (st_buf.st_fab_rat & (FAB$M_CR|FAB$M_FTN|FAB$M_PRN))
-         strcat (rat, ", blk");
-       else
-         strcat (rat, "blk");
+      /* Already configured.  */
     }
-  else
+  else if (EQ (tem, Qhw))
     {
-      strcpy (rfm, vms_stmlf_recfm ? "rfm = stmlf" : "rfm=var");
-      strcpy (rat, "rat=cr");
+#if defined (CRTSCTS)
+      attr.c_cflag |= CRTSCTS;
+#elif defined (CNEW_RTSCTS)
+      attr.c_cflag |= CNEW_RTSCTS;
+#else
+      error ("Hardware flowcontrol (RTS/CTS) not supported");
+#endif
     }
-  /* Until the VAX C RTL fixes the many bugs with modes, always use
-     mode 0 to get the user's default protection. */
-  fd = creat (name, 0, rfm, rat);
-  if (fd < 0 && errno == EEXIST)
+  else if (EQ (tem, Qsw))
     {
-      if (unlink (name) < 0)
-       report_file_error ("delete", build_string (name));
-      fd = creat (name, 0, rfm, rat);
+#if defined (IXON) && defined (IXOFF)
+      attr.c_iflag |= (IXON | IXOFF);
+#else
+      error ("Software flowcontrol (XON/XOFF) not supported");
+#endif
     }
-  return fd;
-}
-#endif /* creat */
+  childp2 = Fplist_put (childp2, QCflowcontrol, tem);
 
-/* fwrite to stdout is S L O W.  Speed it up by using fputc...*/
-int
-sys_fwrite (ptr, size, num, fp)
-     register char * ptr;
-     FILE * fp;
-{
-  register int tot = num * size;
+  /* Activate configuration.  */
+  err = tcsetattr (p->outfd, TCSANOW, &attr);
+  if (err != 0)
+    error ("tcsetattr() failed: %s", emacs_strerror (errno));
 
-  while (tot--)
-    fputc (*ptr++, fp);
-  return num;
-}
+  childp2 = Fplist_put (childp2, QCsummary, build_string (summary));
+  p->childp = childp2;
 
-/*
- * The VMS C library routine creat actually creates a new version of an
- * existing file rather than truncating the old version.  There are times
- * 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
- * "close (creat (fn, 0));" on Unix if fn already exists.
- */
-int
-vms_truncate (fn)
-     char *fn;
-{
-  struct FAB xfab = cc$rms_fab;
-  struct RAB xrab = cc$rms_rab;
-  int status;
-
-  xfab.fab$l_fop = FAB$M_TEF;  /* free allocated but unused blocks on close */
-  xfab.fab$b_fac = FAB$M_TRN | FAB$M_GET; /* allow truncate and get access */
-  xfab.fab$b_shr = FAB$M_NIL;  /* allow no sharing - file must be locked */
-  xfab.fab$l_fna = fn;
-  xfab.fab$b_fns = strlen (fn);
-  xfab.fab$l_dna = ";0";       /* default to latest version of the file */
-  xfab.fab$b_dns = 2;
-  xrab.rab$l_fab = &xfab;
-
-  /* This gibberish opens the file, positions to the first record, and
-     deletes all records from there until the end of file. */
-  if ((SYS$OPEN (&xfab) & 01) == 01)
-    {
-      if ((SYS$CONNECT (&xrab) & 01) == 01 &&
-         (SYS$FIND (&xrab) & 01) == 01 &&
-         (SYS$TRUNCATE (&xrab) & 01) == 01)
-       status = 0;
-      else
-       status = -1;
-    }
-  else
-    status = -1;
-  SYS$CLOSE (&xfab);
-  return status;
 }
+#endif /* TERMIOS  */
+\f
+/* System depended enumeration of and access to system processes a-la ps(1).  */
 
-/* Define this symbol to actually read SYSUAF.DAT.  This requires either
-   SYSPRV or a readable SYSUAF.DAT. */
-
-#ifdef READ_SYSUAF
-/*
- * getuaf.c
- *
- * Routine to read the VMS User Authorization File and return
- * a specific user's record.
- */
+#ifdef HAVE_PROCFS
 
-static struct UAF retuaf;
+/* Process enumeration and access via /proc.  */
 
-struct UAF *
-get_uaf_name (uname)
-     char * uname;
+Lisp_Object
+list_system_processes (void)
 {
-  register status;
-  struct FAB uaf_fab;
-  struct RAB uaf_rab;
-
-  uaf_fab = cc$rms_fab;
-  uaf_rab = cc$rms_rab;
-  /* initialize fab fields */
-  uaf_fab.fab$l_fna = "SYS$SYSTEM:SYSUAF.DAT";
-  uaf_fab.fab$b_fns = 21;
-  uaf_fab.fab$b_fac = FAB$M_GET;
-  uaf_fab.fab$b_org = FAB$C_IDX;
-  uaf_fab.fab$b_shr = FAB$M_GET|FAB$M_PUT|FAB$M_UPD|FAB$M_DEL;
-  /* initialize rab fields */
-  uaf_rab.rab$l_fab = &uaf_fab;
-  /* open the User Authorization File */
-  status = SYS$OPEN (&uaf_fab);
-  if (!(status&1))
-    {
-      errno = EVMSERR;
-      vaxc$errno = status;
-      return 0;
-    }
-  status = SYS$CONNECT (&uaf_rab);
-  if (!(status&1))
-    {
-      errno = EVMSERR;
-      vaxc$errno = status;
-      return 0;
-    }
-  /* read the requested record - index is in uname */
-  uaf_rab.rab$l_kbf = uname;
-  uaf_rab.rab$b_ksz = strlen (uname);
-  uaf_rab.rab$b_rac = RAB$C_KEY;
-  uaf_rab.rab$l_ubf = (char *)&retuaf;
-  uaf_rab.rab$w_usz = sizeof retuaf;
-  status = SYS$GET (&uaf_rab);
-  if (!(status&1))
-    {
-      errno = EVMSERR;
-      vaxc$errno = status;
-      return 0;
-    }
-  /* close the User Authorization File */
-  status = SYS$DISCONNECT (&uaf_rab);
-  if (!(status&1))
-    {
-      errno = EVMSERR;
-      vaxc$errno = status;
-      return 0;
-    }
-  status = SYS$CLOSE (&uaf_fab);
-  if (!(status&1))
-    {
-      errno = EVMSERR;
-      vaxc$errno = status;
-      return 0;
-    }
-  return &retuaf;
-}
+  Lisp_Object procdir, match, proclist, next;
+  struct gcpro gcpro1, gcpro2;
+  register Lisp_Object tail;
 
-struct UAF *
-get_uaf_uic (uic)
-     unsigned long uic;
-{
-  register status;
-  struct FAB uaf_fab;
-  struct RAB uaf_rab;
-
-  uaf_fab = cc$rms_fab;
-  uaf_rab = cc$rms_rab;
-  /* initialize fab fields */
-  uaf_fab.fab$l_fna = "SYS$SYSTEM:SYSUAF.DAT";
-  uaf_fab.fab$b_fns = 21;
-  uaf_fab.fab$b_fac = FAB$M_GET;
-  uaf_fab.fab$b_org = FAB$C_IDX;
-  uaf_fab.fab$b_shr = FAB$M_GET|FAB$M_PUT|FAB$M_UPD|FAB$M_DEL;
-  /* initialize rab fields */
-  uaf_rab.rab$l_fab = &uaf_fab;
-  /* open the User Authorization File */
-  status = SYS$OPEN (&uaf_fab);
-  if (!(status&1))
-    {
-      errno = EVMSERR;
-      vaxc$errno = status;
-      return 0;
-    }
-  status = SYS$CONNECT (&uaf_rab);
-  if (!(status&1))
-    {
-      errno = EVMSERR;
-      vaxc$errno = status;
-      return 0;
-    }
-  /* read the requested record - index is in uic */
-  uaf_rab.rab$b_krf = 1;       /* 1st alternate key */
-  uaf_rab.rab$l_kbf = (char *) &uic;
-  uaf_rab.rab$b_ksz = sizeof uic;
-  uaf_rab.rab$b_rac = RAB$C_KEY;
-  uaf_rab.rab$l_ubf = (char *)&retuaf;
-  uaf_rab.rab$w_usz = sizeof retuaf;
-  status = SYS$GET (&uaf_rab);
-  if (!(status&1))
-    {
-      errno = EVMSERR;
-      vaxc$errno = status;
-      return 0;
-    }
-  /* close the User Authorization File */
-  status = SYS$DISCONNECT (&uaf_rab);
-  if (!(status&1))
-    {
-      errno = EVMSERR;
-      vaxc$errno = status;
-      return 0;
-    }
-  status = SYS$CLOSE (&uaf_fab);
-  if (!(status&1))
+  GCPRO2 (procdir, match);
+  /* For every process on the system, there's a directory in the
+     "/proc" pseudo-directory whose name is the numeric ID of that
+     process.  */
+  procdir = build_string ("/proc");
+  match = build_string ("[0-9]+");
+  proclist = directory_files_internal (procdir, Qnil, match, Qt, 0, Qnil);
+
+  /* `proclist' gives process IDs as strings.  Destructively convert
+     each string into a number.  */
+  for (tail = proclist; CONSP (tail); tail = next)
     {
-      errno = EVMSERR;
-      vaxc$errno = status;
-      return 0;
+      next = XCDR (tail);
+      XSETCAR (tail, Fstring_to_number (XCAR (tail), Qnil));
     }
-  return &retuaf;
+  UNGCPRO;
+
+  /* directory_files_internal returns the files in reverse order; undo
+     that.  */
+  proclist = Fnreverse (proclist);
+  return proclist;
 }
 
-static struct passwd retpw;
+/* The WINDOWSNT implementation is in w32.c.
+   The MSDOS implementation is in dosfns.c.  */
+#elif !defined (WINDOWSNT) && !defined (MSDOS)
 
-struct passwd *
-cnv_uaf_pw (up)
-     struct UAF * up;
+Lisp_Object
+list_system_processes (void)
 {
-  char * ptr;
-
-  /* copy these out first because if the username is 32 chars, the next
-     section will overwrite the first byte of the UIC */
-  retpw.pw_uid = up->uaf$w_mem;
-  retpw.pw_gid = up->uaf$w_grp;
-
-  /* I suppose this is not the best style, to possibly overwrite one
-     byte beyond the end of the field, but what the heck... */
-  ptr = &up->uaf$t_username[UAF$S_USERNAME];
-  while (ptr[-1] == ' ')
-    ptr--;
-  *ptr = '\0';
-  strcpy (retpw.pw_name, up->uaf$t_username);
-
-  /* the rest of these are counted ascii strings */
-  strncpy (retpw.pw_gecos, &up->uaf$t_owner[1], up->uaf$t_owner[0]);
-  retpw.pw_gecos[up->uaf$t_owner[0]] = '\0';
-  strncpy (retpw.pw_dir, &up->uaf$t_defdev[1], up->uaf$t_defdev[0]);
-  retpw.pw_dir[up->uaf$t_defdev[0]] = '\0';
-  strncat (retpw.pw_dir, &up->uaf$t_defdir[1], up->uaf$t_defdir[0]);
-  retpw.pw_dir[up->uaf$t_defdev[0] + up->uaf$t_defdir[0]] = '\0';
-  strncpy (retpw.pw_shell, &up->uaf$t_defcli[1], up->uaf$t_defcli[0]);
-  retpw.pw_shell[up->uaf$t_defcli[0]] = '\0';
-
-  return &retpw;
+  return Qnil;
 }
-#else /* not READ_SYSUAF */
-static struct passwd retpw;
-#endif /* not READ_SYSUAF */
 
-struct passwd *
-getpwnam (name)
-     char * name;
-{
-#ifdef READ_SYSUAF
-  struct UAF *up;
-#else
-  char * user;
-  char * dir;
-  unsigned char * full;
-#endif /* READ_SYSUAF */
-  char *ptr = name;
+#endif /* !defined (WINDOWSNT) */
 
-  while (*ptr)
-    {
-      if ('a' <= *ptr && *ptr <= 'z')
-       *ptr -= 040;
-      ptr++;
-    }
-#ifdef READ_SYSUAF
-  if (!(up = get_uaf_name (name)))
-    return 0;
-  return cnv_uaf_pw (up);
-#else
-  if (strcmp (name, getenv ("USER")) == 0)
-    {
-      retpw.pw_uid = getuid ();
-      retpw.pw_gid = getgid ();
-      strcpy (retpw.pw_name, name);
-      if (full = egetenv ("FULLNAME"))
-       strcpy (retpw.pw_gecos, full);
-      else
-       *retpw.pw_gecos = '\0';
-      strcpy (retpw.pw_dir, egetenv ("HOME"));
-      *retpw.pw_shell = '\0';
-      return &retpw;
-    }
-  else
-    return 0;
-#endif /* not READ_SYSUAF */
-}
-
-struct passwd *
-getpwuid (uid)
-     unsigned long uid;
+#ifdef GNU_LINUX
+static void
+time_from_jiffies (unsigned long long tval, long hz,
+                  time_t *sec, unsigned *usec)
 {
-#ifdef READ_SYSUAF
-  struct UAF * up;
+  unsigned long long ullsec;
 
-  if (!(up = get_uaf_uic (uid)))
-    return 0;
-  return cnv_uaf_pw (up);
-#else
-  if (uid == sys_getuid ())
-    return getpwnam (egetenv ("USER"));
+  *sec = tval / hz;
+  ullsec = *sec;
+  tval -= ullsec * hz;
+  /* Careful: if HZ > 1 million, then integer division by it yields zero.  */
+  if (hz <= 1000000)
+    *usec = tval * 1000000 / hz;
   else
-    return 0;
-#endif /* not READ_SYSUAF */
+    *usec = tval / (hz / 1000000);
 }
 
-/* return total address space available to the current process.  This is
-   the sum of the current p0 size, p1 size and free page table entries
-   available. */
-int
-vlimit ()
+static Lisp_Object
+ltime_from_jiffies (unsigned long long tval, long hz)
 {
-  int item_code;
-  unsigned long free_pages;
-  unsigned long frep0va;
-  unsigned long frep1va;
-  register status;
-
-  item_code = JPI$_FREPTECNT;
-  if (((status = LIB$GETJPI (&item_code, 0, 0, &free_pages)) & 1) == 0)
-    {
-      errno = EVMSERR;
-      vaxc$errno = status;
-      return -1;
-    }
-  free_pages *= 512;
+  time_t sec;
+  unsigned usec;
 
-  item_code = JPI$_FREP0VA;
-  if (((status = LIB$GETJPI (&item_code, 0, 0, &frep0va)) & 1) == 0)
-    {
-      errno = EVMSERR;
-      vaxc$errno = status;
-      return -1;
-    }
-  item_code = JPI$_FREP1VA;
-  if (((status = LIB$GETJPI (&item_code, 0, 0, &frep1va)) & 1) == 0)
-    {
-      errno = EVMSERR;
-      vaxc$errno = status;
-      return -1;
-    }
+  time_from_jiffies (tval, hz, &sec, &usec);
 
-  return free_pages + frep0va + (0x7fffffff - frep1va);
+  return list3 (make_number ((sec >> 16) & 0xffff),
+               make_number (sec & 0xffff),
+               make_number (usec));
 }
 
-int
-define_logical_name (varname, string)
-     char *varname;
-     char *string;
+static void
+get_up_time (time_t *sec, unsigned *usec)
 {
-  struct dsc$descriptor_s strdsc =
-    {strlen (string), DSC$K_DTYPE_T, DSC$K_CLASS_S, string};
-  struct dsc$descriptor_s envdsc =
-    {strlen (varname), DSC$K_DTYPE_T, DSC$K_CLASS_S, varname};
-  struct dsc$descriptor_s lnmdsc =
-    {7, DSC$K_DTYPE_T, DSC$K_CLASS_S, "LNM$JOB"};
-
-  return LIB$SET_LOGICAL (&envdsc, &strdsc, &lnmdsc, 0, 0);
-}
+  FILE *fup;
 
-int
-delete_logical_name (varname)
-     char *varname;
-{
-  struct dsc$descriptor_s envdsc =
-    {strlen (varname), DSC$K_DTYPE_T, DSC$K_CLASS_S, varname};
-  struct dsc$descriptor_s lnmdsc =
-    {7, DSC$K_DTYPE_T, DSC$K_CLASS_S, "LNM$JOB"};
+  *sec = *usec = 0;
 
-  return LIB$DELETE_LOGICAL (&envdsc, &lnmdsc);
-}
+  BLOCK_INPUT;
+  fup = fopen ("/proc/uptime", "r");
 
-int
-ulimit ()
-{
-  return 0;
-}
+  if (fup)
+    {
+      double uptime, idletime;
 
-int
-setpgrp ()
-{
-  return 0;
+      /* The numbers in /proc/uptime use C-locale decimal point, but
+        we already set ourselves to the C locale (see `fixup_locale'
+        in emacs.c).  */
+      if (2 <= fscanf (fup, "%lf %lf", &uptime, &idletime))
+       {
+         *sec = uptime;
+         *usec = (uptime - *sec) * 1000000;
+       }
+      fclose (fup);
+    }
+  UNBLOCK_INPUT;
 }
 
-int
-execvp ()
-{
-  error ("execvp system call not implemented");
-  return -1;
-}
+#define MAJOR(d) (((unsigned)(d) >> 8) & 0xfff)
+#define MINOR(d) (((unsigned)(d) & 0xff) | (((unsigned)(d) & 0xfff00000) >> 12))
 
-int
-rename (from, to)
-     char *from, *to;
+static Lisp_Object
+procfs_ttyname (int rdev)
 {
-  int status;
-  struct FAB from_fab = cc$rms_fab, to_fab = cc$rms_fab;
-  struct NAM from_nam = cc$rms_nam, to_nam = cc$rms_nam;
-  char from_esn[NAM$C_MAXRSS];
-  char to_esn[NAM$C_MAXRSS];
-
-  from_fab.fab$l_fna = from;
-  from_fab.fab$b_fns = strlen (from);
-  from_fab.fab$l_nam = &from_nam;
-  from_fab.fab$l_fop = FAB$M_NAM;
-
-  from_nam.nam$l_esa = from_esn;
-  from_nam.nam$b_ess = sizeof from_esn;
+  FILE *fdev = NULL;
+  char name[PATH_MAX];
 
-  to_fab.fab$l_fna = to;
-  to_fab.fab$b_fns = strlen (to);
-  to_fab.fab$l_nam = &to_nam;
-  to_fab.fab$l_fop = FAB$M_NAM;
+  BLOCK_INPUT;
+  fdev = fopen ("/proc/tty/drivers", "r");
 
-  to_nam.nam$l_esa = to_esn;
-  to_nam.nam$b_ess = sizeof to_esn;
+  if (fdev)
+    {
+      unsigned major;
+      unsigned long minor_beg, minor_end;
+      char minor[25];  /* 2 32-bit numbers + dash */
+      char *endp;
 
-  status = SYS$RENAME (&from_fab, 0, 0, &to_fab);
+      while (!feof (fdev) && !ferror (fdev))
+       {
+         if (3 <= fscanf (fdev, "%*s %s %u %s %*s\n", name, &major, minor)
+             && major == MAJOR (rdev))
+           {
+             minor_beg = strtoul (minor, &endp, 0);
+             if (*endp == '\0')
+               minor_end = minor_beg;
+             else if (*endp == '-')
+               minor_end = strtoul (endp + 1, &endp, 0);
+             else
+               continue;
 
-  if (status & 1)
-    return 0;
-  else
-    {
-      if (status == RMS$_DEV)
-       errno = EXDEV;
-      else
-       errno = EVMSERR;
-      vaxc$errno = status;
-      return -1;
+             if (MINOR (rdev) >= minor_beg && MINOR (rdev) <= minor_end)
+               {
+                 sprintf (name + strlen (name), "%u", MINOR (rdev));
+                 break;
+               }
+           }
+       }
+      fclose (fdev);
     }
+  UNBLOCK_INPUT;
+  return build_string (name);
 }
 
-/* This function renames a file like `rename', but it strips
-   the version number from the "to" filename, such that the "to" file is
-   will always be a new version.  It also sets the file protection once it is
-   finished.  The protection that we will use is stored in fab_final_pro,
-   and was set when we did a creat_copy_attrs to create the file that we
-   are renaming.
-
-   We could use the chmod function, but Eunichs uses 3 bits per user category
-   to describe the protection, and VMS uses 4 (write and delete are separate
-   bits).  To maintain portability, the VMS implementation of `chmod' wires
-   the W and D bits together.  */
+static unsigned long
+procfs_get_total_memory (void)
+{
+  FILE *fmem = NULL;
+  unsigned long retval = 2 * 1024 * 1024; /* default: 2GB */
 
+  BLOCK_INPUT;
+  fmem = fopen ("/proc/meminfo", "r");
 
-static struct fibdef fib;      /* We need this initialized to zero */
-char vms_file_written[NAM$C_MAXRSS];
+  if (fmem)
+    {
+      unsigned long entry_value;
+      char entry_name[20];     /* the longest I saw is 13+1 */
 
-int
-rename_sans_version (from,to)
-     char *from, *to;
-{
-  short int chan;
-  int stat;
-  short int iosb[4];
-  int status;
-  struct FAB to_fab = cc$rms_fab;
-  struct NAM to_nam = cc$rms_nam;
-  struct dsc$descriptor fib_d ={sizeof (fib),0,0,(char*) &fib};
-  struct dsc$descriptor fib_attr[2]
-    = {{sizeof (fab_final_pro),ATR$C_FPRO,0,(char*) &fab_final_pro},{0,0,0,0}};
-  char to_esn[NAM$C_MAXRSS];
-
-  $DESCRIPTOR (disk,to_esn);
-
-  to_fab.fab$l_fna = to;
-  to_fab.fab$b_fns = strlen (to);
-  to_fab.fab$l_nam = &to_nam;
-  to_fab.fab$l_fop = FAB$M_NAM;
-
-  to_nam.nam$l_esa = to_esn;
-  to_nam.nam$b_ess = sizeof to_esn;
-
-  status = SYS$PARSE (&to_fab, 0, 0); /* figure out the full file name */
-
-  if (to_nam.nam$l_fnb && NAM$M_EXP_VER)
-    *(to_nam.nam$l_ver) = '\0';
-
-  stat = rename (from, to_esn);
-  if (stat < 0)
-    return stat;
-
-  strcpy (vms_file_written, to_esn);
-
-  to_fab.fab$l_fna = vms_file_written; /* this points to the versionless name */
-  to_fab.fab$b_fns = strlen (vms_file_written);
-
-  /* Now set the file protection to the correct value */
-  SYS$OPEN (&to_fab, 0, 0);    /* This fills in the nam$w_fid fields */
-
-  /* Copy these fields into the fib */
-  fib.fib$r_fid_overlay.fib$w_fid[0] = to_nam.nam$w_fid[0];
-  fib.fib$r_fid_overlay.fib$w_fid[1] = to_nam.nam$w_fid[1];
-  fib.fib$r_fid_overlay.fib$w_fid[2] = to_nam.nam$w_fid[2];
-
-  SYS$CLOSE (&to_fab, 0, 0);
-
-  stat = SYS$ASSIGN (&disk, &chan, 0, 0); /* open a channel to the disk */
-  if (!stat)
-    LIB$SIGNAL (stat);
-  stat = SYS$QIOW (0, chan, IO$_MODIFY, iosb, 0, 0, &fib_d,
-                  0, 0, 0, &fib_attr, 0);
-  if (!stat)
-    LIB$SIGNAL (stat);
-  stat = SYS$DASSGN (chan);
-  if (!stat)
-    LIB$SIGNAL (stat);
-  strcpy (vms_file_written, to_esn); /* We will write this to the terminal*/
-  return 0;
+      while (!feof (fmem) && !ferror (fmem))
+       {
+         if (2 <= fscanf (fmem, "%s %lu kB\n", entry_name, &entry_value)
+             && strcmp (entry_name, "MemTotal:") == 0)
+           {
+             retval = entry_value;
+             break;
+           }
+       }
+      fclose (fmem);
+    }
+  UNBLOCK_INPUT;
+  return retval;
 }
 
-int
-link (file, new)
-     char * file, * new;
+Lisp_Object
+system_process_attributes (Lisp_Object pid)
 {
-  register status;
-  struct FAB fab;
-  struct NAM nam;
-  unsigned short fid[3];
-  char esa[NAM$C_MAXRSS];
-
-  fab = cc$rms_fab;
-  fab.fab$l_fop = FAB$M_OFP;
-  fab.fab$l_fna = file;
-  fab.fab$b_fns = strlen (file);
-  fab.fab$l_nam = &nam;
-
-  nam = cc$rms_nam;
-  nam.nam$l_esa = esa;
-  nam.nam$b_ess = NAM$C_MAXRSS;
-
-  status = SYS$PARSE (&fab);
-  if ((status & 1) == 0)
-    {
-      errno = EVMSERR;
-      vaxc$errno = status;
-      return -1;
-    }
-  status = SYS$SEARCH (&fab);
-  if ((status & 1) == 0)
-    {
-      errno = EVMSERR;
-      vaxc$errno = status;
-      return -1;
-    }
-
-  fid[0] = nam.nam$w_fid[0];
-  fid[1] = nam.nam$w_fid[1];
-  fid[2] = nam.nam$w_fid[2];
+  char procfn[PATH_MAX], fn[PATH_MAX];
+  struct stat st;
+  struct passwd *pw;
+  struct group *gr;
+  long clocks_per_sec;
+  char *procfn_end;
+  char procbuf[1025], *p, *q;
+  int fd;
+  ssize_t nread;
+  const char *cmd = NULL;
+  char *cmdline = NULL;
+  size_t cmdsize = 0, cmdline_size;
+  unsigned char c;
+  int proc_id, ppid, uid, gid, pgrp, sess, tty, tpgid, thcount;
+  unsigned long long utime, stime, cutime, cstime, start;
+  long priority, nice, rss;
+  unsigned long minflt, majflt, cminflt, cmajflt, vsize;
+  time_t sec;
+  unsigned usec;
+  EMACS_TIME tnow, tstart, tboot, telapsed;
+  double pcpu, pmem;
+  Lisp_Object attrs = Qnil;
+  Lisp_Object cmd_str, decoded_cmd, tem;
+  struct gcpro gcpro1, gcpro2;
+  EMACS_INT uid_eint, gid_eint;
+
+  CHECK_NUMBER_OR_FLOAT (pid);
+  proc_id = FLOATP (pid) ? XFLOAT_DATA (pid) : XINT (pid);
+  sprintf (procfn, "/proc/%u", proc_id);
+  if (stat (procfn, &st) < 0)
+    return attrs;
+
+  GCPRO2 (attrs, decoded_cmd);
+
+  /* euid egid */
+  uid = st.st_uid;
+  /* Use of EMACS_INT stops GCC whining about limited range of data type.  */
+  uid_eint = uid;
+  attrs = Fcons (Fcons (Qeuid, make_fixnum_or_float (uid_eint)), attrs);
+  BLOCK_INPUT;
+  pw = getpwuid (uid);
+  UNBLOCK_INPUT;
+  if (pw)
+    attrs = Fcons (Fcons (Quser, build_string (pw->pw_name)), attrs);
 
-  fab.fab$l_fna = new;
-  fab.fab$b_fns = strlen (new);
+  gid = st.st_gid;
+  gid_eint = gid;
+  attrs = Fcons (Fcons (Qegid, make_fixnum_or_float (gid_eint)), attrs);
+  BLOCK_INPUT;
+  gr = getgrgid (gid);
+  UNBLOCK_INPUT;
+  if (gr)
+    attrs = Fcons (Fcons (Qgroup, build_string (gr->gr_name)), attrs);
 
-  status = SYS$PARSE (&fab);
-  if ((status & 1) == 0)
+  strcpy (fn, procfn);
+  procfn_end = fn + strlen (fn);
+  strcpy (procfn_end, "/stat");
+  fd = emacs_open (fn, O_RDONLY, 0);
+  if (fd >= 0 && (nread = emacs_read (fd, procbuf, sizeof (procbuf) - 1)) > 0)
     {
-      errno = EVMSERR;
-      vaxc$errno = status;
-      return -1;
-    }
+      procbuf[nread] = '\0';
+      p = procbuf;
 
-  nam.nam$w_fid[0] = fid[0];
-  nam.nam$w_fid[1] = fid[1];
-  nam.nam$w_fid[2] = fid[2];
+      p = strchr (p, '(');
+      if (p != NULL)
+       {
+         q = strrchr (p + 1, ')');
+         /* comm */
+         if (q != NULL)
+           {
+             cmd = p + 1;
+             cmdsize = q - cmd;
+           }
+       }
+      else
+       q = NULL;
+      if (cmd == NULL)
+       {
+         cmd = "???";
+         cmdsize = 3;
+       }
+      /* Command name is encoded in locale-coding-system; decode it.  */
+      cmd_str = make_unibyte_string (cmd, cmdsize);
+      decoded_cmd = code_convert_string_norecord (cmd_str,
+                                                 Vlocale_coding_system, 0);
+      attrs = Fcons (Fcons (Qcomm, decoded_cmd), attrs);
 
-  nam.nam$l_esa = nam.nam$l_name;
-  nam.nam$b_esl = nam.nam$b_name + nam.nam$b_type + nam.nam$b_ver;
+      if (q)
+       {
+         EMACS_INT ppid_eint, pgrp_eint, sess_eint, tpgid_eint, thcount_eint;
+         p = q + 2;
+         /* state ppid pgrp sess tty tpgid . minflt cminflt majflt cmajflt utime stime cutime cstime priority nice thcount . start vsize rss */
+         sscanf (p, "%c %d %d %d %d %d %*u %lu %lu %lu %lu %Lu %Lu %Lu %Lu %ld %ld %d %*d %Lu %lu %ld",
+                 &c, &ppid, &pgrp, &sess, &tty, &tpgid,
+                 &minflt, &cminflt, &majflt, &cmajflt,
+                 &utime, &stime, &cutime, &cstime,
+                 &priority, &nice, &thcount, &start, &vsize, &rss);
+         {
+           char state_str[2];
+
+           state_str[0] = c;
+           state_str[1] = '\0';
+           tem =  build_string (state_str);
+           attrs = Fcons (Fcons (Qstate, tem), attrs);
+         }
+         /* Stops GCC whining about limited range of data type.  */
+         ppid_eint = ppid;
+         pgrp_eint = pgrp;
+         sess_eint = sess;
+         tpgid_eint = tpgid;
+         thcount_eint = thcount;
+         attrs = Fcons (Fcons (Qppid, make_fixnum_or_float (ppid_eint)), attrs);
+         attrs = Fcons (Fcons (Qpgrp, make_fixnum_or_float (pgrp_eint)), attrs);
+         attrs = Fcons (Fcons (Qsess, make_fixnum_or_float (sess_eint)), attrs);
+         attrs = Fcons (Fcons (Qttname, procfs_ttyname (tty)), attrs);
+         attrs = Fcons (Fcons (Qtpgid, make_fixnum_or_float (tpgid_eint)), attrs);
+         attrs = Fcons (Fcons (Qminflt, make_fixnum_or_float (minflt)), attrs);
+         attrs = Fcons (Fcons (Qmajflt, make_fixnum_or_float (majflt)), attrs);
+         attrs = Fcons (Fcons (Qcminflt, make_fixnum_or_float (cminflt)), attrs);
+         attrs = Fcons (Fcons (Qcmajflt, make_fixnum_or_float (cmajflt)), attrs);
+         clocks_per_sec = sysconf (_SC_CLK_TCK);
+         if (clocks_per_sec < 0)
+           clocks_per_sec = 100;
+         attrs = Fcons (Fcons (Qutime,
+                               ltime_from_jiffies (utime, clocks_per_sec)),
+                        attrs);
+         attrs = Fcons (Fcons (Qstime,
+                               ltime_from_jiffies (stime, clocks_per_sec)),
+                        attrs);
+         attrs = Fcons (Fcons (Qtime,
+                               ltime_from_jiffies (stime+utime, clocks_per_sec)),
+                        attrs);
+         attrs = Fcons (Fcons (Qcutime,
+                               ltime_from_jiffies (cutime, clocks_per_sec)),
+                        attrs);
+         attrs = Fcons (Fcons (Qcstime,
+                               ltime_from_jiffies (cstime, clocks_per_sec)),
+                        attrs);
+         attrs = Fcons (Fcons (Qctime,
+                               ltime_from_jiffies (cstime+cutime, clocks_per_sec)),
+                        attrs);
+         attrs = Fcons (Fcons (Qpri, make_number (priority)), attrs);
+         attrs = Fcons (Fcons (Qnice, make_number (nice)), attrs);
+         attrs = Fcons (Fcons (Qthcount, make_fixnum_or_float (thcount_eint)), attrs);
+         EMACS_GET_TIME (tnow);
+         get_up_time (&sec, &usec);
+         EMACS_SET_SECS (telapsed, sec);
+         EMACS_SET_USECS (telapsed, usec);
+         EMACS_SUB_TIME (tboot, tnow, telapsed);
+         time_from_jiffies (start, clocks_per_sec, &sec, &usec);
+         EMACS_SET_SECS (tstart, sec);
+         EMACS_SET_USECS (tstart, usec);
+         EMACS_ADD_TIME (tstart, tboot, tstart);
+         attrs = Fcons (Fcons (Qstart,
+                               list3 (make_number
+                                      ((EMACS_SECS (tstart) >> 16) & 0xffff),
+                                      make_number
+                                      (EMACS_SECS (tstart) & 0xffff),
+                                      make_number
+                                      (EMACS_USECS (tstart)))),
+                        attrs);
+         attrs = Fcons (Fcons (Qvsize, make_fixnum_or_float (vsize/1024)), attrs);
+         attrs = Fcons (Fcons (Qrss, make_fixnum_or_float (4*rss)), attrs);
+         EMACS_SUB_TIME (telapsed, tnow, tstart);
+         attrs = Fcons (Fcons (Qetime,
+                               list3 (make_number
+                                      ((EMACS_SECS (telapsed) >> 16) & 0xffff),
+                                      make_number
+                                      (EMACS_SECS (telapsed) & 0xffff),
+                                      make_number
+                                      (EMACS_USECS (telapsed)))),
+                        attrs);
+         time_from_jiffies (utime + stime, clocks_per_sec, &sec, &usec);
+         pcpu = (sec + usec / 1000000.0) / (EMACS_SECS (telapsed) + EMACS_USECS (telapsed) / 1000000.0);
+         if (pcpu > 1.0)
+           pcpu = 1.0;
+         attrs = Fcons (Fcons (Qpcpu, make_float (100 * pcpu)), attrs);
+         pmem = 4.0 * 100 * rss / procfs_get_total_memory ();
+         if (pmem > 100)
+           pmem = 100;
+         attrs = Fcons (Fcons (Qpmem, make_float (pmem)), attrs);
+       }
+    }
+  if (fd >= 0)
+    emacs_close (fd);
 
-  status = SYS$ENTER (&fab);
-  if ((status & 1) == 0)
+  /* args */
+  strcpy (procfn_end, "/cmdline");
+  fd = emacs_open (fn, O_RDONLY, 0);
+  if (fd >= 0)
     {
-      errno = EVMSERR;
-      vaxc$errno = status;
-      return -1;
+      for (cmdline_size = 0; emacs_read (fd, &c, 1) == 1; cmdline_size++)
+       {
+         if (isspace (c) || c == '\\')
+           cmdline_size++;     /* for later quoting, see below */
+       }
+      if (cmdline_size)
+       {
+         cmdline = xmalloc (cmdline_size + 1);
+         lseek (fd, 0L, SEEK_SET);
+         cmdline[0] = '\0';
+         if ((nread = read (fd, cmdline, cmdline_size)) >= 0)
+           cmdline[nread++] = '\0';
+         else
+           {
+             /* Assigning zero to `nread' makes us skip the following
+                two loops, assign zero to cmdline_size, and enter the
+                following `if' clause that handles unknown command
+                lines.  */
+             nread = 0;
+           }
+         /* We don't want trailing null characters.  */
+         for (p = cmdline + nread - 1; p > cmdline && !*p; p--)
+           nread--;
+         for (p = cmdline; p < cmdline + nread; p++)
+           {
+             /* Escape-quote whitespace and backslashes.  */
+             if (isspace (*p) || *p == '\\')
+               {
+                 memmove (p + 1, p, nread - (p - cmdline));
+                 nread++;
+                 *p++ = '\\';
+               }
+             else if (*p == '\0')
+               *p = ' ';
+           }
+         cmdline_size = nread;
+       }
+      if (!cmdline_size)
+       {
+         if (!cmd)
+           cmd = "???";
+         if (!cmdsize)
+           cmdsize = strlen (cmd);
+         cmdline_size = cmdsize + 2;
+         cmdline = xmalloc (cmdline_size + 1);
+         strcpy (cmdline, "[");
+         strcat (strncat (cmdline, cmd, cmdsize), "]");
+       }
+      emacs_close (fd);
+      /* Command line is encoded in locale-coding-system; decode it.  */
+      cmd_str = make_unibyte_string (cmdline, cmdline_size);
+      decoded_cmd = code_convert_string_norecord (cmd_str,
+                                                 Vlocale_coding_system, 0);
+      xfree (cmdline);
+      attrs = Fcons (Fcons (Qargs, decoded_cmd), attrs);
     }
 
-  return 0;
+  UNGCPRO;
+  return attrs;
 }
 
-void
-croak (badfunc)
-     char *badfunc;
-{
-  printf ("%s not yet implemented\r\n", badfunc);
-  reset_all_sys_modes ();
-  exit (1);
-}
+#elif defined (SOLARIS2) && defined (HAVE_PROCFS)
 
-long
-random ()
-{
-  /* Arrange to return a range centered on zero.  */
-  return rand () - (1 << 30);
-}
+/* The <procfs.h> header does not like to be included if _LP64 is defined and
+   __FILE_OFFSET_BITS == 64.  This is an ugly workaround that.  */
+#if !defined (_LP64) && defined (_FILE_OFFSET_BITS) &&  (_FILE_OFFSET_BITS  ==  64)
+#define PROCFS_FILE_OFFSET_BITS_HACK 1
+#undef _FILE_OFFSET_BITS
+#else
+#define PROCFS_FILE_OFFSET_BITS_HACK 0
+#endif
 
-void
-srandom (seed)
-{
-  srand (seed);
-}
-#endif /* VMS */
-\f
-#ifdef AIXHFT
+#include <procfs.h>
 
-/* Called from init_sys_modes.  */
-void
-hft_init (struct tty_display_info *tty_out)
+#if PROCFS_FILE_OFFSET_BITS_HACK ==  1
+#define _FILE_OFFSET_BITS 64
+#endif /* PROCFS_FILE_OFFSET_BITS_HACK ==  1 */
+
+Lisp_Object
+system_process_attributes (Lisp_Object pid)
 {
-  int junk;
+  char procfn[PATH_MAX], fn[PATH_MAX];
+  struct stat st;
+  struct passwd *pw;
+  struct group *gr;
+  char *procfn_end;
+  struct psinfo pinfo;
+  int fd;
+  ssize_t nread;
+  int proc_id, uid, gid;
+  Lisp_Object attrs = Qnil;
+  Lisp_Object decoded_cmd, tem;
+  struct gcpro gcpro1, gcpro2;
+  EMACS_INT uid_eint, gid_eint;
+
+  CHECK_NUMBER_OR_FLOAT (pid);
+  proc_id = FLOATP (pid) ? XFLOAT_DATA (pid) : XINT (pid);
+  sprintf (procfn, "/proc/%u", proc_id);
+  if (stat (procfn, &st) < 0)
+    return attrs;
+
+  GCPRO2 (attrs, decoded_cmd);
+
+  /* euid egid */
+  uid = st.st_uid;
+  /* Use of EMACS_INT stops GCC whining about limited range of data type.  */
+  uid_eint = uid;
+  attrs = Fcons (Fcons (Qeuid, make_fixnum_or_float (uid_eint)), attrs);
+  BLOCK_INPUT;
+  pw = getpwuid (uid);
+  UNBLOCK_INPUT;
+  if (pw)
+    attrs = Fcons (Fcons (Quser, build_string (pw->pw_name)), attrs);
 
-  /* 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. */
-#ifdef IBMR2AIX
-  if (ioctl (0, HFQERROR, &junk) < 0)
-    return;
-#else /* not IBMR2AIX */
-  if (ioctl (0, HFQEIO, 0) < 0)
-    return;
-#endif /* not IBMR2AIX */
-
-  /* On AIX the default hft keyboard mapping uses backspace rather than delete
-     as the rubout key's ASCII code.  Here this is changed.  The bug is that
-     there's no way to determine the old mapping, so in reset_sys_modes
-     we need to assume that the normal map had been present.  Of course, this
-     code also doesn't help if on a terminal emulator which doesn't understand
-     HFT VTD's.  */
-  {
-    struct hfbuf buf;
-    struct hfkeymap keymap;
-
-    buf.hf_bufp = (char *)&keymap;
-    buf.hf_buflen = sizeof (keymap);
-    keymap.hf_nkeys = 2;
-    keymap.hfkey[0].hf_kpos = 15;
-    keymap.hfkey[0].hf_kstate = HFMAPCHAR | HFSHFNONE;
-#ifdef IBMR2AIX
-    keymap.hfkey[0].hf_keyidh = '<';
-#else /* not IBMR2AIX */
-    keymap.hfkey[0].hf_page = '<';
-#endif /* not IBMR2AIX */
-    keymap.hfkey[0].hf_char = 127;
-    keymap.hfkey[1].hf_kpos = 15;
-    keymap.hfkey[1].hf_kstate = HFMAPCHAR | HFSHFSHFT;
-#ifdef IBMR2AIX
-    keymap.hfkey[1].hf_keyidh = '<';
-#else /* not IBMR2AIX */
-    keymap.hfkey[1].hf_page = '<';
-#endif /* not IBMR2AIX */
-    keymap.hfkey[1].hf_char = 127;
-    hftctl (0, HFSKBD, &buf);
-  }
-}
+  gid = st.st_gid;
+  gid_eint = gid;
+  attrs = Fcons (Fcons (Qegid, make_fixnum_or_float (gid_eint)), attrs);
+  BLOCK_INPUT;
+  gr = getgrgid (gid);
+  UNBLOCK_INPUT;
+  if (gr)
+    attrs = Fcons (Fcons (Qgroup, build_string (gr->gr_name)), attrs);
 
-/* Reset the rubout key to backspace.  */
+  strcpy (fn, procfn);
+  procfn_end = fn + strlen (fn);
+  strcpy (procfn_end, "/psinfo");
+  fd = emacs_open (fn, O_RDONLY, 0);
+  if (fd >= 0
+      && (nread = read (fd, (char*)&pinfo, sizeof (struct psinfo)) > 0))
+    {
+          attrs = Fcons (Fcons (Qppid, make_fixnum_or_float (pinfo.pr_ppid)), attrs);
+         attrs = Fcons (Fcons (Qpgrp, make_fixnum_or_float (pinfo.pr_pgid)), attrs);
+         attrs = Fcons (Fcons (Qsess, make_fixnum_or_float (pinfo.pr_sid)), attrs);
 
-void
-hft_reset (struct tty_display_info *tty_out)
-{
-  struct hfbuf buf;
-  struct hfkeymap keymap;
-  int junk;
+         {
+           char state_str[2];
+           state_str[0] =  pinfo.pr_lwp.pr_sname;
+           state_str[1] =  '\0';
+           tem =   build_string (state_str);
+           attrs =  Fcons (Fcons (Qstate,  tem),  attrs);
+         }
 
-#ifdef IBMR2AIX
-  if (ioctl (0, HFQERROR, &junk) < 0)
-    return;
-#else /* not IBMR2AIX */
-  if (ioctl (0, HFQEIO, 0) < 0)
-    return;
-#endif /* not IBMR2AIX */
-
-  buf.hf_bufp = (char *)&keymap;
-  buf.hf_buflen = sizeof (keymap);
-  keymap.hf_nkeys = 2;
-  keymap.hfkey[0].hf_kpos = 15;
-  keymap.hfkey[0].hf_kstate = HFMAPCHAR | HFSHFNONE;
-#ifdef IBMR2AIX
-  keymap.hfkey[0].hf_keyidh = '<';
-#else /* not IBMR2AIX */
-  keymap.hfkey[0].hf_page = '<';
-#endif /* not IBMR2AIX */
-  keymap.hfkey[0].hf_char = 8;
-  keymap.hfkey[1].hf_kpos = 15;
-  keymap.hfkey[1].hf_kstate = HFMAPCHAR | HFSHFSHFT;
-#ifdef IBMR2AIX
-  keymap.hfkey[1].hf_keyidh = '<';
-#else /* not IBMR2AIX */
-  keymap.hfkey[1].hf_page = '<';
-#endif /* not IBMR2AIX */
-  keymap.hfkey[1].hf_char = 8;
-  hftctl (0, HFSKBD, &buf);
-}
+         /* FIXME: missing Qttyname. psinfo.pr_ttydev is a dev_t,
+            need to get a string from it. */
 
-#endif /* AIXHFT */
+         /* FIXME: missing: Qtpgid */
 
-\f
-#ifndef BSTRING
+         /* FIXME: missing:
+               Qminflt
+               Qmajflt
+               Qcminflt
+               Qcmajflt
 
-#ifndef bzero
+               Qutime
+               Qcutime
+               Qstime
+               Qcstime
+               Are they available? */
 
-void
-bzero (b, length)
-     register char *b;
-     register int length;
-{
-#ifdef VMS
-  short zero = 0;
-  long max_str = 65535;
-
-  while (length > max_str) {
-    (void) LIB$MOVC5 (&zero, &zero, &zero, &max_str, b);
-    length -= max_str;
-    b += max_str;
-  }
-  max_str = length;
-  (void) LIB$MOVC5 (&zero, &zero, &zero, &max_str, b);
-#else
-  while (length-- > 0)
-    *b++ = 0;
-#endif /* not VMS */
-}
+         attrs = Fcons (Fcons (Qtime,
+                               list3 (make_number (pinfo.pr_time.tv_sec >> 16),
+                                      make_number (pinfo.pr_time.tv_sec & 0xffff),
+                                      make_number (pinfo.pr_time.tv_nsec))),
+                        attrs);
 
-#endif /* no bzero */
-#endif /* BSTRING */
+         attrs = Fcons (Fcons (Qctime,
+                               list3 (make_number (pinfo.pr_ctime.tv_sec >> 16),
+                                      make_number (pinfo.pr_ctime.tv_sec & 0xffff),
+                                      make_number (pinfo.pr_ctime.tv_nsec))),
+                        attrs);
 
-#if (!defined (BSTRING) && !defined (bcopy)) || defined (NEED_BCOPY)
-#undef bcopy
+         attrs = Fcons (Fcons (Qpri, make_number (pinfo.pr_lwp.pr_pri)), attrs);
+         attrs = Fcons (Fcons (Qnice, make_number (pinfo.pr_lwp.pr_nice)), attrs);
+         attrs = Fcons (Fcons (Qthcount, make_fixnum_or_float (pinfo.pr_nlwp)), attrs);
 
-/* Saying `void' requires a declaration, above, where bcopy is used
-   and that declaration causes pain for systems where bcopy is a macro.  */
-bcopy (b1, b2, length)
-     register char *b1;
-     register char *b2;
-     register int length;
-{
-#ifdef VMS
-  long max_str = 65535;
-
-  while (length > max_str) {
-    (void) LIB$MOVC3 (&max_str, b1, b2);
-    length -= max_str;
-    b1 += max_str;
-    b2 += max_str;
-  }
-  max_str = length;
-  (void) LIB$MOVC3 (&length, b1, b2);
-#else
-  while (length-- > 0)
-    *b2++ = *b1++;
-#endif /* not VMS */
-}
-#endif /* (!defined (BSTRING) && !defined (bcopy)) || defined (NEED_BCOPY) */
+         attrs = Fcons (Fcons (Qstart,
+                               list3 (make_number (pinfo.pr_start.tv_sec >> 16),
+                                      make_number (pinfo.pr_start.tv_sec & 0xffff),
+                                      make_number (pinfo.pr_start.tv_nsec))),
+                        attrs);
+         attrs = Fcons (Fcons (Qvsize, make_fixnum_or_float (pinfo.pr_size)), attrs);
+         attrs = Fcons (Fcons (Qrss, make_fixnum_or_float (pinfo.pr_rssize)), attrs);
 
-#ifndef BSTRING
-#ifndef bcmp
-int
-bcmp (b1, b2, length)  /* This could be a macro! */
-     register char *b1;
-     register char *b2;
-     register int length;
-{
-#ifdef VMS
-  struct dsc$descriptor_s src1 = {length, DSC$K_DTYPE_T, DSC$K_CLASS_S, b1};
-  struct dsc$descriptor_s src2 = {length, DSC$K_DTYPE_T, DSC$K_CLASS_S, b2};
+         /* pr_pctcpu and pr_pctmem are encoded as a fixed point 16 bit number in  [0 ... 1].  */
+         attrs = Fcons (Fcons (Qpcpu, (pinfo.pr_pctcpu * 100.0) / (double)0x8000), attrs);
+         attrs = Fcons (Fcons (Qpmem, (pinfo.pr_pctmem * 100.0) / (double)0x8000), attrs);
 
-  return STR$COMPARE (&src1, &src2);
-#else
-  while (length-- > 0)
-    if (*b1++ != *b2++)
-      return 1;
+         decoded_cmd
+           =  code_convert_string_norecord (make_unibyte_string (pinfo.pr_fname,
+                                                                 strlen (pinfo.pr_fname)),
+                                            Vlocale_coding_system,  0);
+         attrs =  Fcons (Fcons (Qcomm,  decoded_cmd),  attrs);
+         decoded_cmd
+           =  code_convert_string_norecord (make_unibyte_string (pinfo.pr_psargs,
+                                                                 strlen (pinfo.pr_psargs)),
+                                            Vlocale_coding_system,  0);
+         attrs =  Fcons (Fcons (Qargs,  decoded_cmd),  attrs);
+    }
 
-  return 0;
-#endif /* not VMS */
+  if (fd >= 0)
+    emacs_close (fd);
+
+  UNGCPRO;
+  return attrs;
 }
-#endif /* no bcmp */
-#endif /* not BSTRING */
-\f
-#ifndef HAVE_STRSIGNAL
-char *
-strsignal (code)
-     int code;
-{
-  char *signame = 0;
 
-  if (0 <= code && code < NSIG)
-    {
-#ifdef VMS
-      signame = sys_errlist[code];
-#else
-      /* Cast to suppress warning if the table has const char *.  */
-      signame = (char *) sys_siglist[code];
-#endif
-    }
+/* The WINDOWSNT implementation is in w32.c.
+   The MSDOS implementation is in dosfns.c.  */
+#elif !defined (WINDOWSNT) && !defined (MSDOS)
 
-  return signame;
+Lisp_Object
+system_process_attributes (Lisp_Object pid)
+{
+  return Qnil;
 }
-#endif /* HAVE_STRSIGNAL */
+
+#endif /* !defined (WINDOWSNT) */
+
 
 /* arch-tag: edb43589-4e09-4544-b325-978b5b121dcf
    (do not change this comment) */