]> code.delx.au - gnu-emacs/blobdiff - src/sysdep.c
(x_connection_closed): Add newline when printing error message on stderr.
[gnu-emacs] / src / sysdep.c
index e4ef51e519f87917c200c7989315b166d0d51686..5baf95c92b5a46581851947250d40bf36c9d4bc9 100644 (file)
@@ -1,5 +1,5 @@
 /* Interfaces to system-dependent kernel and library entries.
-   Copyright (C) 1985, 86, 87, 88, 93, 94 Free Software Foundation, Inc.
+   Copyright (C) 1985, 86, 87, 88, 93, 94, 95 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -15,7 +15,8 @@ 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, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
 
 
 #include <signal.h>
@@ -75,11 +76,21 @@ extern int h_errno;
 #include <sys/stat.h>
 #include <errno.h>
 
+/* Get _POSIX_VDISABLE, if it is available.  */
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
 #ifdef MSDOS   /* Demacs 1.1.2 91/10/20 Manabu Higashida, MW Aug 1993 */
 #include <dos.h>
 #include "dosfns.h"
 #include "msdos.h"
 #include <sys/param.h>
+
+#if __DJGPP__ > 1
+extern int etext;
+extern unsigned start __asm__ ("start");
+#endif
 #endif
 
 extern int errno;
@@ -186,6 +197,10 @@ struct utimbuf {
 #endif
 #endif
 
+#ifndef VFORK_RETURN_TYPE
+#define VFORK_RETURN_TYPE int
+#endif
+
 /* LPASS8 is new in 4.3, and makes cbreak mode provide all 8 bits.  */
 #ifndef LPASS8
 #define LPASS8 0
@@ -444,6 +459,9 @@ wait_for_termination (pid)
 #endif /* not BSD, 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;
@@ -454,6 +472,7 @@ wait_for_termination (pid)
       if (status == pid || status == -1)
        break;
 #endif /* BSD4_1 */
+#endif /* not __DJGPP__ > 1*/
 #endif /* not subprocesses */
     }
 }
@@ -512,9 +531,13 @@ child_setup_tty (out)
 #ifdef IUCLC
   s.main.c_iflag &= ~IUCLC;    /* Disable downcasing on input.  */
 #endif
+#ifdef ISTRIP
+  s.main.c_iflag &= ~ISTRIP;   /* don't strip 8th bit on input */
+#endif
 #ifdef OLCUC
   s.main.c_oflag &= ~OLCUC;    /* Disable upcasing on output.  */
 #endif
+  s.main.c_oflag &= ~TAB3;     /* Disable tab expansion */
   s.main.c_cflag = (s.main.c_cflag & ~CSIZE) | CS8; /* Don't strip 8th bit */
 #if 0
   /* Said to be unnecessary:  */
@@ -711,19 +734,31 @@ sys_subshell ()
 #ifdef WINDOWSNT
   pid = -1;
 #else /* not WINDOWSNT */
-  pid = vfork ();
 
+#ifdef MSDOS
+  pid = 0;
+#if __DJGPP__ > 1
+  save_signal_handlers (saved_handlers);
+  synch_process_alive = 1;
+#endif /* __DJGPP__ > 1 */
+#else  
+  pid = vfork ();
   if (pid == -1)
     error ("Can't spawn subshell");
+#endif
+
   if (pid == 0)
 #endif /* not WINDOWSNT */
     {
-      char *sh;
+      char *sh = 0;
 
 #ifdef MSDOS    /* MW, Aug 1993 */
       getwd (oldwd);
+      if (sh == 0)
+       sh = (char *) egetenv ("SUSPEND");      /* KFS, 1994-12-14 */
 #endif
-      sh = (char *) egetenv ("SHELL");
+      if (sh == 0)
+       sh = (char *) egetenv ("SHELL");
       if (sh == 0)
        sh = "sh";
 
@@ -747,12 +782,12 @@ sys_subshell ()
 #ifdef MSDOS    /* Demacs 1.1.2 91/10/20 Manabu Higashida */
       st = system (sh);
       chdir (oldwd);
+#if 0  /* This is also reported if last command executed in subshell failed, KFS */
       if (st)
        report_file_error ("Can't execute subshell", Fcons (build_string (sh), Qnil));
+#endif
 #else /* not MSDOS */
 #ifdef  WINDOWSNT
-      restore_console ();
-
       /* Waits for process completion */
       pid = _spawnlp (_P_WAIT, sh, sh, NULL);
       if (pid == -1)
@@ -767,10 +802,17 @@ sys_subshell ()
 #endif /* not MSDOS */
     }
 
