1 /* Synchronous subprocess invocation for GNU Emacs.
2 Copyright (C) 1985, 1986, 1987, 1988, 1993, 1994 Free Software Foundation, Inc.
4 This file is part of GNU Emacs.
6 GNU Emacs is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GNU Emacs is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Emacs; see the file COPYING. If not, write to
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
28 extern char *strerror ();
30 /* Define SIGCHLD as an alias for SIGCLD. */
32 #if !defined (SIGCHLD) && defined (SIGCLD)
33 #define SIGCHLD SIGCLD
36 #include <sys/types.h>
40 #define INCLUDED_FCNTL
47 #include <stdlib.h> /* for proper declaration of environ */
50 #define _P_NOWAIT 1 /* from process.h */
53 #ifdef MSDOS /* Demacs 1.1.1 91/10/16 HIRANO Satoshi */
55 #define INCLUDED_FCNTL
58 #include <sys/param.h>
75 #include "syssignal.h"
79 extern noshare
char **environ
;
81 extern char **environ
;
84 #define max(a, b) ((a) > (b) ? (a) : (b))
87 /* When we are starting external processes we need to know whether they
88 take binary input (no conversion) or text input (\n is converted to
89 \r\n). Similar for output: if newlines are written as \r\n then it's
90 text process output, otherwise it's binary. */
91 Lisp_Object Vbinary_process_input
;
92 Lisp_Object Vbinary_process_output
;
95 Lisp_Object Vexec_path
, Vexec_directory
, Vdata_directory
, Vdoc_directory
;
96 Lisp_Object Vconfigure_info_directory
;
98 Lisp_Object Vshell_file_name
;
100 Lisp_Object Vprocess_environment
;
103 Lisp_Object Qbuffer_file_type
;
106 /* True iff we are about to fork off a synchronous process or if we
107 are waiting for it. */
108 int synch_process_alive
;
110 /* Nonzero => this is a string explaining death of synchronous subprocess. */
111 char *synch_process_death
;
113 /* If synch_process_death is zero,
114 this is exit code of synchronous subprocess. */
115 int synch_process_retcode
;
117 extern Lisp_Object Vdoc_file_name
;
119 /* Clean up when exiting Fcall_process.
120 On MSDOS, delete the temporary file on any kind of termination.
121 On Unix, kill the process and any children on termination by signal. */
123 /* Nonzero if this is termination due to exit. */
124 static int call_process_exited
;
126 #ifndef VMS /* VMS version is in vmsproc.c. */
129 call_process_kill (fdpid
)
132 close (XFASTINT (Fcar (fdpid
)));
133 EMACS_KILLPG (XFASTINT (Fcdr (fdpid
)), SIGKILL
);
134 synch_process_alive
= 0;
139 call_process_cleanup (fdpid
)
143 /* for MSDOS fdpid is really (fd . tempfile) */
144 register Lisp_Object file
;
146 close (XFASTINT (Fcar (fdpid
)));
147 if (strcmp (XSTRING (file
)-> data
, NULL_DEVICE
) != 0)
148 unlink (XSTRING (file
)->data
);
149 #else /* not MSDOS */
150 register int pid
= XFASTINT (Fcdr (fdpid
));
153 if (call_process_exited
)
155 close (XFASTINT (Fcar (fdpid
)));
159 if (EMACS_KILLPG (pid
, SIGINT
) == 0)
161 int count
= specpdl_ptr
- specpdl
;
162 record_unwind_protect (call_process_kill
, fdpid
);
163 message1 ("Waiting for process to die...(type C-g again to kill it instantly)");
166 wait_for_termination (pid
);
168 specpdl_ptr
= specpdl
+ count
; /* Discard the unwind protect. */
169 message1 ("Waiting for process to die...done");
171 synch_process_alive
= 0;
172 close (XFASTINT (Fcar (fdpid
)));
173 #endif /* not MSDOS */
177 DEFUN ("call-process", Fcall_process
, Scall_process
, 1, MANY
, 0,
178 "Call PROGRAM synchronously in separate process.\n\
179 The program's input comes from file INFILE (nil means `/dev/null').\n\
180 Insert output in BUFFER before point; t means current buffer;\n\
181 nil for BUFFER means discard it; 0 means discard and don't wait.\n\
182 BUFFER can also have the form (REAL-BUFFER STDERR-FILE); in that case,\n\
183 REAL-BUFFER says what to do with standard output, as above,\n\
184 while STDERR-FILE says what to do with standard error in the child.\n\
185 STDERR-FILE may be nil (discard standard error output),\n\
186 t (mix it with ordinary output), or a file name string.\n\
188 Fourth arg DISPLAY non-nil means redisplay buffer as output is inserted.\n\
189 Remaining arguments are strings passed as command arguments to PROGRAM.\n\
191 If BUFFER is 0, `call-process' returns immediately with value nil.\n\
192 Otherwise it waits for PROGRAM to terminate\n\
193 and returns a numeric exit status or a signal description string.\n\
194 If you quit, the process is killed with SIGINT, or SIGKILL if you quit again.")
197 register Lisp_Object
*args
;
199 Lisp_Object infile
, buffer
, current_dir
, display
, path
;
204 int count
= specpdl_ptr
- specpdl
;
205 register unsigned char **new_argv
206 = (unsigned char **) alloca ((max (2, nargs
- 2)) * sizeof (char *));
207 struct buffer
*old
= current_buffer
;
208 /* File to use for stderr in the child.
209 t means use same as standard output. */
210 Lisp_Object error_file
;
211 #ifdef MSDOS /* Demacs 1.1.1 91/10/16 HIRANO Satoshi */
212 char *outf
, *tempfile
;
218 CHECK_STRING (args
[0], 0);
223 /* Without asynchronous processes we cannot have BUFFER == 0. */
224 if (nargs
>= 3 && INTEGERP (args
[2]))
225 error ("Operating system cannot handle asynchronous subprocesses");
226 #endif /* subprocesses */
228 if (nargs
>= 2 && ! NILP (args
[1]))
230 infile
= Fexpand_file_name (args
[1], current_buffer
->directory
);
231 CHECK_STRING (infile
, 1);
234 infile
= build_string (NULL_DEVICE
);
240 /* If BUFFER is a list, its meaning is
241 (BUFFER-FOR-STDOUT FILE-FOR-STDERR). */
244 if (CONSP (XCONS (buffer
)->cdr
))
245 error_file
= XCONS (XCONS (buffer
)->cdr
)->car
;
246 buffer
= XCONS (buffer
)->car
;
249 if (!(EQ (buffer
, Qnil
)
251 || XFASTINT (buffer
) == 0))
253 Lisp_Object spec_buffer
;
254 spec_buffer
= buffer
;
255 buffer
= Fget_buffer (buffer
);
256 /* Mention the buffer name for a better error message. */
258 CHECK_BUFFER (spec_buffer
, 2);
259 CHECK_BUFFER (buffer
, 2);
265 /* Make sure that the child will be able to chdir to the current
266 buffer's current directory, or its unhandled equivalent. We
267 can't just have the child check for an error when it does the
268 chdir, since it's in a vfork.
270 We have to GCPRO around this because Fexpand_file_name,
271 Funhandled_file_name_directory, and Ffile_accessible_directory_p
272 might call a file name handling function. The argument list is
273 protected by the caller, so all we really have to worry about is
276 struct gcpro gcpro1
, gcpro2
, gcpro3
;
278 current_dir
= current_buffer
->directory
;
280 GCPRO3 (infile
, buffer
, current_dir
);
283 = expand_and_dir_to_file (Funhandled_file_name_directory (current_dir
),
285 if (NILP (Ffile_accessible_directory_p (current_dir
)))
286 report_file_error ("Setting current directory",
287 Fcons (current_buffer
->directory
, Qnil
));
292 display
= nargs
>= 4 ? args
[3] : Qnil
;
294 filefd
= open (XSTRING (infile
)->data
, O_RDONLY
, 0);
297 report_file_error ("Opening process input file", Fcons (infile
, Qnil
));
299 /* Search for program; barf if not found. */
303 GCPRO1 (current_dir
);
304 openp (Vexec_path
, args
[0], EXEC_SUFFIXES
, &path
, 1);
310 report_file_error ("Searching for program", Fcons (args
[0], Qnil
));
312 new_argv
[0] = XSTRING (path
)->data
;
315 for (i
= 4; i
< nargs
; i
++)
317 CHECK_STRING (args
[i
], i
);
318 new_argv
[i
- 3] = XSTRING (args
[i
])->data
;
323 #ifdef MSDOS /* MW, July 1993 */
324 /* These vars record information from process termination.
325 Clear them now before process can possibly terminate,
326 to avoid timing error if process terminates soon. */
327 synch_process_death
= 0;
328 synch_process_retcode
= 0;
330 if ((outf
= egetenv ("TMP")) || (outf
= egetenv ("TEMP")))
331 strcpy (tempfile
= alloca (strlen (outf
) + 20), outf
);
334 tempfile
= alloca (20);
337 dostounix_filename (tempfile
);
338 if (*tempfile
== '\0' || tempfile
[strlen (tempfile
) - 1] != '/')
339 strcat (tempfile
, "/");
340 strcat (tempfile
, "detmp.XXX");
343 outfilefd
= creat (tempfile
, S_IREAD
| S_IWRITE
);
347 report_file_error ("Opening process output file", Fcons (tempfile
, Qnil
));
351 if (INTEGERP (buffer
))
352 fd
[1] = open (NULL_DEVICE
, O_WRONLY
), fd
[0] = -1;
357 pipe_with_inherited_out (fd
);
358 #else /* not WINDOWSNT */
360 #endif /* not WINDOWSNT */
363 /* Replaced by close_process_descs */
364 set_exclusive_use (fd
[0]);
369 /* child_setup must clobber environ in systems with true vfork.
370 Protect it from permanent change. */
371 register char **save_environ
= environ
;
372 register int fd1
= fd
[1];
375 #if 0 /* Some systems don't have sigblock. */
376 mask
= sigblock (sigmask (SIGCHLD
));
379 /* Record that we're about to create a synchronous process. */
380 synch_process_alive
= 1;
382 /* These vars record information from process termination.
383 Clear them now before process can possibly terminate,
384 to avoid timing error if process terminates soon. */
385 synch_process_death
= 0;
386 synch_process_retcode
= 0;
388 #ifdef MSDOS /* MW, July 1993 */
389 /* ??? Someone who knows MSDOG needs to check whether this properly
390 closes all descriptors that it opens. */
391 pid
= run_msdos_command (new_argv
, current_dir
, filefd
, outfilefd
);
393 fd1
= -1; /* No harm in closing that one! */
394 fd
[0] = open (tempfile
, NILP (Vbinary_process_output
) ? O_TEXT
: O_BINARY
);
399 report_file_error ("Cannot re-open temporary file", Qnil
);
401 #else /* not MSDOS */
403 if (NILP (error_file
))
404 fd_error
= open (NULL_DEVICE
, O_WRONLY
);
405 else if (STRINGP (error_file
))
408 fd_error
= open (XSTRING (error_file
)->data
,
409 O_WRONLY
| O_TRUNC
| O_CREAT
| O_TEXT
,
411 #else /* not DOS_NT */
412 fd_error
= creat (XSTRING (error_file
)->data
, 0666);
413 #endif /* not DOS_NT */
422 report_file_error ("Cannot open", error_file
);
426 pid
= child_setup (filefd
, fd1
, fd_error
, new_argv
, 0, current_dir
);
427 #else /* not WINDOWSNT */
439 child_setup (filefd
, fd1
, fd_error
, new_argv
, 0, current_dir
);
441 #endif /* not MSDOS */
442 #endif /* not WINDOWSNT */
444 environ
= save_environ
;
446 /* Close most of our fd's, but not fd[0]
447 since we will use that to read input from. */
457 report_file_error ("Doing vfork", Qnil
);
460 if (INTEGERP (buffer
))
465 /* If Emacs has been built with asynchronous subprocess support,
466 we don't need to do this, I think because it will then have
467 the facilities for handling SIGCHLD. */
468 wait_without_blocking ();
469 #endif /* subprocesses */
473 /* Enable sending signal if user quits below. */
474 call_process_exited
= 0;
477 /* MSDOS needs different cleanup information. */
478 record_unwind_protect (call_process_cleanup
,
479 Fcons (make_number (fd
[0]), build_string (tempfile
)));
481 record_unwind_protect (call_process_cleanup
,
482 Fcons (make_number (fd
[0]), make_number (pid
)));
483 #endif /* not MSDOS */
486 if (BUFFERP (buffer
))
487 Fset_buffer (buffer
);
496 while ((nread
= read (fd
[0], buf
, sizeof buf
)) != 0)
500 #if defined (__osf__) && defined (__alpha)
501 continue; /* Work around bug in DEC OSF/1 V3.0. */
509 if (!NILP (display
) && INTERACTIVE
)
512 prepare_menu_bars ();
514 redisplay_preserve_echo_area ();
521 /* Wait for it to terminate, unless it already has. */
522 wait_for_termination (pid
);
526 set_buffer_internal (old
);
528 /* Don't kill any children that the subprocess may have left behind
530 call_process_exited
= 1;
532 unbind_to (count
, Qnil
);
534 if (synch_process_death
)
535 return build_string (synch_process_death
);
536 return make_number (synch_process_retcode
);
541 delete_temp_file (name
)
544 /* Use Fdelete_file (indirectly) because that runs a file name handler.
545 We did that when writing the file, so we should do so when deleting. */
546 internal_delete_file (name
);
549 DEFUN ("call-process-region", Fcall_process_region
, Scall_process_region
,
551 "Send text from START to END to a synchronous process running PROGRAM.\n\
552 Delete the text if fourth arg DELETE is non-nil.\n\
554 Insert output in BUFFER before point; t means current buffer;\n\
555 nil for BUFFER means discard it; 0 means discard and don't wait.\n\
556 BUFFER can also have the form (REAL-BUFFER STDERR-FILE); in that case,\n\
557 REAL-BUFFER says what to do with standard output, as above,\n\
558 while STDERR-FILE says what to do with standard error in the child.\n\
559 STDERR-FILE may be nil (discard standard error output),\n\
560 t (mix it with ordinary output), or a file name string.\n\
562 Sixth arg DISPLAY non-nil means redisplay buffer as output is inserted.\n\
563 Remaining args are passed to PROGRAM at startup as command args.\n\
565 If BUFFER is nil, `call-process-region' returns immediately with value nil.\n\
566 Otherwise it waits for PROGRAM to terminate\n\
567 and returns a numeric exit status or a signal description string.\n\
568 If you quit, the process is killed with SIGINT, or SIGKILL if you quit again.")
571 register Lisp_Object
*args
;
574 Lisp_Object filename_string
;
575 register Lisp_Object start
, end
;
581 int count
= specpdl_ptr
- specpdl
;
585 if ((outf
= egetenv ("TMP")) || (outf
= egetenv ("TEMP")))
586 strcpy (tempfile
= alloca (strlen (outf
) + 20), outf
);
589 tempfile
= alloca (20);
592 dostounix_filename (tempfile
);
593 if (tempfile
[strlen (tempfile
) - 1] != '/')
594 strcat (tempfile
, "/");
595 strcat (tempfile
, "detmp.XXX");
596 #else /* not DOS_NT */
599 strcpy (tempfile
, "tmp:emacsXXXXXX.");
601 strcpy (tempfile
, "/tmp/emacsXXXXXX");
603 #endif /* not DOS_NT */
607 filename_string
= build_string (tempfile
);
608 GCPRO1 (filename_string
);
612 specbind (Qbuffer_file_type
, Vbinary_process_input
);
613 Fwrite_region (start
, end
, filename_string
, Qnil
, Qlambda
);
614 unbind_to (count
, Qnil
);
615 #else /* not DOS_NT */
616 Fwrite_region (start
, end
, filename_string
, Qnil
, Qlambda
);
617 #endif /* not DOS_NT */
619 record_unwind_protect (delete_temp_file
, filename_string
);
622 Fdelete_region (start
, end
);
624 args
[3] = filename_string
;
626 RETURN_UNGCPRO (unbind_to (count
, Fcall_process (nargs
- 2, args
+ 2)));
629 #ifndef VMS /* VMS version is in vmsproc.c. */
631 /* This is the last thing run in a newly forked inferior
632 either synchronous or asynchronous.
633 Copy descriptors IN, OUT and ERR as descriptors 0, 1 and 2.
634 Initialize inferior's priority, pgrp, connected dir and environment.
635 then exec another program based on new_argv.
637 This function may change environ for the superior process.
638 Therefore, the superior process must save and restore the value
639 of environ around the vfork and the call to this function.
641 ENV is the environment for the subprocess.
643 SET_PGRP is nonzero if we should put the subprocess into a separate
646 CURRENT_DIR is an elisp string giving the path of the current
647 directory the subprocess should have. Since we can't really signal
648 a decent error from within the child, this should be verified as an
649 executable directory by the parent. */
651 child_setup (in
, out
, err
, new_argv
, set_pgrp
, current_dir
)
653 register char **new_argv
;
655 Lisp_Object current_dir
;
658 /* The MSDOS port of gcc cannot fork, vfork, ... so we must call system
660 #else /* not MSDOS */
666 #endif /* WINDOWSNT */
670 #ifdef SET_EMACS_PRIORITY
672 extern int emacs_priority
;
674 if (emacs_priority
< 0)
675 nice (- emacs_priority
);
680 /* Close Emacs's descriptors that this process should not have. */
681 close_process_descs ();
685 /* Note that use of alloca is always safe here. It's obvious for systems
686 that do not have true vfork or that have true (stack) alloca.
687 If using vfork and C_ALLOCA it is safe because that changes
688 the superior's static variables as if the superior had done alloca
689 and will be cleaned up in the usual way. */
694 i
= XSTRING (current_dir
)->size
;
695 pwd_var
= (char *) alloca (i
+ 6);
697 bcopy ("PWD=", pwd_var
, 4);
698 bcopy (XSTRING (current_dir
)->data
, temp
, i
);
699 if (!IS_DIRECTORY_SEP (temp
[i
- 1])) temp
[i
++] = DIRECTORY_SEP
;
702 /* We can't signal an Elisp error here; we're in a vfork. Since
703 the callers check the current directory before forking, this
704 should only return an error if the directory's permissions
705 are changed between the check and this chdir, but we should
707 if (chdir (temp
) < 0)
710 /* Strip trailing slashes for PWD, but leave "/" and "//" alone. */
711 while (i
> 2 && IS_DIRECTORY_SEP (temp
[i
- 1]))
715 /* Set `env' to a vector of the strings in Vprocess_environment. */
717 register Lisp_Object tem
;
718 register char **new_env
;
719 register int new_length
;
722 for (tem
= Vprocess_environment
;
723 CONSP (tem
) && STRINGP (XCONS (tem
)->car
);
724 tem
= XCONS (tem
)->cdr
)
727 /* new_length + 2 to include PWD and terminating 0. */
728 env
= new_env
= (char **) alloca ((new_length
+ 2) * sizeof (char *));
730 /* If we have a PWD envvar, pass one down,
731 but with corrected value. */
733 *new_env
++ = pwd_var
;
735 /* Copy the Vprocess_environment strings into new_env. */
736 for (tem
= Vprocess_environment
;
737 CONSP (tem
) && STRINGP (XCONS (tem
)->car
);
738 tem
= XCONS (tem
)->cdr
)
741 char *string
= (char *) XSTRING (XCONS (tem
)->car
)->data
;
742 /* See if this string duplicates any string already in the env.
743 If so, don't put it in.
744 When an env var has multiple definitions,
745 we keep the definition that comes first in process-environment. */
746 for (; ep
!= new_env
; ep
++)
748 char *p
= *ep
, *q
= string
;
752 /* The string is malformed; might as well drop it. */
767 prepare_standard_handles (in
, out
, err
, handles
);
768 #else /* not WINDOWSNT */
769 /* Make sure that in, out, and err are not actually already in
770 descriptors zero, one, or two; this could happen if Emacs is
771 started with its standard in, out, or error closed, as might
773 in
= relocate_fd (in
, 3);
775 err
= out
= relocate_fd (out
, 3);
778 out
= relocate_fd (out
, 3);
779 err
= relocate_fd (err
, 3);
792 #endif /* not WINDOWSNT */
795 #ifndef SETPGRP_RELEASES_CTTY
796 setpgrp (); /* No arguments but equivalent in this case */
801 /* setpgrp_of_tty is incorrect here; it uses input_fd. */
802 EMACS_SET_TTY_PGRP (0, &pid
);
805 something missing here
;
809 /* Spawn the child. (See ntproc.c:Spawnve). */
810 cpid
= spawnve (_P_NOWAIT
, new_argv
[0], new_argv
, env
);
811 if (cpid
== -1) { ????
812 report_file_error ("Spawning child process", Qnil
);
814 reset_standard_handles (in
, out
, err
, handles
);
816 #else /* not WINDOWSNT */
817 /* execvp does not accept an environment arg so the only way
818 to pass this environment is to set environ. Our caller
819 is responsible for restoring the ambient value of environ. */
821 execvp (new_argv
[0], new_argv
);
823 write (1, "Couldn't exec the program ", 26);
824 write (1, new_argv
[0], strlen (new_argv
[0]));
826 #endif /* not WINDOWSNT */
827 #endif /* not MSDOS */
830 /* Move the file descriptor FD so that its number is not less than MIN.
831 If the file descriptor is moved at all, the original is freed. */
833 relocate_fd (fd
, min
)
843 char *message1
= "Error while setting up child: ";
844 char *errmessage
= strerror (errno
);
845 char *message2
= "\n";
846 write (2, message1
, strlen (message1
));
847 write (2, errmessage
, strlen (errmessage
));
848 write (2, message2
, strlen (message2
));
851 /* Note that we hold the original FD open while we recurse,
852 to guarantee we'll get a new FD if we need it. */
853 new = relocate_fd (new, min
);
860 getenv_internal (var
, varlen
, value
, valuelen
)
868 for (scan
= Vprocess_environment
; CONSP (scan
); scan
= XCONS (scan
)->cdr
)
872 entry
= XCONS (scan
)->car
;
874 && XSTRING (entry
)->size
> varlen
875 && XSTRING (entry
)->data
[varlen
] == '='
877 /* NT environment variables are case insensitive. */
878 && ! strnicmp (XSTRING (entry
)->data
, var
, varlen
))
879 #else /* not WINDOWSNT */
880 && ! bcmp (XSTRING (entry
)->data
, var
, varlen
))
881 #endif /* not WINDOWSNT */
883 *value
= (char *) XSTRING (entry
)->data
+ (varlen
+ 1);
884 *valuelen
= XSTRING (entry
)->size
- (varlen
+ 1);
892 DEFUN ("getenv", Fgetenv
, Sgetenv
, 1, 1, 0,
893 "Return the value of environment variable VAR, as a string.\n\
894 VAR should be a string. Value is nil if VAR is undefined in the environment.\n\
895 This function consults the variable ``process-environment'' for its value.")
902 CHECK_STRING (var
, 0);
903 if (getenv_internal (XSTRING (var
)->data
, XSTRING (var
)->size
,
905 return make_string (value
, valuelen
);
910 /* A version of getenv that consults process_environment, easily
919 if (getenv_internal (var
, strlen (var
), &value
, &valuelen
))
927 /* This is run before init_cmdargs. */
931 char *data_dir
= egetenv ("EMACSDATA");
932 char *doc_dir
= egetenv ("EMACSDOC");
935 = Ffile_name_as_directory (build_string (data_dir
? data_dir
938 = Ffile_name_as_directory (build_string (doc_dir
? doc_dir
941 /* Check the EMACSPATH environment variable, defaulting to the
942 PATH_EXEC path from paths.h. */
943 Vexec_path
= decode_env_path ("EMACSPATH", PATH_EXEC
);
944 Vexec_directory
= Ffile_name_as_directory (Fcar (Vexec_path
));
945 Vexec_path
= nconc2 (decode_env_path ("PATH", ""), Vexec_path
);
948 /* This is run after init_cmdargs, so that Vinvocation_directory is valid. */
952 char *data_dir
= egetenv ("EMACSDATA");
957 if (initialized
&& !NILP (Vinstallation_directory
))
959 /* Add to the path the lib-src subdir of the installation dir. */
961 tem
= Fexpand_file_name (build_string ("lib-src"),
962 Vinstallation_directory
);
963 if (NILP (Fmember (tem
, Vexec_path
)))
966 /* MSDOS uses wrapped binaries, so don't do this. */
967 Vexec_path
= nconc2 (Vexec_path
, Fcons (tem
, Qnil
));
968 Vexec_directory
= Ffile_name_as_directory (tem
);
969 #endif /* not DOS_NT */
971 /* If we use ../lib-src, maybe use ../etc as well.
972 Do so if ../etc exists and has our DOC-... file in it. */
975 tem
= Fexpand_file_name (build_string ("etc"),
976 Vinstallation_directory
);
977 Vdoc_directory
= Ffile_name_as_directory (tem
);
982 /* Look for the files that should be in etc. We don't use
983 Vinstallation_directory, because these files are never installed
984 in /bin near the executable, and they are never in the build
985 directory when that's different from the source directory.
987 Instead, if these files are not in the nominal place, we try the
991 Lisp_Object tem
, tem1
, newdir
;
993 tem
= Fexpand_file_name (build_string ("GNU"), Vdata_directory
);
994 tem1
= Ffile_exists_p (tem
);
997 newdir
= Fexpand_file_name (build_string ("../etc/"),
998 build_string (PATH_DUMPLOADSEARCH
));
999 tem
= Fexpand_file_name (build_string ("GNU"), newdir
);
1000 tem1
= Ffile_exists_p (tem
);
1002 Vdata_directory
= newdir
;
1006 tempdir
= Fdirectory_file_name (Vexec_directory
);
1007 if (access (XSTRING (tempdir
)->data
, 0) < 0)
1010 "Warning: arch-dependent data dir (%s) does not exist.\n",
1011 XSTRING (Vexec_directory
)->data
);
1015 tempdir
= Fdirectory_file_name (Vdata_directory
);
1016 if (access (XSTRING (tempdir
)->data
, 0) < 0)
1019 "Warning: arch-independent data dir (%s) does not exist.\n",
1020 XSTRING (Vdata_directory
)->data
);
1025 Vshell_file_name
= build_string ("*dcl*");
1027 sh
= (char *) getenv ("SHELL");
1028 Vshell_file_name
= build_string (sh
? sh
: "/bin/sh");
1032 set_process_environment ()
1034 register char **envp
;
1036 Vprocess_environment
= Qnil
;
1040 for (envp
= environ
; *envp
; envp
++)
1041 Vprocess_environment
= Fcons (build_string (*envp
),
1042 Vprocess_environment
);
1048 Qbuffer_file_type
= intern ("buffer-file-type");
1049 staticpro (&Qbuffer_file_type
);
1051 DEFVAR_LISP ("binary-process-input", &Vbinary_process_input
,
1052 "*If non-nil then new subprocesses are assumed to take binary input.");
1053 Vbinary_process_input
= Qnil
;
1055 DEFVAR_LISP ("binary-process-output", &Vbinary_process_output
,
1056 "*If non-nil then new subprocesses are assumed to produce binary output.");
1057 Vbinary_process_output
= Qnil
;
1060 DEFVAR_LISP ("shell-file-name", &Vshell_file_name
,
1061 "*File name to load inferior shells from.\n\
1062 Initialized from the SHELL environment variable.");
1064 DEFVAR_LISP ("exec-path", &Vexec_path
,
1065 "*List of directories to search programs to run in subprocesses.\n\
1066 Each element is a string (directory name) or nil (try default directory).");
1068 DEFVAR_LISP ("exec-directory", &Vexec_directory
,
1069 "Directory of architecture-dependent files that come with GNU Emacs,\n\
1070 especially executable programs intended for Emacs to invoke.");
1072 DEFVAR_LISP ("data-directory", &Vdata_directory
,
1073 "Directory of architecture-independent files that come with GNU Emacs,\n\
1074 intended for Emacs to use.");
1076 DEFVAR_LISP ("doc-directory", &Vdoc_directory
,
1077 "Directory containing the DOC file that comes with GNU Emacs.\n\
1078 This is usually the same as data-directory.");
1080 DEFVAR_LISP ("configure-info-directory", &Vconfigure_info_directory
,
1081 "For internal use by the build procedure only.\n\
1082 This is the name of the directory in which the build procedure installed\n\
1083 Emacs's info files; the default value for Info-default-directory-list\n\
1085 Vconfigure_info_directory
= build_string (PATH_INFO
);
1087 DEFVAR_LISP ("process-environment", &Vprocess_environment
,
1088 "List of environment variables for subprocesses to inherit.\n\
1089 Each element should be a string of the form ENVVARNAME=VALUE.\n\
1090 The environment which Emacs inherits is placed in this variable\n\
1091 when Emacs starts.");
1094 defsubr (&Scall_process
);
1097 defsubr (&Scall_process_region
);