X-Git-Url: http://git.hcoop.net/bpt/emacs.git/blobdiff_plain/7e6c2178ef8c158c5625bc460240482377659e6a..f32b54d420f23e5da7b9b89f06daff69d7b31511:/src/callproc.c diff --git a/src/callproc.c b/src/callproc.c index 174ffa214d..21d0f444a7 100644 --- a/src/callproc.c +++ b/src/callproc.c @@ -1,11 +1,11 @@ /* Synchronous subprocess invocation for GNU Emacs. - Copyright (C) 1985, 1986, 1987, 1988, 1993 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, @@ -20,13 +20,12 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include +#include #include extern int errno; -#ifndef VMS -extern char *sys_errlist[]; -#endif +extern char *strerror (); /* Define SIGCHLD as an alias for SIGCLD. */ @@ -76,7 +75,7 @@ extern char **environ; 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; @@ -96,6 +95,13 @@ int synch_process_retcode; extern Lisp_Object Vdoc_file_name; +/* 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 @@ -121,6 +127,9 @@ call_process_cleanup (fdpid) #else /* not MSDOS */ register int pid = XFASTINT (Fcdr (fdpid)); + if (call_process_exited) + return Qnil; + if (EMACS_KILLPG (pid, SIGINT) == 0) { int count = specpdl_ptr - specpdl; @@ -219,9 +228,9 @@ If you quit, the process is killed with SIGINT, or SIGKILL if you quit again.") 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)); @@ -231,31 +240,34 @@ If you quit, the process is killed with SIGINT, or SIGKILL if you quit again.") 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. @@ -374,6 +386,8 @@ If you quit, the process is killed with SIGINT, or SIGKILL if you quit again.") return Qnil; } + call_process_exited = 0; + #ifdef MSDOS /* MSDOS needs different cleanup information. */ record_unwind_protect (call_process_cleanup, @@ -418,6 +432,10 @@ If you quit, the process is killed with SIGINT, or SIGKILL if you quit again.") 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) @@ -529,7 +547,7 @@ child_setup (in, out, err, new_argv, set_pgrp, current_dir) #else /* not MSDOS */ char **env; - register int pid = getpid (); + int pid = getpid (); { extern int emacs_priority; @@ -541,6 +559,7 @@ child_setup (in, out, err, new_argv, set_pgrp, current_dir) /* 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. @@ -674,9 +693,10 @@ relocate_fd (fd, min) if (new == -1) { char *message1 = "Error while setting up child: "; + char *errmessage = strerror (errno); char *message2 = "\n"; write (2, message1, strlen (message1)); - write (2, sys_errlist[errno], strlen (sys_errlist[errno])); + write (2, errmessage, strlen (errmessage)); write (2, message2, strlen (message2)); _exit (1); } @@ -755,10 +775,14 @@ egetenv (var) 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. */ @@ -776,15 +800,13 @@ init_callproc () 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); @@ -793,13 +815,9 @@ init_callproc () 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); } } } @@ -807,16 +825,18 @@ init_callproc () 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); } @@ -865,6 +885,10 @@ especially executable programs intended for Emacs to invoke."); "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\