+  /* Do this now if we did not do it before.  */
+#if !defined (MSDOS) || __DJGPP__ == 1
   save_signal_handlers (saved_handlers);
   synch_process_alive = 1;
+#endif
+
+#ifndef MSDOS
   wait_for_termination (pid);
+#endif
   restore_signal_handlers (saved_handlers);
+  synch_process_alive = 0;
 #endif /* !VMS */
 }
 
@@ -1028,15 +1070,14 @@ emacs_get_tty (fd, settings)
 
 
 /* Set the parameters of the tty on FD according to the contents of
-   *SETTINGS.  If WAITP is non-zero, we wait for all queued output to
-   be written before making the change; otherwise, we forget any
-   queued input and make the change immediately.
+   *SETTINGS.  If FLUSHP is non-zero, we discard input.
    Return 0 if all went well, and -1 if anything failed.  */
+
 int
-emacs_set_tty (fd, settings, waitp)
+emacs_set_tty (fd, settings, flushp)
      int fd;
      struct emacs_tty *settings;
-     int waitp;
+     int flushp;
 {
   /* Set the primary parameters - baud rate, character size, etcetera.  */
 #ifdef HAVE_TCATTR
@@ -1050,7 +1091,7 @@ emacs_set_tty (fd, settings, waitp)
      AIX requires this to keep tty from hanging occasionally."  */
   /* This make sure that we don't loop indefinitely in here.  */
   for (i = 0 ; i < 10 ; i++)
-    if (tcsetattr (fd, waitp ? TCSAFLUSH : TCSADRAIN, &settings->main) < 0)
+    if (tcsetattr (fd, flushp ? TCSAFLUSH : TCSADRAIN, &settings->main) < 0)
       {
        if (errno == EINTR)
          continue;
@@ -1080,7 +1121,7 @@ emacs_set_tty (fd, settings, waitp)
 #else
 #ifdef HAVE_TERMIO
   /* The SYSV-style interface?  */
-  if (ioctl (fd, waitp ? TCSETAW : TCSETAF, &settings->main) < 0)
+  if (ioctl (fd, flushp ? TCSETAF : TCSETAW, &settings->main) < 0)
     return -1;
 
 #else
@@ -1094,7 +1135,7 @@ emacs_set_tty (fd, settings, waitp)
 #else
 #ifndef DOS_NT
   /* I give up - I hope you have the BSD ioctls.  */
-  if (ioctl (fd, (waitp) ? TIOCSETP : TIOCSETN, &settings->main) < 0)
+  if (ioctl (fd, (flushp) ? TIOCSETP : TIOCSETN, &settings->main) < 0)
     return -1;
 #endif /* not DOS_NT */
 
@@ -1123,7 +1164,11 @@ emacs_set_tty (fd, settings, waitp)
 /* The initial tty mode bits */
 struct emacs_tty old_tty;
 
-int term_initted;              /* 1 if outer tty status has been recorded */
+/* 1 if we have been through init_sys_modes.  */
+int term_initted;
+
+/* 1 if outer tty status has been recorded.  */
+int old_tty_valid;
 
 #ifdef BSD4_1
 /* BSD 4.1 needs to keep track of the lmode bits in order to start
@@ -1205,7 +1250,7 @@ init_sys_modes ()
     narrow_foreground_group ();
 #endif
 
-#ifdef HAVE_X_WINDOWS
+#ifdef HAVE_WINDOW_SYSTEM
   /* Emacs' window system on MSDOG uses the `internal terminal' and therefore
      needs the initialization code below.  */
   if (!read_socket_hook && EQ (Vwindow_system, Qnil))
@@ -1213,6 +1258,8 @@ init_sys_modes ()
     {
       EMACS_GET_TTY (input_fd, &old_tty);
 
+      old_tty_valid = 1;
+
       tty = old_tty;
 
 #if defined (HAVE_TERMIO) || defined (HAVE_TERMIOS)
@@ -1222,6 +1269,10 @@ init_sys_modes ()
 #endif
       tty.main.c_iflag |= (IGNBRK);    /* Ignore break condition */
       tty.main.c_iflag &= ~ICRNL;      /* Disable map of CR to NL on input */
+#ifdef INLCR  /* I'm just being cautious,
+                since I can't check how widespread INLCR is--rms.  */
+      tty.main.c_iflag &= ~INLCR;      /* Disable map of NL to CR on input */
+#endif
 #ifdef ISTRIP
       tty.main.c_iflag &= ~ISTRIP;     /* don't strip 8th bit on input */
 #endif
@@ -1291,7 +1342,7 @@ init_sys_modes ()
 #endif /* VSTOP */
 #endif /* mips or HAVE_TCATTR */
 #ifdef SET_LINE_DISCIPLINE
-      /* Need to explicitely request TERMIODISC line discipline or
+      /* Need to explicitly request TERMIODISC line discipline or
          Ultrix's termios does not work correctly.  */
       tty.main.c_line = SET_LINE_DISCIPLINE;
 #endif
@@ -1388,8 +1439,10 @@ init_sys_modes ()
 #endif
 
 #if defined (HAVE_TERMIOS) || defined (HPUX9)
+#ifdef TCOON
       if (!flow_control) tcflow (input_fd, TCOON);
 #endif
+#endif
 
 #ifdef AIXHFT
       hft_init ();
@@ -1444,7 +1497,11 @@ init_sys_modes ()
 #else
   setbuf (stdout, _sobuf);
 #endif
+#ifdef HAVE_WINDOW_SYSTEM
+  /* Emacs' window system on MSDOG uses the `internal terminal' and therefore
+     needs the initialization code below.  */
   if (! read_socket_hook && EQ (Vwindow_system, Qnil))
+#endif
     set_terminal_modes ();
 
   if (term_initted && no_redraw_on_reenter)
@@ -1583,22 +1640,13 @@ reset_sys_modes ()
     }
   if (!term_initted)
     return;
-#ifdef HAVE_X_WINDOWS
+#ifdef HAVE_WINDOW_SYSTEM
   /* Emacs' window system on MSDOG uses the `internal terminal' and therefore
      needs the clean-up code below.  */
   if (read_socket_hook || !EQ (Vwindow_system, Qnil))
     return;
 #endif
   cursor_to (FRAME_HEIGHT (selected_frame) - 1, 0);
-#ifdef MSDOS
-  if (!EQ (Vwindow_system, Qnil))
-    {
-      /* Change to grey on white.  */
-      putchar ('\e');
-      putchar ('A');
-      putchar (7);
-    }
-#endif
   clear_end_of_line (FRAME_WIDTH (selected_frame));
   /* clear_end_of_line may move the cursor */
   cursor_to (FRAME_HEIGHT (selected_frame) - 1, 0);
@@ -1641,8 +1689,9 @@ reset_sys_modes ()
     reset_sigio ();
 #endif /* BSD4_1 */
 
-  while (EMACS_SET_TTY (input_fd, &old_tty, 0) < 0 && errno == EINTR)
-    ;
+  if (old_tty_valid)
+    while (EMACS_SET_TTY (input_fd, &old_tty, 0) < 0 && errno == EINTR)
+      ;
 
 #ifdef MSDOS   /* Demacs 1.1.2 91/10/20 Manabu Higashida */
   dos_ttcooked ();
@@ -2008,7 +2057,7 @@ start_of_text ()
  *     at least on UniPlus, is temacs will have to be made unshared so
  *     that text and data are contiguous.  Then once loadup is complete,
  *     unexec will produce a shared executable where the data can be
- *     at the normal shared text boundry and the startofdata variable
+ *     at the normal shared text boundary and the startofdata variable
  *     will be patched by unexec to the correct value.
  *
  */
@@ -2112,7 +2161,7 @@ init_system_name ()
   uname (&uts);
   Vsystem_name = build_string (uts.nodename);
 #else /* HAVE_GETHOSTNAME */
-  int hostname_size = 256;
+  unsigned int hostname_size = 256;
   char *hostname = (char *) alloca (hostname_size);
 
   /* Try to get the host name; if the buffer is too short, try
@@ -2155,7 +2204,7 @@ init_system_name ()
        }
       if (hp)
        {
-         char *fqdn = hp->h_name;
+         char *fqdn = (char *) hp->h_name;
          char *p;
 
          if (!index (fqdn, '.'))
@@ -2196,10 +2245,14 @@ init_system_name ()
   }
 }
 \f
+#ifndef MSDOS
 #ifndef VMS
-#ifndef HAVE_SELECT
+#if !defined (HAVE_SELECT) || defined (BROKEN_SELECT_NON_X)
+
+#include "sysselect.h"
+#undef select
 
-#ifdef HAVE_X_WINDOWS
+#if defined (HAVE_X_WINDOWS) && !defined (HAVE_SELECT)
 /* Cause explanatory error message at compile time,
    since the select emulation is not good enough for X.  */
 int *x = &x_windows_lose_if_no_select_system_call;
@@ -2237,13 +2290,15 @@ select_alarm ()
 #ifndef WINDOWSNT
 /* Only rfds are checked.  */
 int
-select (nfds, rfds, wfds, efds, timeout)
+sys_select (nfds, rfds, wfds, efds, timeout)
      int nfds;
-     int *rfds, *wfds, *efds, *timeout;
+     SELECT_TYPE *rfds, *wfds, *efds;
+     EMACS_TIME *timeout;
 {
-  int ravail = 0, orfds = 0, old_alarm;
-  int timeoutval = timeout ? *timeout : 100000;
-  int *local_timeout = &timeoutval;
+  int ravail = 0, old_alarm;
+  SELECT_TYPE orfds;
+  int timeoutval;
+  int *local_timeout;
   extern int proc_buffered_char[];
 #ifndef subprocesses
   int process_tick = 0, update_tick = 0;
@@ -2253,52 +2308,64 @@ select (nfds, rfds, wfds, efds, timeout)
   SIGTYPE (*old_trap) ();
   unsigned char buf;
 
+#if defined (HAVE_SELECT) && defined (HAVE_X_WINDOWS)
+  /* If we're using X, then the native select will work; we only need the
+     emulation for non-X usage.  */
+  if (!NILP (Vwindow_system))
+    return select (nfds, rfds, wfds, efds, timeout);
+#endif
+  timeoutval = timeout ? EMACS_SECS (*timeout) : 100000;
+  local_timeout = &timeoutval;
+  FD_ZERO (&orfds);
   if (rfds)
     {
       orfds = *rfds;
-      *rfds = 0;
+      FD_ZERO (rfds);
     }
   if (wfds)
-    *wfds = 0;
+    FD_ZERO (wfds);
   if (efds)
-    *efds = 0;
+    FD_ZERO (efds);
 
   /* If we are looking only for the terminal, with no timeout,
      just read it and wait -- that's more efficient.  */
-  if (orfds == 1 && *local_timeout == 100000 && process_tick == update_tick)
+  if (*local_timeout == 100000 && process_tick == update_tick
+      && FD_ISSET (0, &orfds))
     {
+      int fd;
+      for (fd = 1; fd < nfds; ++fd)
+       if (FD_ISSET (fd, &orfds))
+         goto hardway;
       if (! detect_input_pending ())
        read_input_waiting ();
-      *rfds = 1;
+      FD_SET (0, rfds);
       return 1;
     }
 
+ hardway:
   /* Once a second, till the timer expires, check all the flagged read
    * descriptors to see if any input is available.  If there is some then
    * set the corresponding bit in the return copy of rfds.
    */ 
   while (1)
     {
-      register int to_check, bit, fd;
+      register int to_check, fd;
 
       if (rfds)
        {
-         for (to_check = nfds, bit = 1, fd = 0; --to_check >= 0; bit <<= 1, fd++)
+         for (to_check = nfds, fd = 0; --to_check >= 0; fd++)
            {
-             if (orfds & bit)
+             if (FD_ISSET (fd, &orfds))
                {
                  int avail = 0, status = 0;
 
-                 if (bit == 1)
+                 if (fd == 0)
                    avail = detect_input_pending (); /* Special keyboard handler */
                  else
                    {
 #ifdef FIONREAD
                      status = ioctl (fd, FIONREAD, &avail);
 #else /* no FIONREAD */
-#ifdef MSDOS
-                     abort (); /* I don't think we need it.  */
-#else /* not MSDOS */
                      /* Hoping it will return -1 if nothing available
                         or 0 if all 0 chars requested are read.  */
                      if (proc_buffered_char[fd] >= 0)
@@ -2309,12 +2376,11 @@ select (nfds, rfds, wfds, efds, timeout)
                          if (avail > 0)
                            proc_buffered_char[fd] = buf;
                        }
-#endif /* not MSDOS */
 #endif /* no FIONREAD */
                    }
                  if (status >= 0 && avail > 0)
                    {
-                     (*rfds) |= bit;
+                     FD_SET (fd, rfds);
                      ravail++;
                    }
                }
@@ -2330,14 +2396,10 @@ select (nfds, rfds, wfds, efds, timeout)
       while (select_alarmed == 0 && *local_timeout != 0
             && process_tick == update_tick)
        {
-#ifdef MSDOS
-         sleep_or_kbd_hit (SELECT_PAUSE, (orfds & 1) != 0);
-         select_alarm ();
-#else /* not MSDOS */
          /* If we are interested in terminal input,
             wait by reading the terminal.
             That makes instant wakeup for terminal input at least.  */
-         if (orfds & 1)
+         if (FD_ISSET (0, &orfds))
            {
              read_input_waiting ();
              if (detect_input_pending ())
@@ -2345,7 +2407,6 @@ select (nfds, rfds, wfds, efds, timeout)
            }
          else
            pause ();
-#endif /* not MSDOS */
        }
       (*local_timeout) -= SELECT_PAUSE;
       /* Reset the old alarm if there was one */
@@ -2370,8 +2431,8 @@ select (nfds, rfds, wfds, efds, timeout)
 /* Read keyboard input into the standard buffer,
    waiting for at least one character.  */
 
-/* Make all keyboard buffers much bigger when using X windows.  */
-#ifdef HAVE_X_WINDOWS
+/* Make all keyboard buffers much bigger when using a window system.  */
+#ifdef HAVE_WINDOW_SYSTEM
 #define BUFFER_SIZE_FACTOR 16
 #else
 #define BUFFER_SIZE_FACTOR 1
@@ -2400,7 +2461,7 @@ read_input_waiting ()
          /* Don't look at input that follows a C-g too closely.
             This reduces lossage due to autorepeat on C-g.  */
          if (buf[i].kind == ascii_keystroke
-             && XINT(buf[i].code) == quit_char)
+             && buf[i].code == quit_char)
            break;
        }
     }
@@ -2438,6 +2499,7 @@ read_input_waiting ()
 
 #endif /* not HAVE_SELECT */
 #endif /* not VMS */
+#endif /* not MSDOS */
 \f
 #ifdef BSD4_1
 /*
@@ -2620,84 +2682,6 @@ sys_sigsetmask (sigset_t new_mask)
 
 #endif /* POSIX_SIGNALS */
 \f
-#ifndef BSTRING
-
-#ifndef bzero
-
-void
-bzero (b, length)
-     register char *b;
-     register int length;
-{
-#ifdef VMS
-  short zero = 0;
-  long max_str = 65535;
-
-  while (length > max_str) {
-    (void) LIB$MOVC5 (&zero, &zero, &zero, &max_str, b);
-    length -= max_str;
-    b += max_str;
-  }
-  max_str = length;
-  (void) LIB$MOVC5 (&zero, &zero, &zero, &max_str, b);
-#else
-  while (length-- > 0)
-    *b++ = 0;
-#endif /* not VMS */
-}
-
-#endif /* no bzero */
-
-#ifndef bcopy
-/* Saying `void' requires a declaration, above, where bcopy is used
-   and that declaration causes pain for systems where bcopy is a macro.  */
-bcopy (b1, b2, length)
-     register char *b1;
-     register char *b2;
-     register int length;
-{
-#ifdef VMS
-  long max_str = 65535;
-
-  while (length > max_str) {
-    (void) LIB$MOVC3 (&max_str, b1, b2);
-    length -= max_str;
-    b1 += max_str;
-    b2 += max_str;
-  }
-  max_str = length;
-  (void) LIB$MOVC3 (&length, b1, b2);
-#else
-  while (length-- > 0)
-    *b2++ = *b1++;
-#endif /* not VMS */
-}
-#endif /* no bcopy */
-
-#ifndef bcmp
-int
-bcmp (b1, b2, length)  /* This could be a macro! */
-     register char *b1;
-     register char *b2;
-     register int length;
-{
-#ifdef VMS
-  struct dsc$descriptor_s src1 = {length, DSC$K_DTYPE_T, DSC$K_CLASS_S, b1};
-  struct dsc$descriptor_s src2 = {length, DSC$K_DTYPE_T, DSC$K_CLASS_S, b2};
-
-  return STR$COMPARE (&src1, &src2);
-#else
-  while (length-- > 0)
-    if (*b1++ != *b2++)
-      return 1;
-
-  return 0;
-#endif /* not VMS */
-}
-#endif /* no bcmp */
-
-#endif /* not BSTRING */
-\f
 #ifndef HAVE_RANDOM
 #ifdef random
 #define HAVE_RANDOM
@@ -2839,7 +2823,7 @@ sys_abort ()
 \f
 #ifdef VMS
 #ifdef LINK_CRTL_SHARE
-#ifdef SHAREABLE_LIB_BUG
+#ifdef SHARABLE_LIB_BUG
 /* Variables declared noshare and initialized in sharable libraries
    cannot be shared.  The VMS linker incorrectly forces you to use a private
    version which is uninitialized... If not for this "feature", we
@@ -2885,7 +2869,7 @@ char *sys_errlist[] =
     "I/O stream empty",
     "vax/vms specific error code nontranslatable error"
   };
-#endif /* SHAREABLE_LIB_BUG */
+#endif /* SHARABLE_LIB_BUG */
 #endif /* LINK_CRTL_SHARE */
 #endif /* VMS */
 
@@ -2927,10 +2911,19 @@ sys_open (path, oflag, mode)
 sys_close (fd)
      int fd;
 {
+  int did_retry = 0;
   register int rtnval;
 
   while ((rtnval = close (fd)) == -1
-        && (errno == EINTR));
+        && (errno == EINTR))
+    did_retry = 1;
+
+  /* If close is interrupted SunOS 4.1 may or may not have closed the
+     file descriptor.  If it did the second close will fail with
+     errno = EBADF.  That means we have succeeded.  */
+  if (rtnval == -1 && did_retry && errno == EBADF)
+    return 0;
+
   return rtnval;
 }
 
@@ -2988,6 +2981,7 @@ sys_write (fildes, buf, nbyte)
  *      Substitute fork for vfork on USG flavors.
  */
 
+VFORK_RETURN_TYPE
 vfork ()
 {
   return (fork ());
@@ -3074,7 +3068,7 @@ char *sys_siglist[NSIG + 1] =
 #ifdef sun
   "window size change",                            /* 20 SIGWINCH */
   "urgent socket condition",               /* 21 SIGURG */
-  "pollable event occured",                /* 22 SIGPOLL */
+  "pollable event occurred",               /* 22 SIGPOLL */
   "stop (cannot be caught or ignored)", /*  23 SIGSTOP */
   "user stop requested from tty",          /* 24 SIGTSTP */
   "stopped process has been continued",        /* 25 SIGCONT */
@@ -3626,17 +3620,17 @@ rmdir (dpath)
          dup2 (fd, 1);
          dup2 (fd, 2);
         }
-      wait_for_termination (cpid);
-  if (synch_process_death != 0 || synch_process_retcode != 0)
-      return -1;               /* /bin/rmdir failed */
+      execl ("/bin/rmdir", "rmdir", dpath, (char *) 0);
+      _exit (-1);              /* Can't exec /bin/rmdir */
+
     default:                   /* Parent process */
-      while (cpid != wait (&status));  /* Wait for kid to finish */
+      wait_for_termination (cpid);
     }
 
