]> code.delx.au - gnu-emacs/blobdiff - src/callproc.c
Fix bad include.
[gnu-emacs] / src / callproc.c
index cd06ad5c2e8a7c3f22cc59680c1de7038468388d..b339f343f6236e4893fb446d5b7f1d3306f813dc 100644 (file)
@@ -1,7 +1,6 @@
 /* Synchronous subprocess invocation for GNU Emacs.
-   Copyright (C) 1985, 1986, 1987, 1988, 1993, 1994, 1995, 1999, 2000, 2001,
-                 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
-                 Free Software Foundation, Inc.
+   Copyright (C) 1985-1988, 1993-1995, 1999-2011
+                Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -24,48 +23,26 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include <errno.h>
 #include <stdio.h>
 #include <setjmp.h>
-
-/* Define SIGCHLD as an alias for SIGCLD.  */
-
-#if !defined (SIGCHLD) && defined (SIGCLD)
-#define SIGCHLD SIGCLD
-#endif /* SIGCLD */
-
 #include <sys/types.h>
-
-#ifdef HAVE_UNISTD_H
 #include <unistd.h>
-#endif
 
 #include <sys/file.h>
-#ifdef HAVE_FCNTL_H
 #include <fcntl.h>
-#endif
+
+#include "lisp.h"
 
 #ifdef WINDOWSNT
 #define NOMINMAX
 #include <windows.h>
-#include <stdlib.h>    /* for proper declaration of environ */
-#include <fcntl.h>
 #include "w32.h"
 #define _P_NOWAIT 1    /* from process.h */
 #endif
 
 #ifdef MSDOS   /* Demacs 1.1.1 91/10/16 HIRANO Satoshi */
-#include <fcntl.h>
 #include <sys/stat.h>
 #include <sys/param.h>
 #endif /* MSDOS */
 
-#ifndef O_RDONLY
-#define O_RDONLY 0
-#endif
-
-#ifndef O_WRONLY
-#define O_WRONLY 1
-#endif
-
-#include "lisp.h"
 #include "commands.h"
 #include "buffer.h"
 #include "character.h"
@@ -95,29 +72,15 @@ extern char **environ;
 #endif
 #endif
 
-Lisp_Object Vexec_path, Vexec_directory, Vexec_suffixes;
-Lisp_Object Vdata_directory, Vdoc_directory;
-Lisp_Object Vconfigure_info_directory, Vshared_game_score_directory;
-
 /* Pattern used by call-process-region to make temp files.  */
 static Lisp_Object Vtemp_file_name_pattern;
 
-extern Lisp_Object Vtemporary_file_directory;
-
-Lisp_Object Vshell_file_name;
-
-Lisp_Object Vprocess_environment, Vinitial_environment;
-
-#ifdef DOS_NT
-Lisp_Object Qbuffer_file_type;
-#endif /* DOS_NT */
-
 /* True if we are about to fork off a synchronous process or if we
    are waiting for it.  */
 int synch_process_alive;
 
 /* Nonzero => this is a string explaining death of synchronous subprocess.  */
-char *synch_process_death;
+const char *synch_process_death;
 
 /* Nonzero => this is the signal number that terminated the subprocess.  */
 int synch_process_termsig;
@@ -134,11 +97,10 @@ int synch_process_retcode;
 /* Nonzero if this is termination due to exit.  */
 static int call_process_exited;
 
-EXFUN (Fgetenv_internal, 2);
+static Lisp_Object Fgetenv_internal (Lisp_Object, Lisp_Object);
 
 static Lisp_Object
-call_process_kill (fdpid)
-     Lisp_Object fdpid;
+call_process_kill (Lisp_Object fdpid)
 {
   emacs_close (XFASTINT (Fcar (fdpid)));
   EMACS_KILLPG (XFASTINT (Fcdr (fdpid)), SIGKILL);
@@ -146,13 +108,13 @@ call_process_kill (fdpid)
   return Qnil;
 }
 
-Lisp_Object
-call_process_cleanup (arg)
-     Lisp_Object arg;
+static Lisp_Object
+call_process_cleanup (Lisp_Object arg)
 {
   Lisp_Object fdpid = Fcdr (arg);
 #if defined (MSDOS)
   Lisp_Object file;
+  int fd;
 #else
   int pid;
 #endif
@@ -161,9 +123,13 @@ call_process_cleanup (arg)
 
 #if defined (MSDOS)
   /* for MSDOS fdpid is really (fd . tempfile)  */
+  fd = XFASTINT (Fcar (fdpid));
   file = Fcdr (fdpid);
-  emacs_close (XFASTINT (Fcar (fdpid)));
-  if (strcmp (SDATA (file), NULL_DEVICE) != 0)
+  /* FD is -1 and FILE is "" when we didn't actually create a
+     temporary file in call-process.  */
+  if (fd >= 0)
+    emacs_close (fd);
+  if (!(strcmp (SDATA (file), NULL_DEVICE) == 0 || SREF (file, 0) == '\0'))
     unlink (SDATA (file));
 #else /* not MSDOS */
   pid = XFASTINT (Fcdr (fdpid));
@@ -196,8 +162,9 @@ DEFUN ("call-process", Fcall_process, Scall_process, 1, MANY, 0,
        doc: /* Call PROGRAM synchronously in separate process.
 The remaining arguments are optional.
 The program's input comes from file INFILE (nil means `/dev/null').
-Insert output in BUFFER before point; t means current buffer;
- nil for BUFFER means discard it; 0 means discard and don't wait.
+Insert output in BUFFER before point; t means current buffer; nil for BUFFER
+ means discard it; 0 means discard and don't wait; and `(:file FILE)', where
+ FILE is a file name string, means that it should be written to that file.
 BUFFER can also have the form (REAL-BUFFER STDERR-FILE); in that case,
 REAL-BUFFER says what to do with standard output, as above,
 while STDERR-FILE says what to do with standard error in the child.
@@ -217,12 +184,10 @@ and returns a numeric exit status or a signal description string.
 If you quit, the process is killed with SIGINT, or SIGKILL if you quit again.
 
 usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS)  */)
-     (nargs, args)
-     int nargs;
-     register Lisp_Object *args;
+  (ptrdiff_t nargs, Lisp_Object *args)
 {
   Lisp_Object infile, buffer, current_dir, path;
-  int display_p;
+  volatile int display_p_volatile;
   int fd[2];
   int filefd;
   register int pid;
@@ -231,19 +196,23 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS)  */)
   char buf[CALLPROC_BUFFER_SIZE_MAX];
   int bufsize = CALLPROC_BUFFER_SIZE_MIN;
   int count = SPECPDL_INDEX ();
+  volatile USE_SAFE_ALLOCA;
 
   register const unsigned char **new_argv;
   /* File to use for stderr in the child.
      t means use same as standard output.  */
   Lisp_Object error_file;
+  Lisp_Object output_file = Qnil;
 #ifdef MSDOS   /* Demacs 1.1.1 91/10/16 HIRANO Satoshi */
-  char *outf, *tempfile;
+  char *outf, *tempfile = NULL;
   int outfilefd;
 #endif
+  int fd_output = -1;
   struct coding_system process_coding; /* coding-system of process output */
   struct coding_system argument_coding;        /* coding-system of arguments */
   /* Set to the return value of Ffind_operation_coding_system.  */
   Lisp_Object coding_systems;
