(graft_intervals_into_buffer): If SOURCE is null
[bpt/emacs.git] / src / callproc.c
CommitLineData
80856e74 1/* Synchronous subprocess invocation for GNU Emacs.
c6c5df7f 2 Copyright (C) 1985, 1986, 1987, 1988, 1993 Free Software Foundation, Inc.
80856e74
JB
3
4This file is part of GNU Emacs.
5
6GNU Emacs is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 1, or (at your option)
9any later version.
10
11GNU Emacs is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU Emacs; see the file COPYING. If not, write to
18the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20
21#include <signal.h>
e576cab4 22#include <errno.h>
80856e74 23
18160b98 24#include <config.h>
80856e74 25
426b37ae
JB
26extern int errno;
27#ifndef VMS
28extern char *sys_errlist[];
29#endif
30
80856e74
JB
31/* Define SIGCHLD as an alias for SIGCLD. */
32
33#if !defined (SIGCHLD) && defined (SIGCLD)
34#define SIGCHLD SIGCLD
35#endif /* SIGCLD */
36
37#include <sys/types.h>
88a64fef 38
80856e74
JB
39#include <sys/file.h>
40#ifdef USG5
41#include <fcntl.h>
42#endif
43
44#ifndef O_RDONLY
45#define O_RDONLY 0
46#endif
47
48#ifndef O_WRONLY
49#define O_WRONLY 1
50#endif
51
52#include "lisp.h"
53#include "commands.h"
54#include "buffer.h"
2a6b3537 55#include <paths.h>
80856e74 56#include "process.h"
d177f194 57#include "syssignal.h"
80856e74
JB
58
59#ifdef VMS
60extern noshare char **environ;
61#else
62extern char **environ;
63#endif
64
65#define max(a, b) ((a) > (b) ? (a) : (b))
66
e576cab4 67Lisp_Object Vexec_path, Vexec_directory, Vdata_directory;
ed61592a 68Lisp_Object Vconfigure_info_directory;
80856e74
JB
69
70Lisp_Object Vshell_file_name;
71
80856e74 72Lisp_Object Vprocess_environment;
80856e74
JB
73
74/* True iff we are about to fork off a synchronous process or if we
75 are waiting for it. */
76int synch_process_alive;
77
78/* Nonzero => this is a string explaining death of synchronous subprocess. */
79char *synch_process_death;
80
81/* If synch_process_death is zero,
82 this is exit code of synchronous subprocess. */
83int synch_process_retcode;
8de15d69
RS
84
85extern Lisp_Object Vdoc_file_name;
80856e74
JB
86\f
87#ifndef VMS /* VMS version is in vmsproc.c. */
88
d177f194
JB
89static Lisp_Object
90call_process_kill (fdpid)
91 Lisp_Object fdpid;
92{
93 close (XFASTINT (Fcar (fdpid)));
94 EMACS_KILLPG (XFASTINT (Fcdr (fdpid)), SIGKILL);
95 synch_process_alive = 0;
96 return Qnil;
97}
98
80856e74
JB
99Lisp_Object
100call_process_cleanup (fdpid)
101 Lisp_Object fdpid;
102{
d177f194
JB
103 register int pid = XFASTINT (Fcdr (fdpid));
104
105 if (EMACS_KILLPG (pid, SIGINT) == 0)
106 {
107 int count = specpdl_ptr - specpdl;
108 record_unwind_protect (call_process_kill, fdpid);
109 message1 ("Waiting for process to die...(type C-g again to kill it instantly)");
110 immediate_quit = 1;
111 QUIT;
112 wait_for_termination (pid);
113 immediate_quit = 0;
114 specpdl_ptr = specpdl + count; /* Discard the unwind protect. */
115 message1 ("Waiting for process to die...done");
116 }
80856e74 117 synch_process_alive = 0;
d177f194 118 close (XFASTINT (Fcar (fdpid)));
80856e74
JB
119 return Qnil;
120}
121
122DEFUN ("call-process", Fcall_process, Scall_process, 1, MANY, 0,
123 "Call PROGRAM synchronously in separate process.\n\
124The program's input comes from file INFILE (nil means `/dev/null').\n\
125Insert output in BUFFER before point; t means current buffer;\n\
126 nil for BUFFER means discard it; 0 means discard and don't wait.\n\
127Fourth arg DISPLAY non-nil means redisplay buffer as output is inserted.\n\
128Remaining arguments are strings passed as command arguments to PROGRAM.\n\
e576cab4 129If BUFFER is 0, returns immediately with value nil.\n\
80856e74 130Otherwise waits for PROGRAM to terminate\n\
e576cab4 131and returns a numeric exit status or a signal description string.\n\
d177f194 132If you quit, the process is killed with SIGINT, or SIGKILL if you quit again.")
80856e74
JB
133 (nargs, args)
134 int nargs;
135 register Lisp_Object *args;
136{
58616e67 137 Lisp_Object infile, buffer, current_dir, display, path;
80856e74
JB
138 int fd[2];
139 int filefd;
140 register int pid;
141 char buf[1024];
142 int count = specpdl_ptr - specpdl;
143 register unsigned char **new_argv
144 = (unsigned char **) alloca ((max (2, nargs - 2)) * sizeof (char *));
145 struct buffer *old = current_buffer;
146#if 0
147 int mask;
148#endif
80856e74
JB
149 CHECK_STRING (args[0], 0);
150
e576cab4
JB
151 if (nargs >= 2 && ! NILP (args[1]))
152 {
153 infile = Fexpand_file_name (args[1], current_buffer->directory);
154 CHECK_STRING (infile, 1);
155 }
80856e74 156 else
5437e9f9 157 infile = build_string (NULL_DEVICE);
80856e74 158
e576cab4
JB
159 if (nargs >= 3)
160 {
161 register Lisp_Object tem;
044512ed 162
e576cab4
JB
163 buffer = tem = args[2];
164 if (!(EQ (tem, Qnil)
165 || EQ (tem, Qt)
166 || XFASTINT (tem) == 0))
167 {
168 buffer = Fget_buffer (tem);
169 CHECK_BUFFER (buffer, 2);
170 }
171 }
172 else
173 buffer = Qnil;
80856e74 174
58616e67
JB
175 /* Make sure that the child will be able to chdir to the current
176 buffer's current directory, or its unhandled equivalent. We
177 can't just have the child check for an error when it does the
178 chdir, since it's in a vfork.
179
180 We have to GCPRO around this because Fexpand_file_name,
181 Funhandled_file_name_directory, and Ffile_accessible_directory_p
182 might call a file name handling function. The argument list is
183 protected by the caller, so all we really have to worry about is
184 buffer. */
185 {
186 struct gcpro gcpro1, gcpro2, gcpro3;
187
188 current_dir = current_buffer->directory;
189
190 GCPRO3 (infile, buffer, current_dir);
191
192 current_dir =
193 expand_and_dir_to_file
82df4891 194 (Funhandled_file_name_directory (current_dir), Qnil);
58616e67
JB
195 if (NILP (Ffile_accessible_directory_p (current_dir)))
196 report_file_error ("Setting current directory",
197 Fcons (current_buffer->directory, Qnil));
198
199 UNGCPRO;
200 }
201
e576cab4 202 display = nargs >= 4 ? args[3] : Qnil;
80856e74
JB
203
204 {
205 register int i;
206 for (i = 4; i < nargs; i++)
207 {
208 CHECK_STRING (args[i], i);
209 new_argv[i - 3] = XSTRING (args[i])->data;
210 }
211 /* Program name is first command arg */
212 new_argv[0] = XSTRING (args[0])->data;
213 new_argv[i - 3] = 0;
214 }
215
e576cab4 216 filefd = open (XSTRING (infile)->data, O_RDONLY, 0);
80856e74
JB
217 if (filefd < 0)
218 {
e576cab4 219 report_file_error ("Opening process input file", Fcons (infile, Qnil));
80856e74
JB
220 }
221 /* Search for program; barf if not found. */
5437e9f9 222 openp (Vexec_path, args[0], EXEC_SUFFIXES, &path, 1);
012c6fcb 223 if (NILP (path))
80856e74
JB
224 {
225 close (filefd);
226 report_file_error ("Searching for program", Fcons (args[0], Qnil));
227 }
228 new_argv[0] = XSTRING (path)->data;
229
230 if (XTYPE (buffer) == Lisp_Int)
5437e9f9 231 fd[1] = open (NULL_DEVICE, O_WRONLY), fd[0] = -1;
80856e74
JB
232 else
233 {
234 pipe (fd);
235#if 0
236 /* Replaced by close_process_descs */
237 set_exclusive_use (fd[0]);
238#endif
239 }
240
241 {
242 /* child_setup must clobber environ in systems with true vfork.
243 Protect it from permanent change. */
244 register char **save_environ = environ;
245 register int fd1 = fd[1];
80856e74
JB
246
247#if 0 /* Some systems don't have sigblock. */
e065a56e 248 mask = sigblock (sigmask (SIGCHLD));
80856e74
JB
249#endif
250
251 /* Record that we're about to create a synchronous process. */
252 synch_process_alive = 1;
253
5c03767e
RS
254 /* These vars record information from process termination.
255 Clear them now before process can possibly terminate,
256 to avoid timing error if process terminates soon. */
257 synch_process_death = 0;
258 synch_process_retcode = 0;
259
80856e74
JB
260 pid = vfork ();
261
262 if (pid == 0)
263 {
264 if (fd[0] >= 0)
265 close (fd[0]);
5a570e37 266#ifdef USG
80856e74
JB
267 setpgrp ();
268#else
269 setpgrp (pid, pid);
270#endif /* USG */
e576cab4 271 child_setup (filefd, fd1, fd1, new_argv, 0, current_dir);
80856e74
JB
272 }
273
274#if 0
275 /* Tell SIGCHLD handler to look for this pid. */
276 synch_process_pid = pid;
277 /* Now let SIGCHLD come through. */
e065a56e 278 sigsetmask (mask);
80856e74
JB
279#endif
280
281 environ = save_environ;
282
283 close (filefd);
284 close (fd1);
285 }
286
287 if (pid < 0)
288 {
289 close (fd[0]);
290 report_file_error ("Doing vfork", Qnil);
291 }
292
293 if (XTYPE (buffer) == Lisp_Int)
294 {
295#ifndef subprocesses
e576cab4
JB
296 /* If Emacs has been built with asynchronous subprocess support,
297 we don't need to do this, I think because it will then have
298 the facilities for handling SIGCHLD. */
80856e74
JB
299 wait_without_blocking ();
300#endif /* subprocesses */
80856e74
JB
301 return Qnil;
302 }
303
304 record_unwind_protect (call_process_cleanup,
305 Fcons (make_number (fd[0]), make_number (pid)));
306
307
308 if (XTYPE (buffer) == Lisp_Buffer)
309 Fset_buffer (buffer);
310
311 immediate_quit = 1;
312 QUIT;
313
314 {
315 register int nread;
316
317 while ((nread = read (fd[0], buf, sizeof buf)) > 0)
318 {
319 immediate_quit = 0;
012c6fcb 320 if (!NILP (buffer))
80856e74 321 insert (buf, nread);
012c6fcb 322 if (!NILP (display) && INTERACTIVE)
80856e74
JB
323 redisplay_preserve_echo_area ();
324 immediate_quit = 1;
325 QUIT;
326 }
327 }
328
329 /* Wait for it to terminate, unless it already has. */
330 wait_for_termination (pid);
331
332 immediate_quit = 0;
333
334 set_buffer_internal (old);
335
336 unbind_to (count, Qnil);
337
80856e74
JB
338 if (synch_process_death)
339 return build_string (synch_process_death);
340 return make_number (synch_process_retcode);
341}
342#endif
343\f
9fefd2ba 344static Lisp_Object
80856e74
JB
345delete_temp_file (name)
346 Lisp_Object name;
347{
348 unlink (XSTRING (name)->data);
349}
350
351DEFUN ("call-process-region", Fcall_process_region, Scall_process_region,
352 3, MANY, 0,
353 "Send text from START to END to a synchronous process running PROGRAM.\n\
354Delete the text if fourth arg DELETE is non-nil.\n\
355Insert output in BUFFER before point; t means current buffer;\n\
356 nil for BUFFER means discard it; 0 means discard and don't wait.\n\
357Sixth arg DISPLAY non-nil means redisplay buffer as output is inserted.\n\
358Remaining args are passed to PROGRAM at startup as command args.\n\
359If BUFFER is nil, returns immediately with value nil.\n\
360Otherwise waits for PROGRAM to terminate\n\
e576cab4 361and returns a numeric exit status or a signal description string.\n\
d177f194 362If you quit, the process is killed with SIGINT, or SIGKILL if you quit again.")
80856e74
JB
363 (nargs, args)
364 int nargs;
365 register Lisp_Object *args;
366{
367 register Lisp_Object filename_string, start, end;
368 char tempfile[20];
369 int count = specpdl_ptr - specpdl;
80856e74
JB
370
371#ifdef VMS
372 strcpy (tempfile, "tmp:emacsXXXXXX.");
373#else
374 strcpy (tempfile, "/tmp/emacsXXXXXX");
375#endif
376 mktemp (tempfile);
377
378 filename_string = build_string (tempfile);
379 start = args[0];
380 end = args[1];
381 Fwrite_region (start, end, filename_string, Qnil, Qlambda);
382 record_unwind_protect (delete_temp_file, filename_string);
383
012c6fcb 384 if (!NILP (args[3]))
80856e74
JB
385 Fdelete_region (start, end);
386
387 args[3] = filename_string;
80856e74 388
58616e67 389 return unbind_to (count, Fcall_process (nargs - 2, args + 2));
80856e74
JB
390}
391\f
392#ifndef VMS /* VMS version is in vmsproc.c. */
393
394/* This is the last thing run in a newly forked inferior
395 either synchronous or asynchronous.
396 Copy descriptors IN, OUT and ERR as descriptors 0, 1 and 2.
397 Initialize inferior's priority, pgrp, connected dir and environment.
398 then exec another program based on new_argv.
399
400 This function may change environ for the superior process.
401 Therefore, the superior process must save and restore the value
402 of environ around the vfork and the call to this function.
403
404 ENV is the environment for the subprocess.
405
406 SET_PGRP is nonzero if we should put the subprocess into a separate
e576cab4
JB
407 process group.
408
409 CURRENT_DIR is an elisp string giving the path of the current
410 directory the subprocess should have. Since we can't really signal
411 a decent error from within the child, this should be verified as an
412 executable directory by the parent. */
80856e74 413
e576cab4 414child_setup (in, out, err, new_argv, set_pgrp, current_dir)
80856e74
JB
415 int in, out, err;
416 register char **new_argv;
80856e74 417 int set_pgrp;
e576cab4 418 Lisp_Object current_dir;
80856e74 419{
e576cab4
JB
420 char **env;
421
80856e74
JB
422 register int pid = getpid();
423
4f0b9d49
JB
424 {
425 extern int emacs_priority;
426
427 nice (- emacs_priority);
428 }
80856e74
JB
429
430#ifdef subprocesses
431 /* Close Emacs's descriptors that this process should not have. */
432 close_process_descs ();
433#endif
434
435 /* Note that use of alloca is always safe here. It's obvious for systems
436 that do not have true vfork or that have true (stack) alloca.
437 If using vfork and C_ALLOCA it is safe because that changes
438 the superior's static variables as if the superior had done alloca
439 and will be cleaned up in the usual way. */
e576cab4
JB
440 {
441 register unsigned char *temp;
442 register int i;
77d78be1 443
e576cab4
JB
444 i = XSTRING (current_dir)->size;
445 temp = (unsigned char *) alloca (i + 2);
446 bcopy (XSTRING (current_dir)->data, temp, i);
447 if (temp[i - 1] != '/') temp[i++] = '/';
448 temp[i] = 0;
449
450 /* We can't signal an Elisp error here; we're in a vfork. Since
451 the callers check the current directory before forking, this
452 should only return an error if the directory's permissions
453 are changed between the check and this chdir, but we should
454 at least check. */
455 if (chdir (temp) < 0)
456 exit (errno);
457 }
80856e74 458
80856e74
JB
459 /* Set `env' to a vector of the strings in Vprocess_environment. */
460 {
461 register Lisp_Object tem;
462 register char **new_env;
463 register int new_length;
464
465 new_length = 0;
466 for (tem = Vprocess_environment;
467 (XTYPE (tem) == Lisp_Cons
468 && XTYPE (XCONS (tem)->car) == Lisp_String);
469 tem = XCONS (tem)->cdr)
470 new_length++;
471
cd9565ba 472 /* new_length + 1 to include terminating 0. */
80856e74
JB
473 env = new_env = (char **) alloca ((new_length + 1) * sizeof (char *));
474
cd9565ba 475 /* Copy the Vprocess_environment strings into new_env. */
80856e74
JB
476 for (tem = Vprocess_environment;
477 (XTYPE (tem) == Lisp_Cons
478 && XTYPE (XCONS (tem)->car) == Lisp_String);
479 tem = XCONS (tem)->cdr)
cd9565ba
RS
480 {
481 char **ep = env;
482 char *string = (char *) XSTRING (XCONS (tem)->car)->data;
483 /* See if this string duplicates any string already in the env.
484 If so, don't put it in.
485 When an env var has multiple definitions,
486 we keep the definition that comes first in process-environment. */
487 for (; ep != new_env; ep++)
488 {
489 char *p = *ep, *q = string;
490 while (1)
491 {
492 if (*q == 0)
493 /* The string is malformed; might as well drop it. */
494 goto duplicate;
495 if (*q != *p)
496 break;
497 if (*q == '=')
498 goto duplicate;
499 p++, q++;
500 }
501 }
502 *new_env++ = string;
503 duplicate: ;
504 }
80856e74
JB
505 *new_env = 0;
506 }
80856e74 507
426b37ae
JB
508 /* Make sure that in, out, and err are not actually already in
509 descriptors zero, one, or two; this could happen if Emacs is
510 started with its standard in, our, or error closed, as might
511 happen under X. */
512 in = relocate_fd (in, 3);
513 out = relocate_fd (out, 3);
514 err = relocate_fd (err, 3);
515
80856e74
JB
516 close (0);
517 close (1);
518 close (2);
519
520 dup2 (in, 0);
521 dup2 (out, 1);
522 dup2 (err, 2);
523 close (in);
524 close (out);
525 close (err);
526
fdba8590
RS
527#ifdef USG
528#ifndef SETPGRP_RELEASES_CTTY
e576cab4 529 setpgrp (); /* No arguments but equivalent in this case */
fdba8590 530#endif
e576cab4
JB
531#else
532 setpgrp (pid, pid);
533#endif /* USG */
80856e74
JB
534 setpgrp_of_tty (pid);
535
536#ifdef vipc
537 something missing here;
538#endif /* vipc */
539
540 /* execvp does not accept an environment arg so the only way
541 to pass this environment is to set environ. Our caller
542 is responsible for restoring the ambient value of environ. */
543 environ = env;
544 execvp (new_argv[0], new_argv);
545
546 write (1, "Couldn't exec the program ", 26);
547 write (1, new_argv[0], strlen (new_argv[0]));
548 _exit (1);
549}
550
426b37ae
JB
551/* Move the file descriptor FD so that its number is not less than MIN.
552 If the file descriptor is moved at all, the original is freed. */
553int
554relocate_fd (fd, min)
555 int fd, min;
556{
557 if (fd >= min)
558 return fd;
559 else
560 {
561 int new = dup (fd);
562 if (new == -1)
563 {
20c018a0
JB
564 char *message1 = "Error while setting up child: ";
565 char *message2 = "\n";
566 write (2, message1, strlen (message1));
426b37ae 567 write (2, sys_errlist[errno], strlen (sys_errlist[errno]));
20c018a0 568 write (2, message2, strlen (message2));
426b37ae
JB
569 _exit (1);
570 }
571 /* Note that we hold the original FD open while we recurse,
572 to guarantee we'll get a new FD if we need it. */
573 new = relocate_fd (new, min);
574 close (fd);
575 return new;
576 }
577}
578
012c6fcb
JA
579static int
580getenv_internal (var, varlen, value, valuelen)
581 char *var;
582 int varlen;
583 char **value;
584 int *valuelen;
585{
586 Lisp_Object scan;
587
588 for (scan = Vprocess_environment; CONSP (scan); scan = XCONS (scan)->cdr)
589 {
590 Lisp_Object entry = XCONS (scan)->car;
e576cab4 591
012c6fcb
JA
592 if (XTYPE (entry) == Lisp_String
593 && XSTRING (entry)->size > varlen
594 && XSTRING (entry)->data[varlen] == '='
595 && ! bcmp (XSTRING (entry)->data, var, varlen))
596 {
597 *value = (char *) XSTRING (entry)->data + (varlen + 1);
598 *valuelen = XSTRING (entry)->size - (varlen + 1);
599 return 1;
600 }
601 }
602
603 return 0;
604}
605
606DEFUN ("getenv", Fgetenv, Sgetenv, 1, 2, 0,
607 "Return the value of environment variable VAR, as a string.\n\
608VAR should be a string. Value is nil if VAR is undefined in the environment.\n\
609This function consults the variable ``process-environment'' for its value.")
610 (var)
611 Lisp_Object var;
612{
613 char *value;
614 int valuelen;
615
616 CHECK_STRING (var, 0);
617 if (getenv_internal (XSTRING (var)->data, XSTRING (var)->size,
618 &value, &valuelen))
619 return make_string (value, valuelen);
620 else
621 return Qnil;
622}
623
624/* A version of getenv that consults process_environment, easily
e576cab4 625 callable from C. */
012c6fcb
JA
626char *
627egetenv (var)
e576cab4 628 char *var;
012c6fcb
JA
629{
630 char *value;
631 int valuelen;
632
633 if (getenv_internal (var, strlen (var), &value, &valuelen))
634 return value;
635 else
636 return 0;
637}
638
80856e74
JB
639#endif /* not VMS */
640\f
8de15d69 641/* This is run before init_cmdargs. */
e576cab4 642
8de15d69
RS
643init_callproc_1 ()
644{
645 char *data_dir = egetenv ("EMACSDATA");
e576cab4 646
8de15d69
RS
647 Vdata_directory
648 = Ffile_name_as_directory (build_string (data_dir ? data_dir
649 : PATH_DATA));
9453ea7b 650
e576cab4
JB
651 /* Check the EMACSPATH environment variable, defaulting to the
652 PATH_EXEC path from paths.h. */
653 Vexec_path = decode_env_path ("EMACSPATH", PATH_EXEC);
80856e74
JB
654 Vexec_directory = Ffile_name_as_directory (Fcar (Vexec_path));
655 Vexec_path = nconc2 (decode_env_path ("PATH", ""), Vexec_path);
8de15d69
RS
656}
657
658/* This is run after init_cmdargs, so that Vinvocation_directory is valid. */
659
660init_callproc ()
661{
662 char *data_dir = egetenv ("EMACSDATA");
663
664 register char * sh;
665 Lisp_Object tempdir;
666
667 if (initialized && !NILP (Vinvocation_directory))
668 {
669 /* Add to the path the ../lib-src dir of the Emacs executable,
670 if that dir exists. */
671 Lisp_Object tem, tem1;
672 tem = Fexpand_file_name (build_string ("../lib-src"),
673 Vinvocation_directory);
674 tem1 = Ffile_exists_p (tem);
675 if (!NILP (tem1) && NILP (Fmember (tem, Vexec_path)))
676 {
677 Vexec_path = nconc2 (Vexec_path, Fcons (tem, Qnil));
678 Vexec_directory = Ffile_name_as_directory (tem);
679
680 /* If we use ../lib-src, maybe use ../etc as well.
681 Do so if ../etc exists and has our DOC-... file in it. */
682 if (data_dir == 0)
683 {
684 Lisp_Object tem, tem2, tem3;
685 tem = Fexpand_file_name (build_string ("../etc"),
686 Vinvocation_directory);
687 tem2 = Fexpand_file_name (Vdoc_file_name, tem);
688 tem3 = Ffile_exists_p (tem2);
fdba8590
RS
689 if (!NILP (tem3))
690 Vdata_directory = Ffile_name_as_directory (tem);
8de15d69
RS
691 }
692 }
693 }
80856e74 694
e576cab4
JB
695 tempdir = Fdirectory_file_name (Vexec_directory);
696 if (access (XSTRING (tempdir)->data, 0) < 0)
80856e74 697 {
e576cab4 698 printf ("Warning: arch-dependent data dir (%s) does not exist.\n",
80856e74
JB
699 XSTRING (Vexec_directory)->data);
700 sleep (2);
701 }
702
e576cab4
JB
703 tempdir = Fdirectory_file_name (Vdata_directory);
704 if (access (XSTRING (tempdir)->data, 0) < 0)
705 {
706 printf ("Warning: arch-independent data dir (%s) does not exist.\n",
707 XSTRING (Vdata_directory)->data);
708 sleep (2);
709 }
710
80856e74
JB
711#ifdef VMS
712 Vshell_file_name = build_string ("*dcl*");
713#else
e576cab4 714 sh = (char *) getenv ("SHELL");
80856e74
JB
715 Vshell_file_name = build_string (sh ? sh : "/bin/sh");
716#endif
9fefd2ba
JB
717}
718
719set_process_environment ()
720{
721 register char **envp;
80856e74 722
80856e74
JB
723 Vprocess_environment = Qnil;
724#ifndef CANNOT_DUMP
725 if (initialized)
726#endif
727 for (envp = environ; *envp; envp++)
728 Vprocess_environment = Fcons (build_string (*envp),
729 Vprocess_environment);
80856e74
JB
730}
731
732syms_of_callproc ()
733{
734 DEFVAR_LISP ("shell-file-name", &Vshell_file_name,
735 "*File name to load inferior shells from.\n\
736Initialized from the SHELL environment variable.");
737
738 DEFVAR_LISP ("exec-path", &Vexec_path,
739 "*List of directories to search programs to run in subprocesses.\n\
740Each element is a string (directory name) or nil (try default directory).");
741
742 DEFVAR_LISP ("exec-directory", &Vexec_directory,
e576cab4
JB
743 "Directory of architecture-dependent files that come with GNU Emacs,\n\
744especially executable programs intended for Emacs to invoke.");
745
746 DEFVAR_LISP ("data-directory", &Vdata_directory,
747 "Directory of architecture-independent files that come with GNU Emacs,\n\
748intended for Emacs to use.");
80856e74 749
ed61592a
JB
750 DEFVAR_LISP ("configure-info-directory", &Vconfigure_info_directory,
751 "For internal use by the build procedure only.\n\
752This is the name of the directory in which the build procedure installed\n\
753Emacs's info files; the default value for Info-default-directory-list\n\
754includes this.");
755 Vconfigure_info_directory = build_string (PATH_INFO);
756
80856e74 757 DEFVAR_LISP ("process-environment", &Vprocess_environment,
e576cab4
JB
758 "List of environment variables for subprocesses to inherit.\n\
759Each element should be a string of the form ENVVARNAME=VALUE.\n\
760The environment which Emacs inherits is placed in this variable\n\
761when Emacs starts.");
80856e74
JB
762
763#ifndef VMS
764 defsubr (&Scall_process);
012c6fcb 765 defsubr (&Sgetenv);
986ffb24 766#endif
e576cab4 767 defsubr (&Scall_process_region);
80856e74 768}