-  if (WIFSIGNALED (status) || WEXITSTATUS (status) != 0)
+  if (synch_process_death != 0 || synch_process_retcode != 0)
     {
       errno = EIO;             /* We don't know why, but */
-      return -1;               /* /bin/mkdir failed */
+      return -1;               /* /bin/rmdir failed */
     }
 
   return 0;
@@ -3794,7 +3788,7 @@ sys_access (filename, type)
   /* Check write protection. */
     
 #define CHECKPRIV(bit)    (prvmask.bit)
-#define WRITEABLE(field)  (! ((xab.xab$w_pro >> field) & XAB$M_NOWRITE))
+#define WRITABLE(field)  (! ((xab.xab$w_pro >> field) & XAB$M_NOWRITE))
 
   /* Find privilege bits */
   status = SYS$SETPRV (0, 0, 0, prvmask);
@@ -3815,7 +3809,7 @@ sys_access (filename, type)
     return -1;
   SYS$CLOSE (&fab, 0, 0);
   /* Check system access */
-  if (CHECKPRIV (PRV$V_SYSPRV) && WRITEABLE (XAB$V_SYS))
+  if (CHECKPRIV (PRV$V_SYSPRV) && WRITABLE (XAB$V_SYS))
     return 0;
   /* Check ACL entries, if any */
   acl_controlled = 0;