+  int output_to_buffer = 1;
 
   /* Qt denotes that Ffind_operation_coding_system is not yet called.  */
   coding_systems = Qt;
@@ -262,7 +231,7 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS)  */)
   /* Decide the coding-system for giving arguments.  */
   {
     Lisp_Object val, *args2;
-    int i;
+    ptrdiff_t i;
 
     /* If arguments are supplied, we may have to encode them.  */
     if (nargs >= 5)
@@ -280,21 +249,16 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS)  */)
        if (!NILP (Vcoding_system_for_write))
          val = Vcoding_system_for_write;
        else if (! must_encode)
-         val = Qnil;
+         val = Qraw_text;
        else
          {
-           args2 = (Lisp_Object *) alloca ((nargs + 1) * sizeof *args2);
+           SAFE_ALLOCA (args2, Lisp_Object *, (nargs + 1) * sizeof *args2);
            args2[0] = Qcall_process;
            for (i = 0; i < nargs; i++) args2[i + 1] = args[i];
            coding_systems = Ffind_operation_coding_system (nargs + 1, args2);
-           if (CONSP (coding_systems))
-             val = XCDR (coding_systems);
-           else if (CONSP (Vdefault_process_coding_system))
-             val = XCDR (Vdefault_process_coding_system);
-           else
-             val = Qnil;
+           val = CONSP (coding_systems) ? XCDR (coding_systems) : Qnil;
          }
-       val = coding_inherit_eol_type (val, Qnil);
+       val = complement_process_encoding_system (val);
        setup_coding_system (Fcheck_coding_system (val), &argument_coding);
        coding_attrs = CODING_ID_ATTRS (argument_coding.id);
        if (NILP (CODING_ATTR_ASCII_COMPAT (coding_attrs)))
@@ -308,7 +272,7 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS)  */)
 
   if (nargs >= 2 && ! NILP (args[1]))
     {
-      infile = Fexpand_file_name (args[1], current_buffer->directory);
+      infile = Fexpand_file_name (args[1], BVAR (current_buffer, directory));
       CHECK_STRING (infile);
     }
   else
@@ -318,9 +282,12 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS)  */)
     {
       buffer = args[2];
 
-      /* If BUFFER is a list, its meaning is
-        (BUFFER-FOR-STDOUT FILE-FOR-STDERR).  */
-      if (CONSP (buffer))
+      /* If BUFFER is a list, its meaning is (BUFFER-FOR-STDOUT
+        FILE-FOR-STDERR), unless the first element is :file, in which case see
+        the next paragraph. */
+      if (CONSP (buffer)
+         && (! SYMBOLP (XCAR (buffer))
+             || strcmp (SSDATA (SYMBOL_NAME (XCAR (buffer))), ":file")))
        {
          if (CONSP (XCDR (buffer)))
            {
@@ -336,6 +303,17 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS)  */)
          buffer = XCAR (buffer);
        }
 
+      /* If the buffer is (still) a list, it might be a (:file "file") spec. */
+      if (CONSP (buffer)
+         && SYMBOLP (XCAR (buffer))
+         && ! strcmp (SSDATA (SYMBOL_NAME (XCAR (buffer))), ":file"))
+       {
+         output_file = Fexpand_file_name (XCAR (XCDR (buffer)),
+                                          BVAR (current_buffer, directory));
+         CHECK_STRING (output_file);
+         buffer = Qnil;
+       }
+
       if (!(EQ (buffer, Qnil)
            || EQ (buffer, Qt)
            || INTEGERP (buffer)))
@@ -363,11 +341,11 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS)  */)
      protected by the caller, so all we really have to worry about is
      buffer.  */
   {
-    struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
+    struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
 
-    current_dir = current_buffer->directory;
+    current_dir = BVAR (current_buffer, directory);
 
-    GCPRO4 (infile, buffer, current_dir, error_file);
+    GCPRO5 (infile, buffer, current_dir, error_file, output_file);
 
     current_dir = Funhandled_file_name_directory (current_dir);
     if (NILP (current_dir))
@@ -379,7 +357,7 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS)  */)
 
     if (NILP (Ffile_accessible_directory_p (current_dir)))
       report_file_error ("Setting current directory",
-                        Fcons (current_buffer->directory, Qnil));
+                        Fcons (BVAR (current_buffer, directory), Qnil));
 
     if (STRING_MULTIBYTE (infile))
       infile = ENCODE_FILE (infile);
@@ -387,17 +365,39 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS)  */)
       current_dir = ENCODE_FILE (current_dir);
     if (STRINGP (error_file) && STRING_MULTIBYTE (error_file))
       error_file = ENCODE_FILE (error_file);
+    if (STRINGP (output_file) && STRING_MULTIBYTE (output_file))
+      output_file = ENCODE_FILE (output_file);
     UNGCPRO;
   }
 
-  display_p = INTERACTIVE && nargs >= 4 && !NILP (args[3]);
+  display_p_volatile = INTERACTIVE && nargs >= 4 && !NILP (args[3]);
 
-  filefd = emacs_open (SDATA (infile), O_RDONLY, 0);
+  filefd = emacs_open (SSDATA (infile), O_RDONLY, 0);
   if (filefd < 0)
     {
       infile = DECODE_FILE (infile);
       report_file_error ("Opening process input file", Fcons (infile, Qnil));
     }
+
+  if (STRINGP (output_file))
+    {
+#ifdef DOS_NT
+      fd_output = emacs_open (SSDATA (output_file),
+                             O_WRONLY | O_TRUNC | O_CREAT | O_TEXT,
+                             S_IREAD | S_IWRITE);
+#else  /* not DOS_NT */
+      fd_output = creat (SSDATA (output_file), 0666);
+#endif /* not DOS_NT */
+      if (fd_output < 0)
+       {
+         output_file = DECODE_FILE (output_file);
+         report_file_error ("Opening process output file",
+                            Fcons (output_file, Qnil));
+       }
+      if (STRINGP (error_file) || NILP (error_file))
+       output_to_buffer = 0;
+    }
+
   /* Search for program; barf if not found.  */
   {
     struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
@@ -418,11 +418,11 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS)  */)
       && SREF (path, 1) == ':')
     path = Fsubstring (path, make_number (2), Qnil);
 
-  new_argv = (const unsigned char **)
-    alloca (max (2, nargs - 2) * sizeof (char *));
+  SAFE_ALLOCA (new_argv, const unsigned char **,
+              (nargs > 4 ? nargs - 2 : 2) * sizeof *new_argv);
   if (nargs > 4)
     {
-      register int i;
+      ptrdiff_t i;
       struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
 
       GCPRO5 (infile, buffer, current_dir, path, error_file);
@@ -444,26 +444,32 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS)  */)
   new_argv[0] = SDATA (path);
 
 #ifdef MSDOS /* MW, July 1993 */
