X-Git-Url: https://git.hcoop.net/bpt/emacs.git/blobdiff_plain/953e106ac84587e765244995687b088969b5f6e1..2bfa3d3e1fb347ba76bddf77f3e288049635821d:/src/callproc.c diff --git a/src/callproc.c b/src/callproc.c index 38cde01718..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,7 +98,7 @@ 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 *); /* Return the current buffer's working directory, or the home directory if it's unreachable, as a string suitable for a system call. @@ -133,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. @@ -161,9 +156,11 @@ record_kill_process (struct Lisp_Process *p, Lisp_Object tempfile) /* 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 @@ -184,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 @@ -248,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])) { @@ -264,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. @@ -278,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; @@ -287,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; @@ -310,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"); @@ -570,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)), @@ -589,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) { @@ -619,7 +618,7 @@ call_process (ptrdiff_t nargs, Lisp_Object *args, int filefd, 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. */ @@ -628,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++) @@ -644,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++) @@ -669,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 */ @@ -682,14 +675,15 @@ 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; } } @@ -708,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); @@ -805,15 +802,18 @@ call_process (ptrdiff_t nargs, Lisp_Object *args, int filefd, /* Now NREAD is the total amount of data in the buffer. */ immediate_quit = 0; - if (NILP (BVAR (current_buffer, enable_multibyte_characters)) - && ! CODING_MAY_REQUIRE_DECODING (&process_coding)) + if (!nread) + ; + else if (NILP (BVAR (current_buffer, enable_multibyte_characters)) + && ! CODING_MAY_REQUIRE_DECODING (&process_coding)) insert_1_both (buf, nread, nread, 0, 1, 0); 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); /* We cannot allow after-change-functions be run during decoding, because that might modify the @@ -823,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)) @@ -898,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)) { @@ -925,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; @@ -977,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]; @@ -1009,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 @@ -1017,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) @@ -1026,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, @@ -1060,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; @@ -1079,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); @@ -1106,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 @@ -1657,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 */ @@ -1664,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. @@ -1744,8 +1743,4 @@ use. See `setenv' and `getenv'. */); Vprocess_environment = Qnil; - - defsubr (&Scall_process); - defsubr (&Sgetenv_internal); - defsubr (&Scall_process_region); }