@@ -3841,16 +3835,16 @@ sys_access (filename, type)
        return -1;
     }
   /* No ACL entries specified, check normal protection */
-  if (WRITEABLE (XAB$V_WLD))   /* World writeable */
+  if (WRITABLE (XAB$V_WLD))    /* World writable */
     return 0;
-  if (WRITEABLE (XAB$V_GRP) &&
+  if (WRITABLE (XAB$V_GRP) &&
       (unsigned short) (xab.xab$l_uic >> 16) == grpid)
-    return 0;                  /* Group writeable */
-  if (WRITEABLE (XAB$V_OWN) &&
+    return 0;                  /* Group writable */
+  if (WRITABLE (XAB$V_OWN) &&
       (xab.xab$l_uic & 0xFFFF) == memid)
-    return 0;                  /* Owner writeable */
+    return 0;                  /* Owner writable */
 
-  return -1;   /* Not writeable */
+  return -1;   /* Not writable */
 }
 #endif /* not VMS4_4 */
 #endif /* access */
@@ -4533,7 +4527,7 @@ cnv_uaf_pw (up)
   retpw.pw_uid = up->uaf$w_mem;
   retpw.pw_gid = up->uaf$w_grp;
 
-  /* I suppose this is not the best sytle, to possibly overwrite one
+  /* I suppose this is not the best style, to possibly overwrite one
      byte beyond the end of the field, but what the heck... */
   ptr = &up->uaf$t_username[UAF$S_USERNAME];
   while (ptr[-1] == ' ')
@@ -5018,3 +5012,84 @@ dlclose ()
 }
 
 #endif /* USE_DL_STUBS */
