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