-  if ((outf = egetenv ("TMPDIR")))
-    strcpy (tempfile = alloca (strlen (outf) + 20), outf);
-  else
-    {
-      tempfile = alloca (20);
-      *tempfile = '\0';
-    }
-  dostounix_filename (tempfile);
-  if (*tempfile == '\0' || tempfile[strlen (tempfile) - 1] != '/')
-    strcat (tempfile, "/");
-  strcat (tempfile, "detmp.XXX");
-  mktemp (tempfile);
-
-  outfilefd = creat (tempfile, S_IREAD | S_IWRITE);
-  if (outfilefd < 0)
+
+  /* If we're redirecting STDOUT to a file, that file is already open
+     on fd_output.  */
+  if (fd_output < 0)
     {
-      emacs_close (filefd);
-      report_file_error ("Opening process output file",
-                        Fcons (build_string (tempfile), Qnil));
+      if ((outf = egetenv ("TMPDIR")))
+       strcpy (tempfile = alloca (strlen (outf) + 20), outf);
+      else
+       {
+         tempfile = alloca (20);
+         *tempfile = '\0';
+       }
+      dostounix_filename (tempfile);
+      if (*tempfile == '\0' || tempfile[strlen (tempfile) - 1] != '/')
+       strcat (tempfile, "/");
+      strcat (tempfile, "detmp.XXX");
+      mktemp (tempfile);
+      outfilefd = creat (tempfile, S_IREAD | S_IWRITE);
+      if (outfilefd < 0) {
+       emacs_close (filefd);
+       report_file_error ("Opening process output file",
+                          Fcons (build_string (tempfile), Qnil));
+      }
     }
+  else
+    outfilefd = fd_output;
   fd[0] = filefd;
   fd[1] = outfilefd;
 #endif /* MSDOS */
@@ -488,7 +494,14 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS)  */)
     register char **save_environ = environ;
     register int fd1 = fd[1];
     int fd_error = fd1;
+#ifdef HAVE_WORKING_VFORK
+    sigset_t procmask;
+    sigset_t blocked;
+    struct sigaction sigpipe_action;
+#endif
 
+    if (fd_output >= 0)
+      fd1 = fd_output;
 #if 0  /* Some systems don't have sigblock.  */
     mask = sigblock (sigmask (SIGCHLD));
 #endif
@@ -508,11 +521,11 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS)  */)
     else if (STRINGP (error_file))
       {
 #ifdef DOS_NT
-       fd_error = emacs_open (SDATA (error_file),
+       fd_error = emacs_open (SSDATA (error_file),
                               O_WRONLY | O_TRUNC | O_CREAT | O_TEXT,
                               S_IREAD | S_IWRITE);
 #else  /* not DOS_NT */
-       fd_error = creat (SDATA (error_file), 0666);
+       fd_error = creat (SSDATA (error_file), 0666);
 #endif /* not DOS_NT */
       }
 
@@ -554,41 +567,87 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS)  */)
     if (fd_error != outfilefd)
       emacs_close (fd_error);
     fd1 = -1; /* No harm in closing that one!  */
-    /* Since CRLF is converted to LF within `decode_coding', we can
-       always open a file with binary mode.  */
-    fd[0] = emacs_open (tempfile, O_RDONLY | O_BINARY, 0);
-    if (fd[0] < 0)
+    if (tempfile)
       {
-       unlink (tempfile);
-       emacs_close (filefd);
-       report_file_error ("Cannot re-open temporary file", Qnil);
+       /* Since CRLF is converted to LF within `decode_coding', we
+          can always open a file with binary mode.  */
+       fd[0] = emacs_open (tempfile, O_RDONLY | O_BINARY, 0);
+       if (fd[0] < 0)
+         {
+           unlink (tempfile);
+           emacs_close (filefd);
+           report_file_error ("Cannot re-open temporary file",
+                              Fcons (build_string (tempfile), Qnil));
+         }
       }
+    else
+      fd[0] = -1; /* We are not going to read from tempfile.   */
 #else /* not MSDOS */
 #ifdef WINDOWSNT
     pid = child_setup (filefd, fd1, fd_error, (char **) new_argv,
                       0, current_dir);
 #else  /* not WINDOWSNT */
+
+#ifdef HAVE_WORKING_VFORK
+    /* On many hosts (e.g. Solaris 2.4), if a vforked child calls `signal',
+       this sets the parent's signal handlers as well as the child's.
+       So delay all interrupts whose handlers the child might munge,
+       and record the current handlers so they can be restored later.  */
+    sigemptyset (&blocked);
+    sigaddset (&blocked, SIGPIPE);
+    sigaction (SIGPIPE, 0, &sigpipe_action);
+    sigprocmask (SIG_BLOCK, &blocked, &procmask);
+#endif
+
     BLOCK_INPUT;
 
-    pid = vfork ();
+    /* vfork, and prevent local vars from being clobbered by the vfork.  */
+    {
+      int volatile fd_error_volatile = fd_error;
+      int volatile fd_output_volatile = fd_output;
+      int volatile output_to_buffer_volatile = output_to_buffer;
+      unsigned char const **volatile new_argv_volatile = new_argv;
+
+      pid = vfork ();
+
+      fd_error = fd_error_volatile;
+      fd_output = fd_output_volatile;
+      output_to_buffer = output_to_buffer_volatile;
+      new_argv = new_argv_volatile;
+    }
 
     if (pid == 0)
       {
        if (fd[0] >= 0)
          emacs_close (fd[0]);
 #ifdef HAVE_SETSID
-        setsid ();
+       setsid ();
 #endif
 #if defined (USG)
-        setpgrp ();
+       setpgrp ();
 #else
-        setpgrp (pid, pid);
+       setpgrp (pid, pid);
 #endif /* USG */
+
+       /* GConf causes us to ignore SIGPIPE, make sure it is restored
+          in the child.  */
+       //signal (SIGPIPE, SIG_DFL);
+#ifdef HAVE_WORKING_VFORK
+       sigprocmask (SIG_SETMASK, &procmask, 0);
+#endif
+
        child_setup (filefd, fd1, fd_error, (char **) new_argv,
                     0, current_dir);
       }
 
     UNBLOCK_INPUT;
+
+#ifdef HAVE_WORKING_VFORK
+    /* Restore the signal state.  */
+    sigaction (SIGPIPE, &sigpipe_action, 0);
+    sigprocmask (SIG_SETMASK, &procmask, 0);
+#endif
+
 #endif /* not WINDOWSNT */
 
     /* The MSDOS case did this already.  */
@@ -601,6 +660,8 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS)  */)
     /* Close most of our fd's, but not fd[0]
        since we will use that to read input from.  */
     emacs_close (filefd);
+    if (fd_output >= 0)
+      emacs_close (fd_output);
     if (fd1 >= 0 && fd1 != fd_error)
       emacs_close (fd1);
   }
@@ -616,12 +677,6 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS)  */)
     {
       if (fd[0] >= 0)
        emacs_close (fd[0]);
-#ifndef subprocesses
-      /* If Emacs has been built with asynchronous subprocess support,
-        we don't need to do this, I think because it will then have
-        the facilities for handling SIGCHLD.  */
-      wait_without_blocking ();
-#endif /* subprocesses */
       return Qnil;
     }
 
