/* Synchronous subprocess invocation for GNU Emacs.
- Copyright (C) 1985, 1986, 1987, 1988, 1992 Free Software Foundation, Inc.
+ Copyright (C) 1985, 1986, 1987, 1988, 1993, 1994 Free Software Foundation, Inc.
This file is part of GNU Emacs.
GNU Emacs is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 1, or (at your option)
+the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Emacs is distributed in the hope that it will be useful,
#include <signal.h>
#include <errno.h>
+#include <stdio.h>
-#include "config.h"
+#include <config.h>
+
+extern int errno;
+extern char *strerror ();
/* Define SIGCHLD as an alias for SIGCLD. */
#endif /* SIGCLD */
#include <sys/types.h>
-#define PRIO_PROCESS 0
+
#include <sys/file.h>
#ifdef USG5
#include <fcntl.h>
#endif
+#ifdef MSDOS /* Demacs 1.1.1 91/10/16 HIRANO Satoshi */
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/param.h>
+#include <errno.h>
+#endif /* MSDOS */
+
#ifndef O_RDONLY
#define O_RDONLY 0
#endif
#include "lisp.h"
#include "commands.h"
#include "buffer.h"
-#include "paths.h"
+#include <paths.h>
#include "process.h"
+#include "syssignal.h"
+#include "systty.h"
#ifdef VMS
extern noshare char **environ;
#define max(a, b) ((a) > (b) ? (a) : (b))
-Lisp_Object Vexec_path, Vexec_directory, Vdata_directory;
+#ifdef MSDOS
+Lisp_Object Vbinary_process;
+#endif
+
+Lisp_Object Vexec_path, Vexec_directory, Vdata_directory, Vdoc_directory;
+Lisp_Object Vconfigure_info_directory;
Lisp_Object Vshell_file_name;
/* If synch_process_death is zero,
this is exit code of synchronous subprocess. */
int synch_process_retcode;
+
+extern Lisp_Object Vdoc_file_name;
\f
+/* Clean up when exiting Fcall_process.
+ On MSDOS, delete the temporary file on any kind of termination.
+ On Unix, kill the process and any children on termination by signal. */
+
+/* Nonzero if this is termination due to exit. */
+static int call_process_exited;
+
#ifndef VMS /* VMS version is in vmsproc.c. */
+static Lisp_Object
+call_process_kill (fdpid)
+ Lisp_Object fdpid;
+{
+ close (XFASTINT (Fcar (fdpid)));
+ EMACS_KILLPG (XFASTINT (Fcdr (fdpid)), SIGKILL);
+ synch_process_alive = 0;
+ return Qnil;
+}
+
Lisp_Object
call_process_cleanup (fdpid)
Lisp_Object fdpid;
{
- register Lisp_Object fd, pid;
- fd = Fcar (fdpid);
- pid = Fcdr (fdpid);
- close (XFASTINT (fd));
- kill (XFASTINT (pid), SIGKILL);
+#ifdef MSDOS
+ /* for MSDOS fdpid is really (fd . tempfile) */
+ register Lisp_Object file;
+ file = Fcdr (fdpid);
+ close (XFASTINT (Fcar (fdpid)));
+ if (strcmp (XSTRING (file)-> data, NULL_DEVICE) != 0)
+ unlink (XSTRING (file)->data);
+#else /* not MSDOS */
+ register int pid = XFASTINT (Fcdr (fdpid));
+
+
+ if (call_process_exited)
+ {
+ close (XFASTINT (Fcar (fdpid)));
+ return Qnil;
+ }
+
+ if (EMACS_KILLPG (pid, SIGINT) == 0)
+ {
+ int count = specpdl_ptr - specpdl;
+ record_unwind_protect (call_process_kill, fdpid);
+ message1 ("Waiting for process to die...(type C-g again to kill it instantly)");
+ immediate_quit = 1;
+ QUIT;
+ wait_for_termination (pid);
+ immediate_quit = 0;
+ specpdl_ptr = specpdl + count; /* Discard the unwind protect. */
+ message1 ("Waiting for process to die...done");
+ }
synch_process_alive = 0;
+ close (XFASTINT (Fcar (fdpid)));
+#endif /* not MSDOS */
return Qnil;
}
nil for BUFFER means discard it; 0 means discard and don't wait.\n\
Fourth arg DISPLAY non-nil means redisplay buffer as output is inserted.\n\
Remaining arguments are strings passed as command arguments to PROGRAM.\n\
-If BUFFER is nil or 0, returns immediately with value nil.\n\
+If BUFFER is 0, returns immediately with value nil.\n\
Otherwise waits for PROGRAM to terminate\n\
-and returns a numeric exit status or a signal name as a string.\n\
-If you quit, the process is killed with SIGKILL.")
+and returns a numeric exit status or a signal description string.\n\
+If you quit, the process is killed with SIGINT, or SIGKILL if you quit again.")
(nargs, args)
int nargs;
register Lisp_Object *args;
{
- Lisp_Object display, infile, buffer, path, current_dir;
+ Lisp_Object infile, buffer, current_dir, display, path;
int fd[2];
int filefd;
register int pid;
register unsigned char **new_argv
= (unsigned char **) alloca ((max (2, nargs - 2)) * sizeof (char *));
struct buffer *old = current_buffer;
+#ifdef MSDOS /* Demacs 1.1.1 91/10/16 HIRANO Satoshi */
+ char *outf, *tempfile;
+ int outfilefd;
+#endif
#if 0
int mask;
#endif
CHECK_STRING (args[0], 0);
+#ifndef subprocesses
+ /* Without asynchronous processes we cannot have BUFFER == 0. */
+ if (nargs >= 3 && XTYPE (args[2]) == Lisp_Int)
+ error ("Operating system cannot handle asynchronous subprocesses");
+#endif /* subprocesses */
+
if (nargs >= 2 && ! NILP (args[1]))
{
infile = Fexpand_file_name (args[1], current_buffer->directory);
CHECK_STRING (infile, 1);
}
else
- infile = build_string ("/dev/null");
+ infile = build_string (NULL_DEVICE);
+
+ if (nargs >= 3)
+ {
+ register Lisp_Object tem;
+
+ buffer = tem = args[2];
+ if (!(EQ (tem, Qnil)
+ || EQ (tem, Qt)
+ || XFASTINT (tem) == 0))
+ {
+ buffer = Fget_buffer (tem);
+ CHECK_BUFFER (buffer, 2);
+ }
+ }
+ else
+ buffer = Qnil;
+ /* Make sure that the child will be able to chdir to the current
+ buffer's current directory, or its unhandled equivalent. We
+ can't just have the child check for an error when it does the
+ chdir, since it's in a vfork.
+
+ We have to GCPRO around this because Fexpand_file_name,
+ Funhandled_file_name_directory, and Ffile_accessible_directory_p
+ might call a file name handling function. The argument list is
+ protected by the caller, so all we really have to worry about is
+ buffer. */
{
- register Lisp_Object tem;
- if (nargs < 3)
- buffer = Qnil;
- else
- {
- buffer = tem = args[2];
- if (!(EQ (tem, Qnil) || EQ (tem, Qt)
- || XFASTINT (tem) == 0))
- {
- buffer = Fget_buffer (tem);
- CHECK_BUFFER (buffer, 2);
- }
- }
+ struct gcpro gcpro1, gcpro2, gcpro3;
+
+ current_dir = current_buffer->directory;
+
+ GCPRO3 (infile, buffer, current_dir);
+
+ current_dir
+ = expand_and_dir_to_file (Funhandled_file_name_directory (current_dir),
+ Qnil);
+ if (NILP (Ffile_accessible_directory_p (current_dir)))
+ report_file_error ("Setting current directory",
+ Fcons (current_buffer->directory, Qnil));
+
+ UNGCPRO;
}
- display = nargs >= 3 ? args[3] : Qnil;
+ display = nargs >= 4 ? args[3] : Qnil;
+
+ filefd = open (XSTRING (infile)->data, O_RDONLY, 0);
+ if (filefd < 0)
+ {
+ report_file_error ("Opening process input file", Fcons (infile, Qnil));
+ }
+ /* Search for program; barf if not found. */
+ {
+ struct gcpro gcpro1;
+ GCPRO1 (current_dir);
+ openp (Vexec_path, args[0], EXEC_SUFFIXES, &path, 1);
+ UNGCPRO;
+ }
+ if (NILP (path))
+ {
+ close (filefd);
+ report_file_error ("Searching for program", Fcons (args[0], Qnil));
+ }
+ new_argv[0] = XSTRING (path)->data;
{
register int i;
for (i = 4; i < nargs; i++)
CHECK_STRING (args[i], i);
new_argv[i - 3] = XSTRING (args[i])->data;
}
- /* Program name is first command arg */
- new_argv[0] = XSTRING (args[0])->data;
new_argv[i - 3] = 0;
}
- filefd = open (XSTRING (infile)->data, O_RDONLY, 0);
- if (filefd < 0)
+#ifdef MSDOS /* MW, July 1993 */
+ /* These vars record information from process termination.
+ Clear them now before process can possibly terminate,
+ to avoid timing error if process terminates soon. */
+ synch_process_death = 0;
+ synch_process_retcode = 0;
+
+ if ((outf = egetenv ("TMP")) || (outf = egetenv ("TEMP")))
+ strcpy (tempfile = alloca (strlen (outf) + 20), outf);
+ else
{
- report_file_error ("Opening process input file", Fcons (infile, Qnil));
+ tempfile = alloca (20);
+ *tempfile = '\0';
}
- /* Search for program; barf if not found. */
- openp (Vexec_path, args[0], "", &path, 1);
- if (NILP (path))
+ dostounix_filename (tempfile);
+ if (*tempfile == '\0' || tempfile[strlen (tempfile) - 1] != '/')
+ strcat (tempfile, "/");
+ strcat (tempfile, "detmp.XXX");
+ mktemp (tempfile);
+
+ outfilefd = creat (tempfile, S_IREAD | S_IWRITE);
+ if (outfilefd < 0)
{
close (filefd);
- report_file_error ("Searching for program", Fcons (args[0], Qnil));
+ report_file_error ("Opening process output file", Fcons (tempfile, Qnil));
}
- new_argv[0] = XSTRING (path)->data;
+#endif
if (XTYPE (buffer) == Lisp_Int)
- fd[1] = open ("/dev/null", O_WRONLY), fd[0] = -1;
+ fd[1] = open (NULL_DEVICE, O_WRONLY), fd[0] = -1;
else
{
+#ifndef MSDOS
pipe (fd);
+#endif
#if 0
/* Replaced by close_process_descs */
set_exclusive_use (fd[0]);
#endif
}
- /* Make sure that the child will be able to chdir to the current
- buffer's current directory. We can't just have the child check
- for an error when it does the chdir, since it's in a vfork. */
- current_dir = expand_and_dir_to_file (current_buffer->directory, Qnil);
- if (NILP (Ffile_accessible_directory_p (current_dir)))
- report_file_error ("Setting current directory",
- Fcons (current_buffer->directory, Qnil));
-
{
/* child_setup must clobber environ in systems with true vfork.
Protect it from permanent change. */
/* Record that we're about to create a synchronous process. */
synch_process_alive = 1;
+ /* These vars record information from process termination.
+ Clear them now before process can possibly terminate,
+ to avoid timing error if process terminates soon. */
+ synch_process_death = 0;
+ synch_process_retcode = 0;
+
+#ifdef MSDOS /* MW, July 1993 */
+ /* ??? Someone who knows MSDOG needs to check whether this properly
+ closes all descriptors that it opens. */
+ pid = run_msdos_command (new_argv, current_dir, filefd, outfilefd);
+ close (outfilefd);
+ fd1 = -1; /* No harm in closing that one! */
+ fd[0] = open (tempfile, NILP (Vbinary_process) ? O_TEXT : O_BINARY);
+ if (fd[0] < 0)
+ {
+ unlink (tempfile);
+ close (filefd);
+ report_file_error ("Cannot re-open temporary file", Qnil);
+ }
+#else /* not MSDOS */
pid = vfork ();
if (pid == 0)
#endif /* USG */
child_setup (filefd, fd1, fd1, new_argv, 0, current_dir);
}
-
-#if 0
- /* Tell SIGCHLD handler to look for this pid. */
- synch_process_pid = pid;
- /* Now let SIGCHLD come through. */
- sigsetmask (mask);
-#endif
+#endif /* not MSDOS */
environ = save_environ;
+ /* Close most of our fd's, but not fd[0]
+ since we will use that to read input from. */
close (filefd);
- close (fd1);
+ if (fd1 >= 0)
+ close (fd1);
}
if (pid < 0)
{
- close (fd[0]);
+ if (fd[0] >= 0)
+ close (fd[0]);
report_file_error ("Doing vfork", Qnil);
}
if (XTYPE (buffer) == Lisp_Int)
{
+ if (fd[0] >= 0)
+ close (fd[0]);
#ifndef subprocesses
/* If Emacs has been built with asynchronous subprocess support,
we don't need to do this, I think because it will then have
return Qnil;
}
- synch_process_death = 0;
- synch_process_retcode = 0;
+ /* Enable sending signal if user quits below. */
+ call_process_exited = 0;
+#ifdef MSDOS
+ /* MSDOS needs different cleanup information. */
+ record_unwind_protect (call_process_cleanup,
+ Fcons (make_number (fd[0]), build_string (tempfile)));
+#else
record_unwind_protect (call_process_cleanup,
Fcons (make_number (fd[0]), make_number (pid)));
+#endif /* not MSDOS */
if (XTYPE (buffer) == Lisp_Buffer)
{
register int nread;
+ int first = 1;
while ((nread = read (fd[0], buf, sizeof buf)) > 0)
{
if (!NILP (buffer))
insert (buf, nread);
if (!NILP (display) && INTERACTIVE)
- redisplay_preserve_echo_area ();
+ {
+ if (first)
+ prepare_menu_bars ();
+ first = 0;
+ redisplay_preserve_echo_area ();
+ }
immediate_quit = 1;
QUIT;
}
set_buffer_internal (old);
+ /* Don't kill any children that the subprocess may have left behind
+ when exiting. */
+ call_process_exited = 1;
+
unbind_to (count, Qnil);
if (synch_process_death)
}
#endif
\f
-static void
+static Lisp_Object
delete_temp_file (name)
Lisp_Object name;
{
Remaining args are passed to PROGRAM at startup as command args.\n\
If BUFFER is nil, returns immediately with value nil.\n\
Otherwise waits for PROGRAM to terminate\n\
-and returns a numeric exit status or a signal name as a string.\n\
-If you quit, the process is killed with SIGKILL.")
+and returns a numeric exit status or a signal description string.\n\
+If you quit, the process is killed with SIGINT, or SIGKILL if you quit again.")
(nargs, args)
int nargs;
register Lisp_Object *args;
{
register Lisp_Object filename_string, start, end;
+#ifdef MSDOS
+ char *tempfile;
+#else
char tempfile[20];
+#endif
int count = specpdl_ptr - specpdl;
+#ifdef MSDOS
+ char *outf = '\0';
+
+ if ((outf = egetenv ("TMP")) || (outf = egetenv ("TEMP")))
+ strcpy (tempfile = alloca (strlen (outf) + 20), outf);
+ else
+ {
+ tempfile = alloca (20);
+ *tempfile = '\0';
+ }
+ dostounix_filename (tempfile);
+ if (tempfile[strlen (tempfile) - 1] != '/')
+ strcat (tempfile, "/");
+ strcat (tempfile, "detmp.XXX");
+#else /* not MSDOS */
#ifdef VMS
strcpy (tempfile, "tmp:emacsXXXXXX.");
#else
strcpy (tempfile, "/tmp/emacsXXXXXX");
#endif
+#endif /* not MSDOS */
+
mktemp (tempfile);
filename_string = build_string (tempfile);
Fdelete_region (start, end);
args[3] = filename_string;
- Fcall_process (nargs - 2, args + 2);
- return unbind_to (count, Qnil);
+ return unbind_to (count, Fcall_process (nargs - 2, args + 2));
}
\f
#ifndef VMS /* VMS version is in vmsproc.c. */
int set_pgrp;
Lisp_Object current_dir;
{
+#ifdef MSDOS
+ /* The MSDOS port of gcc cannot fork, vfork, ... so we must call system
+ instead. */
+#else /* not MSDOS */
char **env;
- register int pid = getpid();
+ int pid = getpid ();
- setpriority (PRIO_PROCESS, pid, 0);
+ {
+ extern int emacs_priority;
+
+ nice (- emacs_priority);
+ }
#ifdef subprocesses
/* Close Emacs's descriptors that this process should not have. */
close_process_descs ();
#endif
+ close_load_descs ();
/* Note that use of alloca is always safe here. It's obvious for systems
that do not have true vfork or that have true (stack) alloca.
tem = XCONS (tem)->cdr)
new_length++;
- /* new_length + 1 to include terminating 0 */
+ /* new_length + 1 to include terminating 0. */
env = new_env = (char **) alloca ((new_length + 1) * sizeof (char *));
- /* Copy the Vprocess_alist strings into new_env. */
+ /* Copy the Vprocess_environment strings into new_env. */
for (tem = Vprocess_environment;
(XTYPE (tem) == Lisp_Cons
&& XTYPE (XCONS (tem)->car) == Lisp_String);
tem = XCONS (tem)->cdr)
- *new_env++ = (char *) XSTRING (XCONS (tem)->car)->data;
+ {
+ char **ep = env;
+ char *string = (char *) XSTRING (XCONS (tem)->car)->data;
+ /* See if this string duplicates any string already in the env.
+ If so, don't put it in.
+ When an env var has multiple definitions,
+ we keep the definition that comes first in process-environment. */
+ for (; ep != new_env; ep++)
+ {
+ char *p = *ep, *q = string;
+ while (1)
+ {
+ if (*q == 0)
+ /* The string is malformed; might as well drop it. */
+ goto duplicate;
+ if (*q != *p)
+ break;
+ if (*q == '=')
+ goto duplicate;
+ p++, q++;
+ }
+ }
+ *new_env++ = string;
+ duplicate: ;
+ }
*new_env = 0;
}
+ /* Make sure that in, out, and err are not actually already in
+ descriptors zero, one, or two; this could happen if Emacs is
+ started with its standard in, out, or error closed, as might
+ happen under X. */
+ in = relocate_fd (in, 3);
+ if (out == err)
+ err = out = relocate_fd (out, 3);
+ else
+ {
+ out = relocate_fd (out, 3);
+ err = relocate_fd (err, 3);
+ }
+
close (0);
close (1);
close (2);
close (err);
#ifdef USG
+#ifndef SETPGRP_RELEASES_CTTY
setpgrp (); /* No arguments but equivalent in this case */
+#endif
#else
setpgrp (pid, pid);
#endif /* USG */
- setpgrp_of_tty (pid);
+ /* setpgrp_of_tty is incorrect here; it uses input_fd. */
+ EMACS_SET_TTY_PGRP (0, &pid);
#ifdef vipc
something missing here;
write (1, "Couldn't exec the program ", 26);
write (1, new_argv[0], strlen (new_argv[0]));
_exit (1);
+#endif /* not MSDOS */
+}
+
+/* Move the file descriptor FD so that its number is not less than MIN.
+ If the file descriptor is moved at all, the original is freed. */
+int
+relocate_fd (fd, min)
+ int fd, min;
+{
+ if (fd >= min)
+ return fd;
+ else
+ {
+ int new = dup (fd);
+ if (new == -1)
+ {
+ char *message1 = "Error while setting up child: ";
+ char *errmessage = strerror (errno);
+ char *message2 = "\n";
+ write (2, message1, strlen (message1));
+ write (2, errmessage, strlen (errmessage));
+ write (2, message2, strlen (message2));
+ _exit (1);
+ }
+ /* Note that we hold the original FD open while we recurse,
+ to guarantee we'll get a new FD if we need it. */
+ new = relocate_fd (new, min);
+ close (fd);
+ return new;
+ }
}
static int
for (scan = Vprocess_environment; CONSP (scan); scan = XCONS (scan)->cdr)
{
- Lisp_Object entry = XCONS (scan)->car;
-
+ Lisp_Object entry;
+
+ entry = XCONS (scan)->car;
if (XTYPE (entry) == Lisp_String
&& XSTRING (entry)->size > varlen
&& XSTRING (entry)->data[varlen] == '='
return 0;
}
-DEFUN ("getenv", Fgetenv, Sgetenv, 1, 2, 0,
+DEFUN ("getenv", Fgetenv, Sgetenv, 1, 1, 0,
"Return the value of environment variable VAR, as a string.\n\
VAR should be a string. Value is nil if VAR is undefined in the environment.\n\
This function consults the variable ``process-environment'' for its value.")
#endif /* not VMS */
\f
-init_callproc ()
+/* This is run before init_cmdargs. */
+
+init_callproc_1 ()
{
- register char * sh;
- register char **envp;
- Lisp_Object tempdir;
+ char *data_dir = egetenv ("EMACSDATA");
+ char *doc_dir = egetenv ("EMACSDOC");
- {
- char *data_dir = egetenv ("EMACSDATA");
-
- Vdata_directory =
- Ffile_name_as_directory
- (build_string (data_dir ? data_dir : PATH_DATA));
- }
+ Vdata_directory
+ = Ffile_name_as_directory (build_string (data_dir ? data_dir
+ : PATH_DATA));
+ Vdoc_directory
+ = Ffile_name_as_directory (build_string (doc_dir ? doc_dir
+ : PATH_DOC));
/* Check the EMACSPATH environment variable, defaulting to the
PATH_EXEC path from paths.h. */
Vexec_path = decode_env_path ("EMACSPATH", PATH_EXEC);
Vexec_directory = Ffile_name_as_directory (Fcar (Vexec_path));
Vexec_path = nconc2 (decode_env_path ("PATH", ""), Vexec_path);
+}
+
+/* This is run after init_cmdargs, so that Vinvocation_directory is valid. */
+
+init_callproc ()
+{
+ char *data_dir = egetenv ("EMACSDATA");
+
+ register char * sh;
+ Lisp_Object tempdir;
+
+ if (initialized && !NILP (Vinstallation_directory))
+ {
+ /* Add to the path the lib-src subdir of the installation dir. */
+ Lisp_Object tem;
+ tem = Fexpand_file_name (build_string ("lib-src"),
+ Vinstallation_directory);
+ if (NILP (Fmember (tem, Vexec_path)))
+ {
+ Vexec_path = nconc2 (Vexec_path, Fcons (tem, Qnil));
+ Vexec_directory = Ffile_name_as_directory (tem);
+
+ /* If we use ../lib-src, maybe use ../etc as well.
+ Do so if ../etc exists and has our DOC-... file in it. */
+ if (data_dir == 0)
+ {
+ tem = Fexpand_file_name (build_string ("etc"),
+ Vinstallation_directory);
+ Vdata_directory = Ffile_name_as_directory (tem);
+ }
+ }
+ }
tempdir = Fdirectory_file_name (Vexec_directory);
if (access (XSTRING (tempdir)->data, 0) < 0)
{
- printf ("Warning: arch-dependent data dir (%s) does not exist.\n",
- XSTRING (Vexec_directory)->data);
+ fprintf (stderr,
+ "Warning: arch-dependent data dir (%s) does not exist.\n",
+ XSTRING (Vexec_directory)->data);
sleep (2);
}
tempdir = Fdirectory_file_name (Vdata_directory);
if (access (XSTRING (tempdir)->data, 0) < 0)
{
- printf ("Warning: arch-independent data dir (%s) does not exist.\n",
- XSTRING (Vdata_directory)->data);
+ fprintf (stderr,
+ "Warning: arch-independent data dir (%s) does not exist.\n",
+ XSTRING (Vdata_directory)->data);
sleep (2);
}
sh = (char *) getenv ("SHELL");
Vshell_file_name = build_string (sh ? sh : "/bin/sh");
#endif
+}
+
+set_process_environment ()
+{
+ register char **envp;
Vprocess_environment = Qnil;
#ifndef CANNOT_DUMP
syms_of_callproc ()
{
+#ifdef MSDOS
+ DEFVAR_LISP ("binary-process", &Vbinary_process,
+ "*If non-nil then new subprocesses are assumed to produce binary output.");
+ Vbinary_process = Qnil;
+#endif
+
DEFVAR_LISP ("shell-file-name", &Vshell_file_name,
"*File name to load inferior shells from.\n\
Initialized from the SHELL environment variable.");
"Directory of architecture-independent files that come with GNU Emacs,\n\
intended for Emacs to use.");
+ DEFVAR_LISP ("doc-directory", &Vdoc_directory,
+ "Directory containing the DOC file that comes with GNU Emacs.\n\
+This is usually the same as data-directory.");
+
+ DEFVAR_LISP ("configure-info-directory", &Vconfigure_info_directory,
+ "For internal use by the build procedure only.\n\
+This is the name of the directory in which the build procedure installed\n\
+Emacs's info files; the default value for Info-default-directory-list\n\
+includes this.");
+ Vconfigure_info_directory = build_string (PATH_INFO);
+
DEFVAR_LISP ("process-environment", &Vprocess_environment,
"List of environment variables for subprocesses to inherit.\n\
Each element should be a string of the form ENVVARNAME=VALUE.\n\
#ifndef VMS
defsubr (&Scall_process);
-#endif
defsubr (&Sgetenv);
+#endif
defsubr (&Scall_process_region);
}