#include <signal.h>
#include <errno.h>
+#include <stdio.h>
#include <config.h>
Lisp_Object Vbinary_process;
#endif
-Lisp_Object Vexec_path, Vexec_directory, Vdata_directory;
+Lisp_Object Vexec_path, Vexec_directory, Vdata_directory, Vdoc_directory;
Lisp_Object Vconfigure_info_directory;
Lisp_Object Vshell_file_name;
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
{
#ifdef MSDOS
/* for MSDOS fdpid is really (fd . tempfile) */
- register Lisp_Object file = Fcdr (fdpid);
+ 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;
GCPRO3 (infile, buffer, current_dir);
- current_dir =
- expand_and_dir_to_file
- (Funhandled_file_name_directory (current_dir), Qnil);
+ 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));
display = nargs >= 4 ? args[3] : Qnil;
- {
- 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)
{
report_file_error ("Opening process input file", Fcons (infile, Qnil));
}
/* Search for program; barf if not found. */
- openp (Vexec_path, args[0], EXEC_SUFFIXES, &path, 1);
+ {
+ 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;
+ }
+ new_argv[i - 3] = 0;
+ }
#ifdef MSDOS /* MW, July 1993 */
/* These vars record information from process termination.
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! */
if (fd[0] < 0)
{
unlink (tempfile);
+ close (filefd);
report_file_error ("Cannot re-open temporary file", Qnil);
}
#else /* not MSDOS */
}
#endif /* not MSDOS */
-#if 0
- /* Tell SIGCHLD handler to look for this pid. */
- synch_process_pid = pid;
- /* Now let SIGCHLD come through. */
- sigsetmask (mask);
-#endif
-
environ = save_environ;
+ /* Close most of our fd's, but not fd[0]
+ since we will use that to read input from. */
close (filefd);
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;
}
+ /* Enable sending signal if user quits below. */
+ call_process_exited = 0;
+
#ifdef MSDOS
/* MSDOS needs different cleanup information. */
record_unwind_protect (call_process_cleanup,
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)
/* 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.
started with its standard in, out, or error closed, as might
happen under X. */
in = relocate_fd (in, 3);
- out = relocate_fd (out, 3);
- err = relocate_fd (err, 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);
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] == '='
init_callproc_1 ()
{
char *data_dir = egetenv ("EMACSDATA");
-
+ char *doc_dir = egetenv ("EMACSDOC");
+
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. */
register char * sh;
Lisp_Object tempdir;
- if (initialized && !NILP (Vinvocation_directory))
+ if (initialized && !NILP (Vinstallation_directory))
{
- /* Add to the path the ../lib-src dir of the Emacs executable,
- if that dir exists. */
- Lisp_Object tem, tem1;
- tem = Fexpand_file_name (build_string ("../lib-src"),
- Vinvocation_directory);
- tem1 = Ffile_exists_p (tem);
- if (!NILP (tem1) && NILP (Fmember (tem, Vexec_path)))
+ /* 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);
Do so if ../etc exists and has our DOC-... file in it. */
if (data_dir == 0)
{
- Lisp_Object tem, tem2, tem3;
- tem = Fexpand_file_name (build_string ("../etc"),
- Vinvocation_directory);
- tem2 = Fexpand_file_name (Vdoc_file_name, tem);
- tem3 = Ffile_exists_p (tem2);
- if (!NILP (tem3))
- Vdata_directory = Ffile_name_as_directory (tem);
+ 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);
}
"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\