X-Git-Url: http://git.hcoop.net/bpt/emacs.git/blobdiff_plain/c4e6b585bbdf26cfbb5b79da216e347e195dc38d..2bfa3d3e1fb347ba76bddf77f3e288049635821d:/src/callproc.c diff --git a/src/callproc.c b/src/callproc.c index 7ba3e398b4..56bdc7de0e 100644 --- a/src/callproc.c +++ b/src/callproc.c @@ -82,12 +82,7 @@ static Lisp_Object Vtemp_file_name_pattern; /* If nonzero, a process-ID that has not been reaped. */ static pid_t synch_process_pid; -/* If a string, the name of a temp file that has not been removed. */ -#ifdef MSDOS static Lisp_Object synch_process_tempfile; -#else -# define synch_process_tempfile make_number (0) -#endif /* Indexes of file descriptors that need closing on call_process_kill. */ enum @@ -103,31 +98,8 @@ enum CALLPROC_FDS }; -static Lisp_Object call_process (ptrdiff_t, Lisp_Object *, int, ptrdiff_t); +static Lisp_Object call_process (ptrdiff_t, Lisp_Object *, int *, Lisp_Object *); - -#ifndef MSDOS -/* Block SIGCHLD. */ - -void -block_child_signal (void) -{ - sigset_t blocked; - sigemptyset (&blocked); - sigaddset (&blocked, SIGCHLD); - pthread_sigmask (SIG_BLOCK, &blocked, 0); -} - -/* Unblock SIGCHLD. */ - -void -unblock_child_signal (void) -{ - pthread_sigmask (SIG_SETMASK, &empty_mask, 0); -} - -#endif /* !MSDOS */ - /* Return the current buffer's working directory, or the home directory if it's unreachable, as a string suitable for a system call. Signal an error if the result would not be an accessible directory. */ @@ -156,7 +128,7 @@ encode_current_directory (void) report_file_error ("Setting current directory", BVAR (current_buffer, directory)); - RETURN_UNGCPRO (dir); + return dir; } /* If P is reapable, record it as a deleted process and kill it. @@ -167,7 +139,8 @@ void record_kill_process (struct Lisp_Process *p, Lisp_Object tempfile) { #ifndef MSDOS - block_child_signal (); + sigset_t oldset; + block_child_signal (&oldset); if (p->alive) { @@ -176,16 +149,18 @@ record_kill_process (struct Lisp_Process *p, Lisp_Object tempfile) kill (- p->pid, SIGKILL); } - unblock_child_signal (); + unblock_child_signal (&oldset); #endif /* !MSDOS */ } /* Clean up files, file descriptors and processes created by Fcall_process. */ static void -delete_temp_file (Lisp_Object name) +delete_temp_file_ptr (Lisp_Object *name_ptr) { - unlink (SSDATA (name)); + Lisp_Object name = *name_ptr; + if (! NILP (name)) + unlink (SSDATA (name)); } static void @@ -206,7 +181,7 @@ call_process_kill (void *ptr) synch_process_pid = 0; } else if (STRINGP (synch_process_tempfile)) - delete_temp_file (synch_process_tempfile); + delete_temp_file_ptr (&synch_process_tempfile); } /* Clean up when exiting Fcall_process: restore the buffer, and @@ -270,7 +245,7 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) * Lisp_Object infile, encoded_infile; int filefd; struct gcpro gcpro1; - ptrdiff_t count = SPECPDL_INDEX (); + dynwind_begin (); if (nargs >= 2 && ! NILP (args[1])) { @@ -286,9 +261,11 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) * filefd = emacs_open (SSDATA (encoded_infile), O_RDONLY, 0); if (filefd < 0) report_file_error ("Opening process input file", infile); - record_unwind_protect_int (close_file_unwind, filefd); + record_unwind_protect_ptr (close_file_ptr_unwind, &filefd); UNGCPRO; - return unbind_to (count, call_process (nargs, args, filefd, -1)); + Lisp_Object tem0 = call_process (nargs, args, &filefd, NULL); + dynwind_end (); + return tem0; } /* Like Fcall_process (NARGS, ARGS), except use FILEFD as the input file. @@ -300,8 +277,7 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) * At entry, the specpdl stack top entry must be close_file_unwind (FILEFD). */ static Lisp_Object -call_process (ptrdiff_t nargs, Lisp_Object *args, int filefd, - ptrdiff_t tempfile_index) +call_process (ptrdiff_t nargs, Lisp_Object *args, int *filefd, Lisp_Object *tempfile_ptr) { Lisp_Object buffer, current_dir, path; bool display_p; @@ -309,7 +285,6 @@ call_process (ptrdiff_t nargs, Lisp_Object *args, int filefd, int callproc_fd[CALLPROC_FDS]; int status; ptrdiff_t i; - ptrdiff_t count = SPECPDL_INDEX (); USE_SAFE_ALLOCA; char **new_argv; @@ -321,6 +296,7 @@ call_process (ptrdiff_t nargs, Lisp_Object *args, int filefd, char *tempfile = NULL; int pid; #else + sigset_t oldset; pid_t pid; #endif int child_errno; @@ -331,6 +307,8 @@ call_process (ptrdiff_t nargs, Lisp_Object *args, int filefd, Lisp_Object coding_systems; bool discard_output; + dynwind_begin (); + if (synch_process_pid) error ("call-process invoked recursively"); @@ -591,12 +569,12 @@ call_process (ptrdiff_t nargs, Lisp_Object *args, int filefd, #ifdef MSDOS /* MW, July 1993 */ /* Note that on MSDOS `child_setup' actually returns the child process exit status, not its PID, so assign it to status below. */ - pid = child_setup (filefd, fd_output, fd_error, new_argv, 0, current_dir); + pid = child_setup (*filefd, fd_output, fd_error, new_argv, 0, current_dir); if (pid < 0) { child_errno = errno; - unbind_to (count, Qnil); + dynwind_end (); synchronize_system_messages_locale (); return code_convert_string_norecord (build_string (strerror (child_errno)), @@ -610,8 +588,8 @@ call_process (ptrdiff_t nargs, Lisp_Object *args, int filefd, emacs_close (callproc_fd[i]); callproc_fd[i] = -1; } - emacs_close (filefd); - clear_unwind_protect (count - 1); + emacs_close (*filefd); + *filefd = -1; if (tempfile) { @@ -637,10 +615,10 @@ call_process (ptrdiff_t nargs, Lisp_Object *args, int filefd, #ifndef MSDOS block_input (); - block_child_signal (); + block_child_signal (&oldset); #ifdef WINDOWSNT - pid = child_setup (filefd, fd_output, fd_error, new_argv, 0, current_dir); + pid = child_setup (*filefd, fd_output, fd_error, new_argv, 0, current_dir); #else /* not WINDOWSNT */ /* vfork, and prevent local vars from being clobbered by the vfork. */ @@ -649,11 +627,8 @@ call_process (ptrdiff_t nargs, Lisp_Object *args, int filefd, Lisp_Object volatile coding_systems_volatile = coding_systems; Lisp_Object volatile current_dir_volatile = current_dir; bool volatile display_p_volatile = display_p; - bool volatile sa_must_free_volatile = sa_must_free; int volatile fd_error_volatile = fd_error; - int volatile filefd_volatile = filefd; - ptrdiff_t volatile count_volatile = count; - ptrdiff_t volatile sa_count_volatile = sa_count; + int *volatile filefd_volatile = filefd; char **volatile new_argv_volatile = new_argv; int volatile callproc_fd_volatile[CALLPROC_FDS]; for (i = 0; i < CALLPROC_FDS; i++) @@ -665,11 +640,8 @@ call_process (ptrdiff_t nargs, Lisp_Object *args, int filefd, coding_systems = coding_systems_volatile; current_dir = current_dir_volatile; display_p = display_p_volatile; - sa_must_free = sa_must_free_volatile; fd_error = fd_error_volatile; filefd = filefd_volatile; - count = count_volatile; - sa_count = sa_count_volatile; new_argv = new_argv_volatile; for (i = 0; i < CALLPROC_FDS; i++) @@ -679,7 +651,7 @@ call_process (ptrdiff_t nargs, Lisp_Object *args, int filefd, if (pid == 0) { - unblock_child_signal (); + unblock_child_signal (&oldset); setsid (); @@ -690,7 +662,7 @@ call_process (ptrdiff_t nargs, Lisp_Object *args, int filefd, signal (SIGPROF, SIG_DFL); #endif - child_setup (filefd, fd_output, fd_error, new_argv, 0, current_dir); + child_setup (*filefd, fd_output, fd_error, new_argv, 0, current_dir); } #endif /* not WINDOWSNT */ @@ -703,19 +675,20 @@ call_process (ptrdiff_t nargs, Lisp_Object *args, int filefd, if (INTEGERP (buffer)) { - if (tempfile_index < 0) - record_deleted_pid (pid, Qnil); - else - { - eassert (1 < nargs); - record_deleted_pid (pid, args[1]); - clear_unwind_protect (tempfile_index); - } + if (tempfile_ptr) + { + record_deleted_pid (pid, *tempfile_ptr); + *tempfile_ptr = Qnil; + } + else + { + record_deleted_pid (pid, Qnil); + } synch_process_pid = 0; } } - unblock_child_signal (); + unblock_child_signal (&oldset); unblock_input (); if (pid < 0) @@ -729,13 +702,16 @@ call_process (ptrdiff_t nargs, Lisp_Object *args, int filefd, emacs_close (callproc_fd[i]); callproc_fd[i] = -1; } - emacs_close (filefd); - clear_unwind_protect (count - 1); + emacs_close (*filefd); + *filefd = -1; #endif /* not MSDOS */ if (INTEGERP (buffer)) - return unbind_to (count, Qnil); + { + dynwind_end (); + return Qnil; + } if (BUFFERP (buffer)) Fset_buffer (buffer); @@ -834,8 +810,8 @@ call_process (ptrdiff_t nargs, Lisp_Object *args, int filefd, else { /* We have to decode the input. */ Lisp_Object curbuf; - ptrdiff_t count1 = SPECPDL_INDEX (); + dynwind_begin (); XSETBUFFER (curbuf, current_buffer); /* FIXME: Call signal_after_change! */ prepare_to_modify_buffer (PT, PT, NULL); @@ -847,7 +823,7 @@ call_process (ptrdiff_t nargs, Lisp_Object *args, int filefd, specbind (Qinhibit_modification_hooks, Qt); decode_coding_c_string (&process_coding, (unsigned char *) buf, nread, curbuf); - unbind_to (count1, Qnil); + dynwind_end (); if (display_on_the_fly && CODING_REQUIRE_DETECTION (&saved_coding) && ! CODING_REQUIRE_DETECTION (&process_coding)) @@ -922,7 +898,7 @@ call_process (ptrdiff_t nargs, Lisp_Object *args, int filefd, synch_process_pid = 0; SAFE_FREE (); - unbind_to (count, Qnil); + dynwind_end (); if (WIFSIGNALED (status)) { @@ -949,9 +925,9 @@ call_process (ptrdiff_t nargs, Lisp_Object *args, int filefd, Unwind-protect the file, so that the file descriptor will be closed and the file removed when the caller unwinds the specpdl stack. */ -static int +static void create_temp_file (ptrdiff_t nargs, Lisp_Object *args, - Lisp_Object *filename_string_ptr) + Lisp_Object *filename_string_ptr, int *fdp) { int fd; struct gcpro gcpro1; @@ -1001,14 +977,14 @@ create_temp_file (ptrdiff_t nargs, Lisp_Object *args, GCPRO1 (filename_string); tempfile = SSDATA (filename_string); - count = SPECPDL_INDEX (); - record_unwind_protect_nothing (); fd = mkostemp (tempfile, O_CLOEXEC); if (fd < 0) report_file_error ("Failed to open temporary file using pattern", pattern); - set_unwind_protect (count, delete_temp_file, filename_string); - record_unwind_protect_int (close_file_unwind, fd); + *fdp = fd; + *filename_string_ptr = filename_string; + record_unwind_protect (delete_temp_file_ptr, filename_string_ptr); + record_unwind_protect_ptr (close_file_ptr_unwind, fdp); } start = args[0]; @@ -1033,7 +1009,7 @@ create_temp_file (ptrdiff_t nargs, Lisp_Object *args, val = complement_process_encoding_system (val); { - ptrdiff_t count1 = SPECPDL_INDEX (); + dynwind_begin (); specbind (intern ("coding-system-for-write"), val); /* POSIX lets mk[s]temp use "."; don't invoke jka-compr if we @@ -1041,7 +1017,7 @@ create_temp_file (ptrdiff_t nargs, Lisp_Object *args, specbind (intern ("file-name-handler-alist"), Qnil); write_region (start, end, filename_string, Qnil, Qlambda, Qnil, Qnil, fd); - unbind_to (count1, Qnil); + dynwind_end (); } if (lseek (fd, 0, SEEK_SET) < 0) @@ -1050,9 +1026,7 @@ create_temp_file (ptrdiff_t nargs, Lisp_Object *args, /* Note that Fcall_process takes care of binding coding-system-for-read. */ - *filename_string_ptr = filename_string; UNGCPRO; - return fd; } DEFUN ("call-process-region", Fcall_process_region, Scall_process_region, @@ -1084,7 +1058,7 @@ usage: (call-process-region START END PROGRAM &optional DELETE BUFFER DISPLAY &r { struct gcpro gcpro1; Lisp_Object infile, val; - ptrdiff_t count = SPECPDL_INDEX (); + dynwind_begin (); Lisp_Object start = args[0]; Lisp_Object end = args[1]; bool empty_input; @@ -1103,14 +1077,14 @@ usage: (call-process-region START END PROGRAM &optional DELETE BUFFER DISPLAY &r } if (!empty_input) - fd = create_temp_file (nargs, args, &infile); + create_temp_file (nargs, args, &infile, &fd); else { infile = Qnil; fd = emacs_open (NULL_DEVICE, O_RDONLY, 0); if (fd < 0) report_file_error ("Opening null device", Qnil); - record_unwind_protect_int (close_file_unwind, fd); + record_unwind_protect_ptr (close_file_ptr_unwind, &fd); } GCPRO1 (infile); @@ -1130,8 +1104,9 @@ usage: (call-process-region START END PROGRAM &optional DELETE BUFFER DISPLAY &r } args[1] = infile; - val = call_process (nargs, args, fd, empty_input ? -1 : count); - RETURN_UNGCPRO (unbind_to (count, val)); + val = call_process (nargs, args, &fd, &infile); + dynwind_end (); + return val; } #ifndef WINDOWSNT @@ -1628,13 +1603,13 @@ init_callproc (void) srcdir = Fexpand_file_name (build_string ("../src/"), lispdir); - tem = Fexpand_file_name (build_string ("GNU"), Vdata_directory); + tem = Fexpand_file_name (build_string ("NEWS"), Vdata_directory); tem1 = Ffile_exists_p (tem); if (!NILP (Fequal (srcdir, Vinvocation_directory)) || NILP (tem1)) { Lisp_Object newdir; newdir = Fexpand_file_name (build_string ("../etc/"), lispdir); - tem = Fexpand_file_name (build_string ("GNU"), newdir); + tem = Fexpand_file_name (build_string ("NEWS"), newdir); tem1 = Ffile_exists_p (tem); if (!NILP (tem1)) Vdata_directory = newdir; @@ -1681,6 +1656,8 @@ set_initial_environment (void) void syms_of_callproc (void) { +#include "callproc.x" + #ifndef DOS_NT Vtemp_file_name_pattern = build_string ("emacsXXXXXX"); #else /* DOS_NT */ @@ -1688,10 +1665,8 @@ syms_of_callproc (void) #endif staticpro (&Vtemp_file_name_pattern); -#ifdef MSDOS synch_process_tempfile = make_number (0); staticpro (&synch_process_tempfile); -#endif DEFVAR_LISP ("shell-file-name", Vshell_file_name, doc: /* File name to load inferior shells from. @@ -1768,8 +1743,4 @@ use. See `setenv' and `getenv'. */); Vprocess_environment = Qnil; - - defsubr (&Scall_process); - defsubr (&Sgetenv_internal); - defsubr (&Scall_process_region); }