ff28a498243fda0756cc74aec8a7a7e0662fcebe
[chise/xemacs-chise.git.1] / src / callproc.c
1 /* Old synchronous subprocess invocation for XEmacs.
2    Copyright (C) 1985, 86, 87, 88, 93, 94, 95 Free Software Foundation, Inc.
3
4 This file is part of XEmacs.
5
6 XEmacs is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
9 later version.
10
11 XEmacs is distributed in the hope that it will be useful, but WITHOUT
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with XEmacs; see the file COPYING.  If not, write to
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA.  */
20
21 /* Synched up with: Mule 2.0, FSF 19.30. */
22 /* Partly sync'ed with 19.36.4 */
23
24
25 /* #### This ENTIRE file is only used in batch mode.
26
27    We only need two things to get rid of both this and ntproc.c:
28
29    -- my `stderr-proc' ws, which adds support for a separate stderr
30       in asynch. subprocesses. (it's a feature in `old-call-process-internal'.)
31    -- a noninteractive event loop that supports processes.
32 */
33
34 #include <config.h>
35 #include "lisp.h"
36
37 #include "buffer.h"
38 #include "commands.h"
39 #include "insdel.h"
40 #include "lstream.h"
41 #include "process.h"
42 #include "sysdep.h"
43 #include "window.h"
44 #ifdef FILE_CODING
45 #include "file-coding.h"
46 #endif
47
48 #include "systime.h"
49 #include "sysproc.h"
50 #include "sysfile.h" /* Always include after sysproc.h */
51 #include "syssignal.h" /* Always include before systty.h */
52 #include "systty.h"
53
54 #ifdef WIN32_NATIVE
55 #define _P_NOWAIT 1     /* from process.h */
56 #include "nt.h"
57 #endif
58
59 #ifdef WIN32_NATIVE
60 /* When we are starting external processes we need to know whether they
61    take binary input (no conversion) or text input (\n is converted to
62    \r\n).  Similarly for output: if newlines are written as \r\n then it's
63    text process output, otherwise it's binary.  */
64 Lisp_Object Vbinary_process_input;
65 Lisp_Object Vbinary_process_output;
66 #endif /* WIN32_NATIVE */
67
68 Lisp_Object Vshell_file_name;
69
70 /* The environment to pass to all subprocesses when they are started.
71    This is in the semi-bogus format of ("VAR=VAL" "VAR2=VAL2" ... )
72  */
73 Lisp_Object Vprocess_environment;
74
75 /* True iff we are about to fork off a synchronous process or if we
76    are waiting for it.  */
77 volatile int synch_process_alive;
78
79 /* Nonzero => this is a string explaining death of synchronous subprocess.  */
80 const char *synch_process_death;
81
82 /* If synch_process_death is zero,
83    this is exit code of synchronous subprocess.  */
84 int synch_process_retcode;
85 \f
86 /* Clean up when exiting Fcall_process_internal.
87    On Windows, delete the temporary file on any kind of termination.
88    On Unix, kill the process and any children on termination by signal.  */
89
90 /* Nonzero if this is termination due to exit.  */
91 static int call_process_exited;
92
93 Lisp_Object Vlisp_EXEC_SUFFIXES;
94
95 static Lisp_Object
96 call_process_kill (Lisp_Object fdpid)
97 {
98   Lisp_Object fd = Fcar (fdpid);
99   Lisp_Object pid = Fcdr (fdpid);
100
101   if (!NILP (fd))
102     close (XINT (fd));
103
104   if (!NILP (pid))
105     EMACS_KILLPG (XINT (pid), SIGKILL);
106
107   synch_process_alive = 0;
108   return Qnil;
109 }
110
111 static Lisp_Object
112 call_process_cleanup (Lisp_Object fdpid)
113 {
114   int fd  = XINT (Fcar (fdpid));
115   int pid = XINT (Fcdr (fdpid));
116
117   if (!call_process_exited &&
118       EMACS_KILLPG (pid, SIGINT) == 0)
119   {
120     int speccount = specpdl_depth ();
121
122     record_unwind_protect (call_process_kill, fdpid);
123     /* #### "c-G" -- need non-consing Single-key-description */
124     message ("Waiting for process to die...(type C-g again to kill it instantly)");
125
126 #ifdef WIN32_NATIVE
127     {
128       HANDLE pHandle = OpenProcess (PROCESS_ALL_ACCESS, 0, pid);
129       if (pHandle == NULL)
130         warn_when_safe (Qprocess, Qwarning,
131                         "cannot open process (PID %d) for cleanup", pid);
132       else
133         wait_for_termination (pHandle);
134     }
135 #else
136     wait_for_termination (pid);
137 #endif
138
139     /* "Discard" the unwind protect.  */
140     XCAR (fdpid) = Qnil;
141     XCDR (fdpid) = Qnil;
142     unbind_to (speccount, Qnil);
143
144     message ("Waiting for process to die... done");
145   }
146   synch_process_alive = 0;
147   close (fd);
148   return Qnil;
149 }
150
151 static Lisp_Object fork_error;
152 #if 0 /* UNUSED */
153 static void
154 report_fork_error (char *string, Lisp_Object data)
155 {
156   Lisp_Object errstring = lisp_strerror (errno);
157
158   fork_error = Fcons (build_string (string), Fcons (errstring, data));
159
160   /* terminate this branch of the fork, without closing stdin/out/etc. */
161   _exit (1);
162 }
163 #endif /* unused */
164
165 DEFUN ("old-call-process-internal", Fold_call_process_internal, 1, MANY, 0, /*
166 Call PROGRAM synchronously in separate process, with coding-system specified.
167 Arguments are
168  (PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS).
169 The program's input comes from file INFILE (nil means `/dev/null').
170 Insert output in BUFFER before point; t means current buffer;
171  nil for BUFFER means discard it; 0 means discard and don't wait.
172 BUFFER can also have the form (REAL-BUFFER STDERR-FILE); in that case,
173 REAL-BUFFER says what to do with standard output, as above,
174 while STDERR-FILE says what to do with standard error in the child.
175 STDERR-FILE may be nil (discard standard error output),
176 t (mix it with ordinary output), or a file name string.
177
178 Fourth arg DISPLAY non-nil means redisplay buffer as output is inserted.
179 Remaining arguments are strings passed as command arguments to PROGRAM.
180
181 If BUFFER is 0, `call-process' returns immediately with value nil.
182 Otherwise it waits for PROGRAM to terminate and returns a numeric exit status
183  or a signal description string.
184 If you quit, the process is killed with SIGINT, or SIGKILL if you
185  quit again.
186 */
187        (int nargs, Lisp_Object *args))
188 {
189   /* This function can GC */
190   Lisp_Object infile, buffer, current_dir, display, path;
191   int fd[2];
192   int filefd;
193 #ifdef WIN32_NATIVE
194   HANDLE pHandle;
195 #endif
196   int pid;
197   char buf[16384];
198   char *bufptr = buf;
199   int bufsize = 16384;
200   int speccount = specpdl_depth ();
201   struct gcpro gcpro1, gcpro2, gcpro3;
202   char **new_argv = alloca_array (char *, max (2, nargs - 2));
203
204   /* File to use for stderr in the child.
205      t means use same as standard output.  */
206   Lisp_Object error_file;
207
208   CHECK_STRING (args[0]);
209
210   error_file = Qt;
211
212 #if defined (NO_SUBPROCESSES)
213   /* Without asynchronous processes we cannot have BUFFER == 0.  */
214   if (nargs >= 3 && !INTP (args[2]))
215     error ("Operating system cannot handle asynchronous subprocesses");
216 #endif /* NO_SUBPROCESSES */
217
218   /* Do this before building new_argv because GC in Lisp code
219    *  called by various filename-hacking routines might relocate strings */
220   locate_file (Vexec_path, args[0], Vlisp_EXEC_SUFFIXES, &path, X_OK);
221
222   /* Make sure that the child will be able to chdir to the current
223      buffer's current directory, or its unhandled equivalent.  We
224      can't just have the child check for an error when it does the
225      chdir, since it's in a vfork. */
226   {
227     struct gcpro ngcpro1, ngcpro2;
228     /* Do this test before building new_argv because GC in Lisp code
229      *  called by various filename-hacking routines might relocate strings */
230     /* Make sure that the child will be able to chdir to the current
231        buffer's current directory.  We can't just have the child check
232        for an error when it does the chdir, since it's in a vfork.  */
233
234     current_dir = current_buffer->directory;
235     NGCPRO2 (current_dir, path);   /* Caller gcprotects args[] */
236     current_dir = Funhandled_file_name_directory (current_dir);
237     current_dir = expand_and_dir_to_file (current_dir, Qnil);
238 #if 0
239     /* This is in FSF, but it breaks everything in the presence of
240        ange-ftp-visited files, so away with it.  */
241     if (NILP (Ffile_accessible_directory_p (current_dir)))
242       report_file_error ("Setting current directory",
243                          Fcons (current_buffer->directory, Qnil));
244 #endif /* 0 */
245     NUNGCPRO;
246   }
247
248   GCPRO2 (current_dir, path);
249
250   if (nargs >= 2 && ! NILP (args[1]))
251     {
252       struct gcpro ngcpro1;
253       NGCPRO1 (current_buffer->directory);
254       infile = Fexpand_file_name (args[1], current_buffer->directory);
255       NUNGCPRO;
256       CHECK_STRING (infile);
257     }
258   else
259     infile = build_string (NULL_DEVICE);
260
261   UNGCPRO;
262
263   GCPRO3 (infile, current_dir, path);   /* Fexpand_file_name might trash it */
264
265   if (nargs >= 3)
266     {
267       buffer = args[2];
268
269       /* If BUFFER is a list, its meaning is
270          (BUFFER-FOR-STDOUT FILE-FOR-STDERR).  */
271       if (CONSP (buffer))
272         {
273           if (CONSP (XCDR (buffer)))
274             {
275               Lisp_Object file_for_stderr = XCAR (XCDR (buffer));
276
277               if (NILP (file_for_stderr) || EQ (Qt, file_for_stderr))
278                 error_file = file_for_stderr;
279               else
280                 error_file = Fexpand_file_name (file_for_stderr, Qnil);
281             }
282
283           buffer = XCAR (buffer);
284         }
285
286       if (!(EQ (buffer, Qnil)
287             || EQ (buffer, Qt)
288             || ZEROP (buffer)))
289         {
290           Lisp_Object spec_buffer = buffer;
291           buffer = Fget_buffer (buffer);
292           /* Mention the buffer name for a better error message.  */
293           if (NILP (buffer))
294             CHECK_BUFFER (spec_buffer);
295           CHECK_BUFFER (buffer);
296         }
297     }
298   else
299     buffer = Qnil;
300
301   UNGCPRO;
302
303   display = ((nargs >= 4) ? args[3] : Qnil);
304
305   /* From here we assume we won't GC (unless an error is signaled). */
306   {
307     REGISTER int i;
308     for (i = 4; i < nargs; i++)
309       {
310         CHECK_STRING (args[i]);
311         new_argv[i - 3] = (char *) XSTRING_DATA (args[i]);
312       }
313   }
314   new_argv[max(nargs - 3,1)] = 0;
315
316   if (NILP (path))
317     report_file_error ("Searching for program", Fcons (args[0], Qnil));
318   new_argv[0] = (char *) XSTRING_DATA (path);
319
320   filefd = open ((char *) XSTRING_DATA (infile), O_RDONLY | OPEN_BINARY, 0);
321   if (filefd < 0)
322     report_file_error ("Opening process input file", Fcons (infile, Qnil));
323
324   if (INTP (buffer))
325     {
326       fd[1] = open (NULL_DEVICE, O_WRONLY | OPEN_BINARY, 0);
327       fd[0] = -1;
328     }
329   else
330     {
331       pipe (fd);
332 #if 0
333       /* Replaced by close_process_descs */
334       set_exclusive_use (fd[0]);
335 #endif
336     }
337
338   {
339     /* child_setup must clobber environ in systems with true vfork.
340        Protect it from permanent change.  */
341     REGISTER char **save_environ = environ;
342     REGISTER int fd1 = fd[1];
343     int fd_error = fd1;
344
345     /* Record that we're about to create a synchronous process.  */
346     synch_process_alive = 1;
347
348     /* These vars record information from process termination.
349        Clear them now before process can possibly terminate,
350        to avoid timing error if process terminates soon.  */
351     synch_process_death = 0;
352     synch_process_retcode = 0;
353
354     if (NILP (error_file))
355       fd_error = open (NULL_DEVICE, O_WRONLY | OPEN_BINARY);
356     else if (STRINGP (error_file))
357       {
358         fd_error = open ((const char *) XSTRING_DATA (error_file),
359 #ifdef WIN32_NATIVE
360                          O_WRONLY | O_TRUNC | O_CREAT | O_TEXT,
361                          S_IREAD | S_IWRITE
362 #else  /* not WIN32_NATIVE */
363                          O_WRONLY | O_TRUNC | O_CREAT | OPEN_BINARY,
364                          CREAT_MODE
365 #endif /* not WIN32_NATIVE */
366                          );
367       }
368
369     if (fd_error < 0)
370       {
371         int save_errno = errno;
372         close (filefd);
373         close (fd[0]);
374         if (fd1 >= 0)
375           close (fd1);
376         errno = save_errno;
377         report_file_error ("Cannot open", Fcons(error_file, Qnil));
378       }
379
380     fork_error = Qnil;
381 #ifdef WIN32_NATIVE
382     pid = child_setup (filefd, fd1, fd_error, new_argv,
383                        (char *) XSTRING_DATA (current_dir));
384     if (!INTP (buffer))
385       {
386         /* OpenProcess() as soon after child_setup as possible.  It's too
387            late once the process terminated. */
388         pHandle = OpenProcess(PROCESS_ALL_ACCESS, 0, pid);
389 #if 0
390         if (pHandle == NULL)
391           {
392             /* #### seems to cause crash in unbind_to(...) below. APA */
393             warn_when_safe (Qprocess, Qwarning,
394                             "cannot open process to wait for");
395           }
396 #endif
397       }
398     /* Close STDERR into the parent process.  We no longer need it. */
399     if (fd_error >= 0)
400       close (fd_error);
401 #else  /* not WIN32_NATIVE */
402     pid = fork ();
403
404     if (pid == 0)
405       {
406         if (fd[0] >= 0)
407           close (fd[0]);
408         /* This is necessary because some shells may attempt to
409            access the current controlling terminal and will hang
410            if they are run in the background, as will be the case
411            when XEmacs is started in the background.  Martin
412            Buchholz observed this problem running a subprocess
413            that used zsh to call gzip to uncompress an info
414            file. */
415         disconnect_controlling_terminal ();
416         child_setup (filefd, fd1, fd_error, new_argv,
417                      (char *) XSTRING_DATA (current_dir));
418       }
419     if (fd_error >= 0)
420       close (fd_error);
421
422 #endif /* not WIN32_NATIVE */
423
424     environ = save_environ;
425
426     /* Close most of our fd's, but not fd[0]
427        since we will use that to read input from.  */
428     close (filefd);
429     if (fd1 >= 0)
430       close (fd1);
431   }
432
433   if (!NILP (fork_error))
434     signal_error (Qfile_error, fork_error);
435
436 #ifndef WIN32_NATIVE
437   if (pid < 0)
438     {
439       int save_errno = errno;
440       if (fd[0] >= 0)
441         close (fd[0]);
442       errno = save_errno;
443       report_file_error ("Doing fork", Qnil);
444     }
445 #endif
446
447   if (INTP (buffer))
448     {
449       if (fd[0] >= 0)
450         close (fd[0]);
451 #if defined (NO_SUBPROCESSES)
452       /* If Emacs has been built with asynchronous subprocess support,
453          we don't need to do this, I think because it will then have
454          the facilities for handling SIGCHLD.  */
455       wait_without_blocking ();
456 #endif /* NO_SUBPROCESSES */
457       return Qnil;
458     }
459
460   {
461     int nread;
462     int total_read = 0;
463     Lisp_Object instream;
464     struct gcpro ngcpro1;
465
466     /* Enable sending signal if user quits below.  */
467     call_process_exited = 0;
468
469     record_unwind_protect (call_process_cleanup,
470                            Fcons (make_int (fd[0]), make_int (pid)));
471
472     /* FSFmacs calls Fset_buffer() here.  We don't have to because
473        we can insert into buffers other than the current one. */
474     if (EQ (buffer, Qt))
475       XSETBUFFER (buffer, current_buffer);
476     instream = make_filedesc_input_stream (fd[0], 0, -1, LSTR_ALLOW_QUIT);
477 #ifdef FILE_CODING
478     instream =
479       make_decoding_input_stream
480         (XLSTREAM (instream),
481          Fget_coding_system (Vcoding_system_for_read));
482     Lstream_set_character_mode (XLSTREAM (instream));
483 #endif
484     NGCPRO1 (instream);
485     while (1)
486       {
487         QUIT;
488         /* Repeatedly read until we've filled as much as possible
489            of the buffer size we have.  But don't read
490            less than 1024--save that for the next bufferfull.  */
491
492         nread = 0;
493         while (nread < bufsize - 1024)
494           {
495             Lstream_data_count this_read
496               = Lstream_read (XLSTREAM (instream), bufptr + nread,
497                               bufsize - nread);
498
499             if (this_read < 0)
500               goto give_up;
501
502             if (this_read == 0)
503               goto give_up_1;
504
505             nread += this_read;
506           }
507
508       give_up_1:
509
510         /* Now NREAD is the total amount of data in the buffer.  */
511         if (nread == 0)
512           break;
513
514 #if 0
515 #ifdef WIN32_NATIVE
516        /* Until we pull out of MULE things like
517           make_decoding_input_stream(), we do the following which is
518           less elegant. --marcpa */
519         /* We did. -- kkm */
520        {
521          int lf_count = 0;
522          if (NILP (Vbinary_process_output)) {
523            nread = crlf_to_lf(nread, bufptr, &lf_count);
524          }
525        }
526 #endif
527 #endif
528
529         total_read += nread;
530
531         if (!NILP (buffer))
532           buffer_insert_raw_string (XBUFFER (buffer), (Bufbyte *) bufptr,
533                                     nread);
534
535         /* Make the buffer bigger as we continue to read more data,
536            but not past 64k.  */
537         if (bufsize < 64 * 1024 && total_read > 32 * bufsize)
538           {
539             bufsize *= 2;
540             bufptr = (char *) alloca (bufsize);
541           }
542
543         if (!NILP (display) && INTERACTIVE)
544           {
545             redisplay ();
546           }
547       }
548   give_up:
549     Lstream_close (XLSTREAM (instream));
550     NUNGCPRO;
551
552     QUIT;
553     /* Wait for it to terminate, unless it already has.  */
554 #ifdef WIN32_NATIVE
555     wait_for_termination (pHandle);
556 #else
557     wait_for_termination (pid);
558 #endif
559
560     /* Don't kill any children that the subprocess may have left behind
561        when exiting.  */
562     call_process_exited = 1;
563     unbind_to (speccount, Qnil);
564
565     if (synch_process_death)
566       return build_string (synch_process_death);
567     return make_int (synch_process_retcode);
568   }
569 }
570
571 \f
572
573 /* Move the file descriptor FD so that its number is not less than MIN. *
574    The original file descriptor remains open.  */
575 static int
576 relocate_fd (int fd, int min)
577 {
578   if (fd >= min)
579     return fd;
580   else
581     {
582       int newfd = dup (fd);
583       if (newfd == -1)
584         {
585           stderr_out ("Error while setting up child: %s\n",
586                       strerror (errno));
587           _exit (1);
588         }
589       return relocate_fd (newfd, min);
590     }
591 }
592
593 /* This is the last thing run in a newly forked inferior
594    either synchronous or asynchronous.
595    Copy descriptors IN, OUT and ERR
596    as descriptors STDIN_FILENO, STDOUT_FILENO, and STDERR_FILENO.
597    Initialize inferior's priority, pgrp, connected dir and environment.
598    then exec another program based on new_argv.
599
600    This function may change environ for the superior process.
601    Therefore, the superior process must save and restore the value
602    of environ around the fork and the call to this function.
603
604    ENV is the environment for the subprocess.
605
606    XEmacs: We've removed the SET_PGRP argument because it's already
607    done by the callers of child_setup.
608
609    CURRENT_DIR is an elisp string giving the path of the current
610    directory the subprocess should have.  Since we can't really signal
611    a decent error from within the child, this should be verified as an
612    executable directory by the parent.  */
613
614 #ifdef WIN32_NATIVE
615 int
616 #else
617 void
618 #endif
619 child_setup (int in, int out, int err, char **new_argv,
620              const char *current_dir)
621 {
622   char **env;
623   char *pwd;
624 #ifdef WIN32_NATIVE
625   int cpid;
626   HANDLE handles[4];
627 #endif /* WIN32_NATIVE */
628
629 #ifdef SET_EMACS_PRIORITY
630   if (emacs_priority != 0)
631     nice (- emacs_priority);
632 #endif
633
634   /* Under Windows, we are not in a child process at all, so we should
635      not close handles inherited from the parent -- we are the parent
636      and doing so will screw up all manner of things!  Similarly, most
637      of the rest of the cleanup done in this function is not done
638      under Windows.
639
640      #### This entire child_setup() function is an utter and complete
641      piece of shit.  I would rewrite it, at the very least splitting
642      out the Windows and non-Windows stuff into two completely
643      different functions; but instead I'm trying to make it go away
644      entirely, using the Lisp definition in process.el.  What's left
645      is to fix up the routines in event-msw.c (and in event-Xt.c and
646      event-tty.c) to allow for stream devices to be handled correctly.
647      There isn't much to do, in fact, and I'll fix it shortly.  That
648      way, the Lisp definition can be used non-interactively too. */
649 #if !defined (NO_SUBPROCESSES) && !defined (WIN32_NATIVE)
650   /* Close Emacs's descriptors that this process should not have.  */
651   close_process_descs ();
652 #endif /* not NO_SUBPROCESSES */
653 #ifndef WIN32_NATIVE
654   close_load_descs ();
655 #endif
656
657   /* Note that use of alloca is always safe here.  It's obvious for systems
658      that do not have true vfork or that have true (stack) alloca.
659      If using vfork and C_ALLOCA it is safe because that changes
660      the superior's static variables as if the superior had done alloca
661      and will be cleaned up in the usual way.  */
662   {
663     REGISTER int i;
664
665     i = strlen (current_dir);
666     pwd = alloca_array (char, i + 6);
667     memcpy (pwd, "PWD=", 4);
668     memcpy (pwd + 4, current_dir, i);
669     i += 4;
670     if (!IS_DIRECTORY_SEP (pwd[i - 1]))
671       pwd[i++] = DIRECTORY_SEP;
672     pwd[i] = 0;
673
674     /* We can't signal an Elisp error here; we're in a vfork.  Since
675        the callers check the current directory before forking, this
676        should only return an error if the directory's permissions
677        are changed between the check and this chdir, but we should
678        at least check.  */
679     if (chdir (pwd + 4) < 0)
680       {
681         /* Don't report the chdir error, or ange-ftp.el doesn't work. */
682         /* (FSFmacs does _exit (errno) here.) */
683         pwd = 0;
684       }
685     else
686       {
687         /* Strip trailing "/".  Cretinous *[]&@$#^%@#$% Un*x */
688         /* leave "//" (from FSF) */
689         while (i > 6 && IS_DIRECTORY_SEP (pwd[i - 1]))
690           pwd[--i] = 0;
691       }
692   }
693
694   /* Set `env' to a vector of the strings in Vprocess_environment.  */
695   /* + 2 to include PWD and terminating 0.  */
696   env = alloca_array (char *, XINT (Flength (Vprocess_environment)) + 2);
697   {
698     REGISTER Lisp_Object tail;
699     char **new_env = env;
700
701     /* If we have a PWD envvar and we know the real current directory,
702        pass one down, but with corrected value.  */
703     if (pwd && getenv ("PWD"))
704       *new_env++ = pwd;
705
706     /* Copy the Vprocess_environment strings into new_env.  */
707     for (tail = Vprocess_environment;
708          CONSP (tail) && STRINGP (XCAR (tail));
709          tail = XCDR (tail))
710     {
711       char **ep = env;
712       char *envvar_external;
713
714       TO_EXTERNAL_FORMAT (LISP_STRING, XCAR (tail),
715                           C_STRING_ALLOCA, envvar_external,
716                           Qfile_name);
717
718       /* See if envvar_external duplicates any string already in the env.
719          If so, don't put it in.
720          When an env var has multiple definitions,
721          we keep the definition that comes first in process-environment.  */
722       for (; ep != new_env; ep++)
723         {
724           char *p = *ep, *q = envvar_external;
725           while (1)
726             {
727               if (*q == 0)
728                 /* The string is malformed; might as well drop it.  */
729                 goto duplicate;
730               if (*q != *p)
731                 break;
732               if (*q == '=')
733                 goto duplicate;
734               p++, q++;
735             }
736         }
737       if (pwd && !strncmp ("PWD=", envvar_external, 4))
738         {
739           *new_env++ = pwd;
740           pwd = 0;
741         }
742       else
743         *new_env++ = envvar_external;
744
745     duplicate: ;
746     }
747     *new_env = 0;
748   }
749
750 #ifdef WIN32_NATIVE
751   prepare_standard_handles (in, out, err, handles);
752   set_process_dir (current_dir);
753 #else  /* not WIN32_NATIVE */
754   /* Make sure that in, out, and err are not actually already in
755      descriptors zero, one, or two; this could happen if Emacs is
756      started with its standard in, out, or error closed, as might
757      happen under X.  */
758   in  = relocate_fd (in,  3);
759   out = relocate_fd (out, 3);
760   err = relocate_fd (err, 3);
761
762   /* Set the standard input/output channels of the new process.  */
763   close (STDIN_FILENO);
764   close (STDOUT_FILENO);
765   close (STDERR_FILENO);
766
767   dup2 (in,  STDIN_FILENO);
768   dup2 (out, STDOUT_FILENO);
769   dup2 (err, STDERR_FILENO);
770
771   close (in);
772   close (out);
773   close (err);
774
775   /* I can't think of any reason why child processes need any more
776      than the standard 3 file descriptors.  It would be cleaner to
777      close just the ones that need to be, but the following brute
778      force approach is certainly effective, and not too slow. */
779   {
780     int fd;
781     for (fd=3; fd<=64; fd++)
782       close (fd);
783   }
784 #endif /* not WIN32_NATIVE */
785
786 #ifdef vipc
787   something missing here;
788 #endif /* vipc */
789
790 #ifdef WIN32_NATIVE
791   /* Spawn the child.  (See ntproc.c:Spawnve).  */
792   cpid = spawnve (_P_NOWAIT, new_argv[0], (const char* const*)new_argv,
793                   (const char* const*)env);
794   if (cpid == -1)
795     /* An error occurred while trying to spawn the process.  */
796     report_file_error ("Spawning child process", Qnil);
797   reset_standard_handles (in, out, err, handles);
798   return cpid;
799 #else /* not WIN32_NATIVE */
800   /* execvp does not accept an environment arg so the only way
801      to pass this environment is to set environ.  Our caller
802      is responsible for restoring the ambient value of environ.  */
803   environ = env;
804   execvp (new_argv[0], new_argv);
805
806   stdout_out ("Can't exec program %s\n", new_argv[0]);
807   _exit (1);
808 #endif /* not WIN32_NATIVE */
809 }
810
811 static int
812 getenv_internal (const Bufbyte *var,
813                  Bytecount varlen,
814                  Bufbyte **value,
815                  Bytecount *valuelen)
816 {
817   Lisp_Object scan;
818
819   for (scan = Vprocess_environment; CONSP (scan); scan = XCDR (scan))
820     {
821       Lisp_Object entry = XCAR (scan);
822
823       if (STRINGP (entry)
824           && XSTRING_LENGTH (entry) > varlen
825           && XSTRING_BYTE (entry, varlen) == '='
826 #ifdef WIN32_NATIVE
827           /* NT environment variables are case insensitive.  */
828           && ! memicmp (XSTRING_DATA (entry), var, varlen)
829 #else  /* not WIN32_NATIVE */
830           && ! memcmp (XSTRING_DATA (entry), var, varlen)
831 #endif /* not WIN32_NATIVE */
832           )
833         {
834           *value    = XSTRING_DATA   (entry) + (varlen + 1);
835           *valuelen = XSTRING_LENGTH (entry) - (varlen + 1);
836           return 1;
837         }
838     }
839
840   return 0;
841 }
842
843 DEFUN ("getenv", Fgetenv, 1, 2, "sEnvironment variable: \np", /*
844 Return the value of environment variable VAR, as a string.
845 VAR is a string, the name of the variable.
846 When invoked interactively, prints the value in the echo area.
847 */
848        (var, interactivep))
849 {
850   Bufbyte *value;
851   Bytecount valuelen;
852   Lisp_Object v = Qnil;
853   struct gcpro gcpro1;
854
855   CHECK_STRING (var);
856   GCPRO1 (v);
857   if (getenv_internal (XSTRING_DATA (var), XSTRING_LENGTH (var),
858                        &value, &valuelen))
859     v = make_string (value, valuelen);
860   if (!NILP (interactivep))
861     {
862       if (NILP (v))
863         message ("%s not defined in environment", XSTRING_DATA (var));
864       else
865         /* #### Should use Fprin1_to_string or Fprin1 to handle string
866            containing quotes correctly.  */
867         message ("\"%s\"", value);
868     }
869   RETURN_UNGCPRO (v);
870 }
871
872 /* A version of getenv that consults process_environment, easily
873    callable from C.  */
874 char *
875 egetenv (const char *var)
876 {
877   /* This cannot GC -- 7-28-00 ben */
878   Bufbyte *value;
879   Bytecount valuelen;
880
881   if (getenv_internal ((const Bufbyte *) var, strlen (var), &value, &valuelen))
882     return (char *) value;
883   else
884     return 0;
885 }
886
887 \f
888 void
889 init_callproc (void)
890 {
891   /* This function can GC */
892
893   {
894     /* jwz: always initialize Vprocess_environment, so that egetenv()
895        works in temacs. */
896     char **envp;
897     Vprocess_environment = Qnil;
898     for (envp = environ; envp && *envp; envp++)
899       Vprocess_environment =
900         Fcons (build_ext_string (*envp, Qfile_name), Vprocess_environment);
901   }
902
903   {
904     /* Initialize shell-file-name from environment variables or best guess. */
905 #ifdef WIN32_NATIVE
906     const char *shell = egetenv ("SHELL");
907     if (!shell) shell = egetenv ("COMSPEC");
908     /* Should never happen! */
909     if (!shell) shell = (GetVersion () & 0x80000000 ? "command" : "cmd");
910 #else /* not WIN32_NATIVE */
911     const char *shell = egetenv ("SHELL");
912     if (!shell) shell = "/bin/sh";
913 #endif
914
915 #if 0 /* defined (WIN32_NATIVE) */
916     /* BAD BAD BAD.  We do not wanting to be passing an XEmacs-created
917        SHELL var down to some inferior Cygwin process, which might get
918        screwed up.
919          
920        There are a few broken apps (eterm/term.el, eterm/tshell.el,
921        os-utils/terminal.el, texinfo/tex-mode.el) where this will
922        cause problems.  Those broken apps don't look at
923        shell-file-name, instead just at explicit-shell-file-name,
924        ESHELL and SHELL.  They are apparently attempting to borrow
925        what `M-x shell' uses, but that latter also looks at
926        shell-file-name.  What we want is for all of these apps to look
927        at shell-file-name, so that the user can change the value of
928        shell-file-name and everything will work out hunky-dorey.
929        */
930     
931     if (!egetenv ("SHELL"))
932       {
933         CBufbyte *faux_var = alloca_array (CBufbyte, 7 + strlen (shell));
934         sprintf (faux_var, "SHELL=%s", shell);
935         Vprocess_environment = Fcons (build_string (faux_var),
936                                       Vprocess_environment);
937       }
938 #endif /* 0 */
939
940     Vshell_file_name = build_string (shell);
941   }
942 }
943
944 #if 0
945 void
946 set_process_environment (void)
947 {
948   REGISTER char **envp;
949
950   Vprocess_environment = Qnil;
951 #ifndef CANNOT_DUMP
952   if (initialized)
953 #endif
954     for (envp = environ; *envp; envp++)
955       Vprocess_environment = Fcons (build_string (*envp),
956                                     Vprocess_environment);
957 }
958 #endif /* unused */
959
960 void
961 syms_of_callproc (void)
962 {
963   DEFSUBR (Fold_call_process_internal);
964   DEFSUBR (Fgetenv);
965 }
966
967 void
968 vars_of_callproc (void)
969 {
970   /* This function can GC */
971 #ifdef WIN32_NATIVE
972   DEFVAR_LISP ("binary-process-input", &Vbinary_process_input /*
973 *If non-nil then new subprocesses are assumed to take binary input.
974 */ );
975   Vbinary_process_input = Qnil;
976
977   DEFVAR_LISP ("binary-process-output", &Vbinary_process_output /*
978 *If non-nil then new subprocesses are assumed to produce binary output.
979 */ );
980   Vbinary_process_output = Qnil;
981 #endif /* WIN32_NATIVE */
982
983   DEFVAR_LISP ("shell-file-name", &Vshell_file_name /*
984 *File name to load inferior shells from.
985 Initialized from the SHELL environment variable.
986 */ );
987
988   DEFVAR_LISP ("process-environment", &Vprocess_environment /*
989 List of environment variables for subprocesses to inherit.
990 Each element should be a string of the form ENVVARNAME=VALUE.
991 The environment which Emacs inherits is placed in this variable
992 when Emacs starts.
993 */ );
994
995   Vlisp_EXEC_SUFFIXES = build_string (EXEC_SUFFIXES);
996   staticpro (&Vlisp_EXEC_SUFFIXES);
997 }