+\f
+#ifndef BSTRING
+
+#ifndef bzero
+
+void
+bzero (b, length)
+     register char *b;
+     register int length;
+{
+#ifdef VMS
+  short zero = 0;
+  long max_str = 65535;
+
+  while (length > max_str) {
+    (void) LIB$MOVC5 (&zero, &zero, &zero, &max_str, b);
+    length -= max_str;
+    b += max_str;
+  }
+  max_str = length;
+  (void) LIB$MOVC5 (&zero, &zero, &zero, &max_str, b);
+#else
+  while (length-- > 0)
+    *b++ = 0;
+#endif /* not VMS */
+}
+
+#endif /* no bzero */
+#endif /* BSTRING */
+
+#if (!defined (BSTRING) && !defined (bcopy)) || defined (NEED_BCOPY)
+#undef bcopy
+
+/* Saying `void' requires a declaration, above, where bcopy is used
+   and that declaration causes pain for systems where bcopy is a macro.  */
+bcopy (b1, b2, length)
+     register char *b1;
+     register char *b2;
+     register int length;
+{
+#ifdef VMS
+  long max_str = 65535;
+
+  while (length > max_str) {
+    (void) LIB$MOVC3 (&max_str, b1, b2);
+    length -= max_str;
+    b1 += max_str;
+    b2 += max_str;
+  }
+  max_str = length;
+  (void) LIB$MOVC3 (&length, b1, b2);
+#else
+  while (length-- > 0)
+    *b2++ = *b1++;
+#endif /* not VMS */
+}
+#endif /* (defined (BSTRING) && !defined (bcopy)) || defined (NEED_BCOPY) */
+
+#ifndef BSTRING
+#ifndef bcmp
+int
+bcmp (b1, b2, length)  /* This could be a macro! */
+     register char *b1;
+     register char *b2;
+     register int length;
+{
+#ifdef VMS
+  struct dsc$descriptor_s src1 = {length, DSC$K_DTYPE_T, DSC$K_CLASS_S, b1};
+  struct dsc$descriptor_s src2 = {length, DSC$K_DTYPE_T, DSC$K_CLASS_S, b2};
+
+  return STR$COMPARE (&src1, &src2);
+#else
+  while (length-- > 0)
+    if (*b1++ != *b2++)
+      return 1;
+
+  return 0;
+#endif /* not VMS */
+}
+#endif /* no bcmp */
+#endif /* not BSTRING */