@@ -633,7 +688,7 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS)  */)
   record_unwind_protect (call_process_cleanup,
                         Fcons (Fcurrent_buffer (),
                                Fcons (make_number (fd[0]),
-                                      build_string (tempfile))));
+                                      build_string (tempfile ? tempfile : ""))));
 #else
   record_unwind_protect (call_process_cleanup,
                         Fcons (Fcurrent_buffer (),
@@ -661,9 +716,9 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS)  */)
        {
          if (EQ (coding_systems, Qt))
            {
-             int i;
+             ptrdiff_t i;
 
-             args2 = (Lisp_Object *) alloca ((nargs + 1) * sizeof *args2);
+             SAFE_ALLOCA (args2, Lisp_Object *, (nargs + 1) * sizeof *args2);
              args2[0] = Qcall_process;
              for (i = 0; i < nargs; i++) args2[i + 1] = args[i];
              coding_systems
@@ -680,7 +735,7 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS)  */)
       /* In unibyte mode, character code conversion should not take
         place but EOL conversion should.  So, setup raw-text or one
         of the subsidiary according to the information just setup.  */
-      if (NILP (current_buffer->enable_multibyte_characters)
+      if (NILP (BVAR (current_buffer, enable_multibyte_characters))
          && !NILP (val))
        val = raw_text_coding_system (val);
       setup_coding_system (val, &process_coding);
@@ -689,136 +744,141 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS)  */)
   immediate_quit = 1;
   QUIT;
 
-  {
-    register int nread;
-    int first = 1;
-    int total_read = 0;
-    int carryover = 0;
-    int display_on_the_fly = display_p;
-    struct coding_system saved_coding;
-
-    saved_coding = process_coding;
-    while (1)
-      {
-       /* Repeatedly read until we've filled as much as possible
-          of the buffer size we have.  But don't read
-          less than 1024--save that for the next bufferful.  */
-       nread = carryover;
-       while (nread < bufsize - 1024)
-         {
-           int this_read = emacs_read (fd[0], buf + nread,
-                                       bufsize - nread);
+  if (output_to_buffer)
+    {
+      register EMACS_INT nread;
+      int first = 1;
+      EMACS_INT total_read = 0;
+      int carryover = 0;
+      int display_p = display_p_volatile;
+      int display_on_the_fly = display_p;
+      struct coding_system saved_coding;
+
+      saved_coding = process_coding;
+      while (1)
+       {
+         /* Repeatedly read until we've filled as much as possible
+            of the buffer size we have.  But don't read
+            less than 1024--save that for the next bufferful.  */
+         nread = carryover;
+         while (nread < bufsize - 1024)
+           {
+             int this_read = emacs_read (fd[0], buf + nread,
+                                         bufsize - nread);
 
-           if (this_read < 0)
-             goto give_up;
+             if (this_read < 0)
+               goto give_up;
 
-           if (this_read == 0)
-             {
-               process_coding.mode |= CODING_MODE_LAST_BLOCK;
-               break;
-             }
+             if (this_read == 0)
+               {
+                 process_coding.mode |= CODING_MODE_LAST_BLOCK;
+                 break;
+               }
 
-           nread += this_read;
-           total_read += this_read;
+             nread += this_read;
+             total_read += this_read;
 
-           if (display_on_the_fly)
-             break;
-         }
+             if (display_on_the_fly)
+               break;
+           }
 
-       /* Now NREAD is the total amount of data in the buffer.  */
-       immediate_quit = 0;
+         /* Now NREAD is the total amount of data in the buffer.  */
+         immediate_quit = 0;
 
-       if (!NILP (buffer))
-         {
-           if (NILP (current_buffer->enable_multibyte_characters)
-               && ! CODING_MAY_REQUIRE_DECODING (&process_coding))
-             insert_1_both (buf, nread, nread, 0, 1, 0);
-           else
-             {                 /* We have to decode the input.  */
-               Lisp_Object curbuf;
-               int count1 = SPECPDL_INDEX ();
-
-               XSETBUFFER (curbuf, current_buffer);
-               /* We cannot allow after-change-functions be run
-                  during decoding, because that might modify the
-                  buffer, while we rely on process_coding.produced to
-                  faithfully reflect inserted text until we
-                  TEMP_SET_PT_BOTH below.  */
-               specbind (Qinhibit_modification_hooks, Qt);
-               decode_coding_c_string (&process_coding, buf, nread,
-                                       curbuf);
-               unbind_to (count1, Qnil);
-               if (display_on_the_fly
-                   && CODING_REQUIRE_DETECTION (&saved_coding)
-                   && ! CODING_REQUIRE_DETECTION (&process_coding))
-                 {
-                   /* We have detected some coding system.  But,
-                      there's a possibility that the detection was
-                      done by insufficient data.  So, we give up
-                      displaying on the fly.  */
-                   if (process_coding.produced > 0)
-                     del_range_2 (process_coding.dst_pos,
-                                  process_coding.dst_pos_byte,
-                                  process_coding.dst_pos
-                                  + process_coding.produced_char,
-                                  process_coding.dst_pos_byte
-                                  + process_coding.produced, 0);
-                   display_on_the_fly = 0;
-                   process_coding = saved_coding;
-                   carryover = nread;
-                   /* This is to make the above condition always
-                      fails in the future.  */
-                   saved_coding.common_flags
-                     &= ~CODING_REQUIRE_DETECTION_MASK;
-                   continue;
-                 }
-
-               TEMP_SET_PT_BOTH (PT + process_coding.produced_char,
-                                 PT_BYTE + process_coding.produced);
-               carryover = process_coding.carryover_bytes;
-               if (carryover > 0)
-                 /* As CARRYOVER should not be that large, we had
-                    better avoid overhead of bcopy.  */
-                 BCOPY_SHORT (process_coding.carryover, buf,
-                              process_coding.carryover_bytes);
-             }
-         }
+         if (!NILP (buffer))
+           {
+             if (NILP (BVAR (current_buffer, enable_multibyte_characters))
+                 && ! CODING_MAY_REQUIRE_DECODING (&process_coding))
+               insert_1_both (buf, nread, nread, 0, 1, 0);
+             else
+               {                       /* We have to decode the input.  */
+                 Lisp_Object curbuf;
+                 int count1 = SPECPDL_INDEX ();
+
+                 XSETBUFFER (curbuf, current_buffer);
+                 /* We cannot allow after-change-functions be run
+                    during decoding, because that might modify the
+                    buffer, while we rely on process_coding.produced to
+                    faithfully reflect inserted text until we
+                    TEMP_SET_PT_BOTH below.  */
+                 specbind (Qinhibit_modification_hooks, Qt);
+                 decode_coding_c_string (&process_coding,
+                                         (unsigned char *) buf, nread, curbuf);
+                 unbind_to (count1, Qnil);
+                 if (display_on_the_fly
+                     && CODING_REQUIRE_DETECTION (&saved_coding)
+                     && ! CODING_REQUIRE_DETECTION (&process_coding))
+                   {
+                     /* We have detected some coding system.  But,
+                        there's a possibility that the detection was
+                        done by insufficient data.  So, we give up
+                        displaying on the fly.  */
+                     if (process_coding.produced > 0)
+                       del_range_2 (process_coding.dst_pos,
+                                    process_coding.dst_pos_byte,
+                                    process_coding.dst_pos
+                                    + process_coding.produced_char,
+                                    process_coding.dst_pos_byte
+                                    + process_coding.produced, 0);
+                     display_on_the_fly = 0;
+                     process_coding = saved_coding;
+                     carryover = nread;
+                     /* This is to make the above condition always
+                        fails in the future.  */
+                     saved_coding.common_flags
+                       &= ~CODING_REQUIRE_DETECTION_MASK;
+                     continue;
+                   }
+
+                 TEMP_SET_PT_BOTH (PT + process_coding.produced_char,
+                                   PT_BYTE + process_coding.produced);
+                 carryover = process_coding.carryover_bytes;
+                 if (carryover > 0)
+                   memcpy (buf, process_coding.carryover,
+                           process_coding.carryover_bytes);
+               }
+           }
 
-       if (process_coding.mode & CODING_MODE_LAST_BLOCK)
-         break;
+         if (process_coding.mode & CODING_MODE_LAST_BLOCK)
+           break;
 
-       /* Make the buffer bigger as we continue to read more data,
-          but not past CALLPROC_BUFFER_SIZE_MAX.  */
-       if (bufsize < CALLPROC_BUFFER_SIZE_MAX && total_read > 32 * bufsize)
-         if ((bufsize *= 2) > CALLPROC_BUFFER_SIZE_MAX)
-           bufsize = CALLPROC_BUFFER_SIZE_MAX;
+         /* Make the buffer bigger as we continue to read more data,
+            but not past CALLPROC_BUFFER_SIZE_MAX.  */
+         if (bufsize < CALLPROC_BUFFER_SIZE_MAX && total_read > 32 * bufsize)
+           if ((bufsize *= 2) > CALLPROC_BUFFER_SIZE_MAX)
+             bufsize = CALLPROC_BUFFER_SIZE_MAX;
 
-       if (display_p)
-         {
-           if (first)
-             prepare_menu_bars ();
-           first = 0;
-           redisplay_preserve_echo_area (1);
-           /* This variable might have been set to 0 for code
-              detection.  In that case, we set it back to 1 because
-              we should have already detected a coding system.  */
-           display_on_the_fly = 1;
-         }
-       immediate_quit = 1;
-       QUIT;
-      }
-  give_up: ;
-
-    Vlast_coding_system_used = CODING_ID_NAME (process_coding.id);
-    /* If the caller required, let the buffer inherit the
-       coding-system used to decode the process output.  */
-    if (inherit_process_coding_system)
-      call1 (intern ("after-insert-file-set-buffer-file-coding-system"),
-            make_number (total_read));
-  }
+         if (display_p)
+           {
+             if (first)
+               prepare_menu_bars ();
+             first = 0;
+             redisplay_preserve_echo_area (1);
+             /* This variable might have been set to 0 for code
+                detection.  In that case, we set it back to 1 because
+                we should have already detected a coding system.  */
+             display_on_the_fly = 1;
+           }
+         immediate_quit = 1;
+         QUIT;
+       }
+    give_up: ;
+
+      Vlast_coding_system_used = CODING_ID_NAME (process_coding.id);
+      /* If the caller required, let the buffer inherit the
+        coding-system used to decode the process output.  */
+      if (inherit_process_coding_system)
+       call1 (intern ("after-insert-file-set-buffer-file-coding-system"),
+              make_number (total_read));
+    }
 
+#ifndef MSDOS
   /* Wait for it to terminate, unless it already has.  */
-  wait_for_termination (pid);
+  if (output_to_buffer)
+    wait_for_termination (pid);
+  else
+    interruptible_wait_for_termination (pid);
+#endif
 
   immediate_quit = 0;
 
@@ -826,17 +886,18 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS)  */)
      when exiting.  */
   call_process_exited = 1;
 
+  SAFE_FREE ();
   unbind_to (count, Qnil);
 
   if (synch_process_termsig)
     {
-      char *signame;
+      const char *signame;
 
       synchronize_system_messages_locale ();
       signame = strsignal (synch_process_termsig);
 
       if (signame == 0)
-        signame = "unknown";
+       signame = "unknown";
 
       synch_process_death = signame;
     }
@@ -848,8 +909,7 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS)  */)
 }
 \f
 static Lisp_Object
-delete_temp_file (name)
-     Lisp_Object name;
+delete_temp_file (Lisp_Object name)
 {
   /* Suppress jka-compr handling, etc.  */
   int count = SPECPDL_INDEX ();
@@ -865,8 +925,10 @@ DEFUN ("call-process-region", Fcall_process_region, Scall_process_region,
 The remaining arguments are optional.
 Delete the text if fourth arg DELETE is non-nil.
 
-Insert output in BUFFER before point; t means current buffer;
- nil for BUFFER means discard it; 0 means discard and don't wait.
+Insert output in BUFFER before point; t means current buffer; nil for
+ BUFFER means discard it; 0 means discard and don't wait; and `(:file
+ FILE)', where FILE is a file name string, means that it should be
+ written to that file.
 BUFFER can also have the form (REAL-BUFFER STDERR-FILE); in that case,
 REAL-BUFFER says what to do with standard output, as above,
 while STDERR-FILE says what to do with standard error in the child.
@@ -882,9 +944,7 @@ and returns a numeric exit status or a signal description string.
 If you quit, the process is killed with SIGINT, or SIGKILL if you quit again.
 
 usage: (call-process-region START END PROGRAM &optional DELETE BUFFER DISPLAY &rest ARGS)  */)
-     (nargs, args)
-     int nargs;
-     register Lisp_Object *args;
+  (ptrdiff_t nargs, Lisp_Object *args)
 {
   struct gcpro gcpro1;
   Lisp_Object filename_string;
@@ -893,7 +953,7 @@ usage: (call-process-region START END PROGRAM &optional DELETE BUFFER DISPLAY &r
   /* Qt denotes we have not yet called Ffind_operation_coding_system.  */
   Lisp_Object coding_systems;
   Lisp_Object val, *args2;
-  int i;
+  ptrdiff_t i;
   char *tempfile;
   Lisp_Object tmpdir, pattern;
 
@@ -917,50 +977,53 @@ usage: (call-process-region START END PROGRAM &optional DELETE BUFFER DISPLAY &r
 #endif
     }
 
-  pattern = Fexpand_file_name (Vtemp_file_name_pattern, tmpdir);
-  tempfile = (char *) alloca (SBYTES (pattern) + 1);
-  bcopy (SDATA (pattern), tempfile, SBYTES (pattern) + 1);
-  coding_systems = Qt;
+  {
+    USE_SAFE_ALLOCA;
+    pattern = Fexpand_file_name (Vtemp_file_name_pattern, tmpdir);
+    SAFE_ALLOCA (tempfile, char *, SBYTES (pattern) + 1);
+    memcpy (tempfile, SDATA (pattern), SBYTES (pattern) + 1);
+    coding_systems = Qt;
 
 #ifdef HAVE_MKSTEMP
- {
-   int fd;
-
-   BLOCK_INPUT;
-   fd = mkstemp (tempfile);
-   UNBLOCK_INPUT;
-   if (fd == -1)
-     report_file_error ("Failed to open temporary file",
-                       Fcons (Vtemp_file_name_pattern, Qnil));
-   else
-     close (fd);
- }
   {
+      int fd;
+
+      BLOCK_INPUT;
+      fd = mkstemp (tempfile);
+      UNBLOCK_INPUT;
+      if (fd == -1)
+       report_file_error ("Failed to open temporary file",
+                          Fcons (Vtemp_file_name_pattern, Qnil));
+      else
+       close (fd);
   }
 #else
-  mktemp (tempfile);
+    mktemp (tempfile);
 #endif
 
-  filename_string = build_string (tempfile);
-  GCPRO1 (filename_string);
+    filename_string = build_string (tempfile);
+    GCPRO1 (filename_string);
+    SAFE_FREE ();
+  }
+
   start = args[0];
   end = args[1];
   /* Decide coding-system of the contents of the temporary file.  */
   if (!NILP (Vcoding_system_for_write))
     val = Vcoding_system_for_write;
-  else if (NILP (current_buffer->enable_multibyte_characters))
-    val = Qnil;
+  else if (NILP (BVAR (current_buffer, enable_multibyte_characters)))
+    val = Qraw_text;
   else
     {
-      args2 = (Lisp_Object *) alloca ((nargs + 1) * sizeof *args2);
+      USE_SAFE_ALLOCA;
+      SAFE_ALLOCA (args2, Lisp_Object *, (nargs + 1) * sizeof *args2);
       args2[0] = Qcall_process_region;
       for (i = 0; i < nargs; i++) args2[i + 1] = args[i];
       coding_systems = Ffind_operation_coding_system (nargs + 1, args2);
-      if (CONSP (coding_systems))
-       val = XCDR (coding_systems);
-      else if (CONSP (Vdefault_process_coding_system))
-       val = XCDR (Vdefault_process_coding_system);
-      else
-       val = Qnil;
+      val = CONSP (coding_systems) ? XCDR (coding_systems) : Qnil;
+      SAFE_FREE ();
     }
+  val = complement_process_encoding_system (val);
 
   {
     int count1 = SPECPDL_INDEX ();
@@ -997,7 +1060,9 @@ usage: (call-process-region START END PROGRAM &optional DELETE BUFFER DISPLAY &r
   RETURN_UNGCPRO (unbind_to (count, Fcall_process (nargs, args)));
 }
 \f
-static int relocate_fd ();
+#ifndef WINDOWSNT
+static int relocate_fd (int fd, int minfd);
+#endif
 
 static char **
 add_env (char **env, char **new_env, char *string)
@@ -1015,18 +1080,18 @@ add_env (char **env, char **new_env, char *string)
     {
       char *p = *ep, *q = string;
       while (ok)
-        {
-          if (*q != *p)
-            break;
-          if (*q == 0)
-            /* The string is a lone variable name; keep it for now, we
-               will remove it later.  It is a placeholder for a
-               variable that is not to be included in the environment.  */
-            break;
-          if (*q == '=')
-            ok = 0;
-          p++, q++;
-        }
+       {
+         if (*q != *p)
+           break;
+         if (*q == 0)
+           /* The string is a lone variable name; keep it for now, we
+              will remove it later.  It is a placeholder for a
+              variable that is not to be included in the environment.  */
+           break;
+         if (*q == '=')
+           ok = 0;
+         p++, q++;
+       }
     }
   if (ok)
     *new_env++ = string;
@@ -1052,11 +1117,7 @@ add_env (char **env, char **new_env, char *string)
    executable directory by the parent.  */
 
 int
-child_setup (in, out, err, new_argv, set_pgrp, current_dir)
-     int in, out, err;
-     register char **new_argv;
-     int set_pgrp;
-     Lisp_Object current_dir;
+child_setup (int in, int out, int err, register char **new_argv, int set_pgrp, Lisp_Object current_dir)
 {
   char **env;
   char *pwd_var;
@@ -1067,19 +1128,9 @@ child_setup (in, out, err, new_argv, set_pgrp, current_dir)
 
   int pid = getpid ();
 
-#ifdef SET_EMACS_PRIORITY
-  {
-    extern EMACS_INT emacs_priority;
-
-    if (emacs_priority < 0)
-      nice (- emacs_priority);
-  }
-#endif
-
-#ifdef subprocesses
   /* Close Emacs's descriptors that this process should not have.  */
   close_process_descs ();
-#endif
+
   /* DOS_NT isn't in a vfork, so if we are in the middle of load-file,
      we will lose if we call close_load_descs here.  */
 #ifndef DOS_NT
@@ -1106,8 +1157,8 @@ child_setup (in, out, err, new_argv, set_pgrp, current_dir)
     pwd_var = (char *) alloca (i + 6);
 #endif
     temp = pwd_var + 4;
-    bcopy ("PWD=", pwd_var, 4);
-    bcopy (SDATA (current_dir), temp, i);
+    memcpy (pwd_var, "PWD=", 4);
+    memcpy (temp, SDATA (current_dir), i);
     if (!IS_DIRECTORY_SEP (temp[i - 1])) temp[i++] = DIRECTORY_SEP;
     temp[i] = 0;
 
@@ -1140,14 +1191,14 @@ child_setup (in, out, err, new_argv, set_pgrp, current_dir)
     char **p, **q;
     register int new_length;
     Lisp_Object display = Qnil;
-    
+
     new_length = 0;
 
     for (tem = Vprocess_environment;
-         CONSP (tem) && STRINGP (XCAR (tem));
-         tem = XCDR (tem))
+        CONSP (tem) && STRINGP (XCAR (tem));
+        tem = XCDR (tem))
       {
-       if (strncmp (SDATA (XCAR (tem)), "DISPLAY", 7) == 0
+       if (strncmp (SSDATA (XCAR (tem)), "DISPLAY", 7) == 0
            && (SDATA (XCAR (tem)) [7] == '\0'
                || SDATA (XCAR (tem)) [7] == '='))
          /* DISPLAY is specified in process-environment.  */
@@ -1176,13 +1227,12 @@ child_setup (in, out, err, new_argv, set_pgrp, current_dir)
        but with corrected value.  */
     if (egetenv ("PWD"))
       *new_env++ = pwd_var;
+
     if (STRINGP (display))
       {
-       int vlen = strlen ("DISPLAY=") + strlen (SDATA (display)) + 1;
-       char *vdata = (char *) alloca (vlen);
+       char *vdata = (char *) alloca (sizeof "DISPLAY=" + SBYTES (display));
        strcpy (vdata, "DISPLAY=");
-       strcat (vdata, SDATA (display));
+       strcat (vdata, SSDATA (display));
        new_env = add_env (env, new_env, vdata);
       }
 
@@ -1190,7 +1240,7 @@ child_setup (in, out, err, new_argv, set_pgrp, current_dir)
     for (tem = Vprocess_environment;
         CONSP (tem) && STRINGP (XCAR (tem));
         tem = XCDR (tem))
-      new_env = add_env (env, new_env, SDATA (XCAR (tem)));
+      new_env = add_env (env, new_env, SSDATA (XCAR (tem)));
 
     *new_env = 0;
 
@@ -1198,18 +1248,26 @@ child_setup (in, out, err, new_argv, set_pgrp, current_dir)
     p = q = env;
     while (*p != 0)
       {
-        while (*q != 0 && strchr (*q, '=') == NULL)
-          q++;
-        *p = *q++;
-        if (*p != 0)
-          p++;
+       while (*q != 0 && strchr (*q, '=') == NULL)
+         q++;
+       *p = *q++;
+       if (*p != 0)
+         p++;
       }
   }
 
-  
+
 #ifdef WINDOWSNT
   prepare_standard_handles (in, out, err, handles);
   set_process_dir (SDATA (current_dir));
+  /* Spawn the child.  (See ntproc.c:Spawnve).  */
+  cpid = spawnve (_P_NOWAIT, new_argv[0], new_argv, env);
+  reset_standard_handles (in, out, err, handles);
+  if (cpid == -1)
+    /* An error occurred while trying to spawn the process.  */
+    report_file_error ("Spawning child process", Qnil);
+  return cpid;
+
 #else  /* not WINDOWSNT */
   /* Make sure that in, out, and err are not actually already in
      descriptors zero, one, or two; this could happen if Emacs is
@@ -1248,36 +1306,18 @@ child_setup (in, out, err, new_argv, set_pgrp, current_dir)
     emacs_close (out);
   if (err != in && err != out)
     emacs_close (err);
-#endif /* not MSDOS */
-#endif /* not WINDOWSNT */
 
 #if defined(USG)
 #ifndef SETPGRP_RELEASES_CTTY
   setpgrp ();                  /* No arguments but equivalent in this case */
 #endif
-#else
+#else /* not USG */
   setpgrp (pid, pid);
-#endif /* USG */
+#endif /* not USG */
+
   /* setpgrp_of_tty is incorrect here; it uses input_fd.  */
-  EMACS_SET_TTY_PGRP (0, &pid);
+  tcsetpgrp (0, pid);
 
-#ifdef MSDOS
-  pid = run_msdos_command (new_argv, pwd_var + 4, in, out, err, env);
-  xfree (pwd_var);
-  if (pid == -1)
-    /* An error occurred while trying to run the subprocess.  */
-    report_file_error ("Spawning child process", Qnil);
-  return pid;
-#else  /* not MSDOS */
-#ifdef WINDOWSNT
-  /* Spawn the child.  (See ntproc.c:Spawnve).  */
-  cpid = spawnve (_P_NOWAIT, new_argv[0], new_argv, env);
-  reset_standard_handles (in, out, err, handles);
-  if (cpid == -1)
-    /* An error occurred while trying to spawn the process.  */
-    report_file_error ("Spawning child process", Qnil);
-  return cpid;
-#else /* not WINDOWSNT */
   /* execvp does not accept an environment arg so the only way
      to pass this environment is to set environ.  Our caller
      is responsible for restoring the ambient value of environ.  */
@@ -1288,46 +1328,57 @@ child_setup (in, out, err, new_argv, set_pgrp, current_dir)
   emacs_write (1, new_argv[0], strlen (new_argv[0]));
   emacs_write (1, "\n", 1);
   _exit (1);
-#endif /* not WINDOWSNT */
-#endif /* not MSDOS */
+
+#else /* MSDOS */
+  pid = run_msdos_command (new_argv, pwd_var + 4, in, out, err, env);
+  xfree (pwd_var);
+  if (pid == -1)
+    /* An error occurred while trying to run the subprocess.  */
+    report_file_error ("Spawning child process", Qnil);
+  return pid;
+#endif  /* MSDOS */
+#endif  /* not WINDOWSNT */
 }
 
+#ifndef WINDOWSNT
 /* Move the file descriptor FD so that its number is not less than MINFD.
    If the file descriptor is moved at all, the original is freed.  */
 static int
-relocate_fd (fd, minfd)
-     int fd, minfd;
+relocate_fd (int fd, int minfd)
 {
   if (fd >= minfd)
     return fd;
   else
     {
-      int new = dup (fd);
+      int new;
+#ifdef F_DUPFD
+      new = fcntl (fd, F_DUPFD, minfd);
+#else
+      new = dup (fd);
+      if (new != -1)
+       /* Note that we hold the original FD open while we recurse,
+          to guarantee we'll get a new FD if we need it.  */
+       new = relocate_fd (new, minfd);
+#endif
       if (new == -1)
        {
-         char *message1 = "Error while setting up child: ";
-         char *errmessage = strerror (errno);
-         char *message2 = "\n";
-         emacs_write (2, message1, strlen (message1));
+         const char *message_1 = "Error while setting up child: ";
+         const char *errmessage = strerror (errno);
+         const char *message_2 = "\n";
+         emacs_write (2, message_1, strlen (message_1));
          emacs_write (2, errmessage, strlen (errmessage));
-         emacs_write (2, message2, strlen (message2));
+         emacs_write (2, message_2, strlen (message_2));
          _exit (1);
        }
-      /* Note that we hold the original FD open while we recurse,
-        to guarantee we'll get a new FD if we need it.  */
-      new = relocate_fd (new, minfd);
       emacs_close (fd);
       return new;
     }
 }
+#endif /* not WINDOWSNT */
 
 static int
-getenv_internal_1 (var, varlen, value, valuelen, env)
-     char *var;
-     int varlen;
-     char **value;
-     int *valuelen;
-     Lisp_Object env;
+getenv_internal_1 (const char *var, ptrdiff_t varlen, char **value,
+                  ptrdiff_t *valuelen, Lisp_Object env)
 {
   for (; CONSP (env); env = XCDR (env))
     {
@@ -1338,13 +1389,13 @@ getenv_internal_1 (var, varlen, value, valuelen, env)
          /* NT environment variables are case insensitive.  */
          && ! strnicmp (SDATA (entry), var, varlen)
 #else  /* not WINDOWSNT */
-         && ! bcmp (SDATA (entry), var, varlen)
+         && ! memcmp (SDATA (entry), var, varlen)
 #endif /* not WINDOWSNT */
          )
        {
          if (SBYTES (entry) > varlen && SREF (entry, varlen) == '=')
            {
-             *value = (char *) SDATA (entry) + (varlen + 1);
+             *value = SSDATA (entry) + (varlen + 1);
              *valuelen = SBYTES (entry) - (varlen + 1);
              return 1;
            }
@@ -1361,12 +1412,8 @@ getenv_internal_1 (var, varlen, value, valuelen, env)
 }
 
 static int
-getenv_internal (var, varlen, value, valuelen, frame)
-     char *var;
-     int varlen;
-     char **value;
-     int *valuelen;
-     Lisp_Object frame;
+getenv_internal (const char *var, ptrdiff_t varlen, char **value,
+                ptrdiff_t *valuelen, Lisp_Object frame)
 {
   /* Try to find VAR in Vprocess_environment first.  */
   if (getenv_internal_1 (var, varlen, value, valuelen,
@@ -1380,7 +1427,7 @@ getenv_internal (var, varlen, value, valuelen, frame)
        = Fframe_parameter (NILP (frame) ? selected_frame : frame, Qdisplay);
       if (STRINGP (display))
        {
-         *value    = (char *) SDATA (display);
+         *value    = SSDATA (display);
          *valuelen = SBYTES (display);
          return 1;
        }
@@ -1403,22 +1450,21 @@ This function searches `process-environment' for VARIABLE.
 If optional parameter ENV is a list, then search this list instead of
 `process-environment', and return t when encountering a negative entry
 \(an entry for a variable with no value).  */)
-     (variable, env)
-     Lisp_Object variable, env;
+  (Lisp_Object variable, Lisp_Object env)
 {
   char *value;
-  int valuelen;
+  ptrdiff_t valuelen;
 
   CHECK_STRING (variable);
   if (CONSP (env))
     {
-      if (getenv_internal_1 (SDATA (variable), SBYTES (variable),
+      if (getenv_internal_1 (SSDATA (variable), SBYTES (variable),
                             &value, &valuelen, env))
        return value ? make_string (value, valuelen) : Qt;
       else
        return Qnil;
     }
-  else if (getenv_internal (SDATA (variable), SBYTES (variable),
+  else if (getenv_internal (SSDATA (variable), SBYTES (variable),
                            &value, &valuelen, env))
     return make_string (value, valuelen);
   else
@@ -1428,11 +1474,10 @@ If optional parameter ENV is a list, then search this list instead of
 /* A version of getenv that consults the Lisp environment lists,
    easily callable from C.  */
 char *
-egetenv (var)
-     char *var;
+egetenv (const char *var)
 {
   char *value;
-  int valuelen;
+  ptrdiff_t valuelen;
 
   if (getenv_internal (var, strlen (var), &value, &valuelen, Qnil))
     return value;
@@ -1444,7 +1489,7 @@ egetenv (var)
 /* This is run before init_cmdargs.  */
 
 void
-init_callproc_1 ()
+init_callproc_1 (void)
 {
   char *data_dir = egetenv ("EMACSDATA");
   char *doc_dir = egetenv ("EMACSDOC");
@@ -1466,7 +1511,7 @@ init_callproc_1 ()
 /* This is run after init_cmdargs, when Vinstallation_directory is valid.  */
 
 void
-init_callproc ()
+init_callproc (void)
 {
   char *data_dir = egetenv ("EMACSDATA");
 
@@ -1532,13 +1577,13 @@ init_callproc ()
 #endif
     {
       tempdir = Fdirectory_file_name (Vexec_directory);
-      if (access (SDATA (tempdir), 0) < 0)
+      if (access (SSDATA (tempdir), 0) < 0)
        dir_warning ("Warning: arch-dependent data dir (%s) does not exist.\n",
                     Vexec_directory);
     }
 
   tempdir = Fdirectory_file_name (Vdata_directory);
-  if (access (SDATA (tempdir), 0) < 0)
+  if (access (SSDATA (tempdir), 0) < 0)
     dir_warning ("Warning: arch-independent data dir (%s) does not exist.\n",
                 Vdata_directory);
 
@@ -1555,33 +1600,20 @@ init_callproc ()
 }
 
 void
-set_initial_environment ()
+set_initial_environment (void)
 {
-  register char **envp;
-#ifndef CANNOT_DUMP
-  if (initialized)
-    {
-#else
-    {
-      Vprocess_environment = Qnil;
-#endif
-      for (envp = environ; *envp; envp++)
-       Vprocess_environment = Fcons (build_string (*envp),
-                                     Vprocess_environment);
-      /* Ideally, the `copy' shouldn't be necessary, but it seems it's frequent
-        to use `delete' and friends on process-environment.  */
-      Vinitial_environment = Fcopy_sequence (Vprocess_environment);
-    }
+  char **envp;
+  for (envp = environ; *envp; envp++)
+    Vprocess_environment = Fcons (build_string (*envp),
+                                 Vprocess_environment);
+  /* Ideally, the `copy' shouldn't be necessary, but it seems it's frequent
+     to use `delete' and friends on process-environment.  */
+  Vinitial_environment = Fcopy_sequence (Vprocess_environment);
 }
 
 void
-syms_of_callproc ()
+syms_of_callproc (void)
 {
-#ifdef DOS_NT
-  Qbuffer_file_type = intern ("buffer-file-type");
-  staticpro (&Qbuffer_file_type);
-#endif /* DOS_NT */
-
 #ifndef DOS_NT
   Vtemp_file_name_pattern = build_string ("emacsXXXXXX");
 #elif defined (WINDOWSNT)
@@ -1591,41 +1623,41 @@ syms_of_callproc ()
 #endif
   staticpro (&Vtemp_file_name_pattern);
 
-  DEFVAR_LISP ("shell-file-name", &Vshell_file_name,
+  DEFVAR_LISP ("shell-file-name", Vshell_file_name,
               doc: /* *File name to load inferior shells from.
 Initialized from the SHELL environment variable, or to a system-dependent
 default if SHELL is not set.  */);
 
-  DEFVAR_LISP ("exec-path", &Vexec_path,
+  DEFVAR_LISP ("exec-path", Vexec_path,
               doc: /* *List of directories to search programs to run in subprocesses.
 Each element is a string (directory name) or nil (try default directory).  */);
 
-  DEFVAR_LISP ("exec-suffixes", &Vexec_suffixes,
+  DEFVAR_LISP ("exec-suffixes", Vexec_suffixes,
               doc: /* *List of suffixes to try to find executable file names.
 Each element is a string.  */);
   Vexec_suffixes = Qnil;
 
-  DEFVAR_LISP ("exec-directory", &Vexec_directory,
+  DEFVAR_LISP ("exec-directory", Vexec_directory,
               doc: /* Directory for executables for Emacs to invoke.
 More generally, this includes any architecture-dependent files
 that are built and installed from the Emacs distribution.  */);
 
-  DEFVAR_LISP ("data-directory", &Vdata_directory,
+  DEFVAR_LISP ("data-directory", Vdata_directory,
               doc: /* Directory of machine-independent files that come with GNU Emacs.
 These are files intended for Emacs to use while it runs.  */);
 
-  DEFVAR_LISP ("doc-directory", &Vdoc_directory,
+  DEFVAR_LISP ("doc-directory", Vdoc_directory,
               doc: /* Directory containing the DOC file that comes with GNU Emacs.
 This is usually the same as `data-directory'.  */);
 
-  DEFVAR_LISP ("configure-info-directory", &Vconfigure_info_directory,
+  DEFVAR_LISP ("configure-info-directory", Vconfigure_info_directory,
               doc: /* For internal use by the build procedure only.
 This is the name of the directory in which the build procedure installed
 Emacs's info files; the default value for `Info-default-directory-list'
 includes this.  */);
   Vconfigure_info_directory = build_string (PATH_INFO);
 
-  DEFVAR_LISP ("shared-game-score-directory", &Vshared_game_score_directory,
+  DEFVAR_LISP ("shared-game-score-directory", Vshared_game_score_directory,
               doc: /* Directory of score files for games which come with GNU Emacs.
 If this variable is nil, then Emacs is unable to use a shared directory.  */);
 #ifdef DOS_NT
@@ -1634,13 +1666,13 @@ If this variable is nil, then Emacs is unable to use a shared directory.  */);
   Vshared_game_score_directory = build_string (PATH_GAME);
 #endif
 
-  DEFVAR_LISP ("initial-environment", &Vinitial_environment,
+  DEFVAR_LISP ("initial-environment", Vinitial_environment,
               doc: /* List of environment variables inherited from the parent process.
 Each element should be a string of the form ENVVARNAME=VALUE.
 The elements must normally be decoded (using `locale-coding-system') for use.  */);
   Vinitial_environment = Qnil;
 
-  DEFVAR_LISP ("process-environment", &Vprocess_environment,
+  DEFVAR_LISP ("process-environment", Vprocess_environment,
               doc: /* List of overridden environment variables for subprocesses to inherit.
 Each element should be a string of the form ENVVARNAME=VALUE.
 
@@ -1667,6 +1699,3 @@ See `setenv' and `getenv'.  */);
   defsubr (&Sgetenv_internal);
   defsubr (&Scall_process_region);
 }
-
-/* arch-tag: 769b8045-1df7-4d2b-8968-e3fb49017f95
-   (do not change this comment) */