X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/4170f62f39edf1ff1e99aec9bfbfe7bbf10e7fc9..6bee44d6400c47201de3abfef17b63ce9acfb8c9:/src/callproc.c diff --git a/src/callproc.c b/src/callproc.c index 3726eb3cc7..b5b8cadeb6 100644 --- a/src/callproc.c +++ b/src/callproc.c @@ -1,6 +1,6 @@ /* Synchronous subprocess invocation for GNU Emacs. - Copyright (C) 1985-1988, 1993-1995, 1999-2011 - Free Software Foundation, Inc. + Copyright (C) 1985-1988, 1993-1995, 1999-2012 + Free Software Foundation, Inc. This file is part of GNU Emacs. @@ -29,6 +29,8 @@ along with GNU Emacs. If not, see . */ #include #include +#include "lisp.h" + #ifdef WINDOWSNT #define NOMINMAX #include @@ -41,7 +43,6 @@ along with GNU Emacs. If not, see . */ #include #endif /* MSDOS */ -#include "lisp.h" #include "commands.h" #include "buffer.h" #include "character.h" @@ -113,6 +114,7 @@ call_process_cleanup (Lisp_Object arg) Lisp_Object fdpid = Fcdr (arg); #if defined (MSDOS) Lisp_Object file; + int fd; #else int pid; #endif @@ -121,9 +123,13 @@ call_process_cleanup (Lisp_Object arg) #if defined (MSDOS) /* for MSDOS fdpid is really (fd . tempfile) */ + fd = XFASTINT (Fcar (fdpid)); file = Fcdr (fdpid); - emacs_close (XFASTINT (Fcar (fdpid))); - if (strcmp (SDATA (file), NULL_DEVICE) != 0) + /* FD is -1 and FILE is "" when we didn't actually create a + temporary file in call-process. */ + if (fd >= 0) + emacs_close (fd); + if (!(strcmp (SDATA (file), NULL_DEVICE) == 0 || SREF (file, 0) == '\0')) unlink (SDATA (file)); #else /* not MSDOS */ pid = XFASTINT (Fcdr (fdpid)); @@ -156,8 +162,10 @@ DEFUN ("call-process", Fcall_process, Scall_process, 1, MANY, 0, doc: /* Call PROGRAM synchronously in separate process. The remaining arguments are optional. The program's input comes from file INFILE (nil means `/dev/null'). -Insert output in BUFFER before point; t means current buffer; - nil for BUFFER means discard it; 0 means discard and don't wait. +Insert output in BUFFER before point; t means current buffer; nil for BUFFER + means discard it; 0 means discard and don't wait; and `(:file FILE)', where + FILE is a file name string, means that it should be written to that file + \(if the file already exists it is overwritten). BUFFER can also have the form (REAL-BUFFER STDERR-FILE); in that case, REAL-BUFFER says what to do with standard output, as above, while STDERR-FILE says what to do with standard error in the child. @@ -177,7 +185,7 @@ and returns a numeric exit status or a signal description string. If you quit, the process is killed with SIGINT, or SIGKILL if you quit again. usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) - (size_t nargs, register Lisp_Object *args) + (ptrdiff_t nargs, Lisp_Object *args) { Lisp_Object infile, buffer, current_dir, path; volatile int display_p_volatile; @@ -191,19 +199,21 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) int count = SPECPDL_INDEX (); volatile USE_SAFE_ALLOCA; - const unsigned char **volatile new_argv_volatile; register const unsigned char **new_argv; /* File to use for stderr in the child. t means use same as standard output. */ Lisp_Object error_file; + Lisp_Object output_file = Qnil; #ifdef MSDOS /* Demacs 1.1.1 91/10/16 HIRANO Satoshi */ - char *outf, *tempfile; + char *outf, *tempfile = NULL; int outfilefd; #endif + int fd_output = -1; struct coding_system process_coding; /* coding-system of process output */ struct coding_system argument_coding; /* coding-system of arguments */ /* Set to the return value of Ffind_operation_coding_system. */ Lisp_Object coding_systems; + int output_to_buffer = 1; /* Qt denotes that Ffind_operation_coding_system is not yet called. */ coding_systems = Qt; @@ -222,7 +232,7 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) /* Decide the coding-system for giving arguments. */ { Lisp_Object val, *args2; - size_t i; + ptrdiff_t i; /* If arguments are supplied, we may have to encode them. */ if (nargs >= 5) @@ -243,7 +253,7 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) val = Qraw_text; else { - SAFE_ALLOCA (args2, Lisp_Object *, (nargs + 1) * sizeof *args2); + SAFE_NALLOCA (args2, 1, nargs + 1); args2[0] = Qcall_process; for (i = 0; i < nargs; i++) args2[i + 1] = args[i]; coding_systems = Ffind_operation_coding_system (nargs + 1, args2); @@ -273,9 +283,12 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) { buffer = args[2]; - /* If BUFFER is a list, its meaning is - (BUFFER-FOR-STDOUT FILE-FOR-STDERR). */ - if (CONSP (buffer)) + /* If BUFFER is a list, its meaning is (BUFFER-FOR-STDOUT + FILE-FOR-STDERR), unless the first element is :file, in which case see + the next paragraph. */ + if (CONSP (buffer) + && (! SYMBOLP (XCAR (buffer)) + || strcmp (SSDATA (SYMBOL_NAME (XCAR (buffer))), ":file"))) { if (CONSP (XCDR (buffer))) { @@ -291,6 +304,17 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) buffer = XCAR (buffer); } + /* If the buffer is (still) a list, it might be a (:file "file") spec. */ + if (CONSP (buffer) + && SYMBOLP (XCAR (buffer)) + && ! strcmp (SSDATA (SYMBOL_NAME (XCAR (buffer))), ":file")) + { + output_file = Fexpand_file_name (XCAR (XCDR (buffer)), + BVAR (current_buffer, directory)); + CHECK_STRING (output_file); + buffer = Qnil; + } + if (!(EQ (buffer, Qnil) || EQ (buffer, Qt) || INTEGERP (buffer))) @@ -318,11 +342,11 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) protected by the caller, so all we really have to worry about is buffer. */ { - struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; + struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5; current_dir = BVAR (current_buffer, directory); - GCPRO4 (infile, buffer, current_dir, error_file); + GCPRO5 (infile, buffer, current_dir, error_file, output_file); current_dir = Funhandled_file_name_directory (current_dir); if (NILP (current_dir)) @@ -342,6 +366,8 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) current_dir = ENCODE_FILE (current_dir); if (STRINGP (error_file) && STRING_MULTIBYTE (error_file)) error_file = ENCODE_FILE (error_file); + if (STRINGP (output_file) && STRING_MULTIBYTE (output_file)) + output_file = ENCODE_FILE (output_file); UNGCPRO; } @@ -353,6 +379,26 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) infile = DECODE_FILE (infile); report_file_error ("Opening process input file", Fcons (infile, Qnil)); } + + if (STRINGP (output_file)) + { +#ifdef DOS_NT + fd_output = emacs_open (SSDATA (output_file), + O_WRONLY | O_TRUNC | O_CREAT | O_TEXT, + S_IREAD | S_IWRITE); +#else /* not DOS_NT */ + fd_output = creat (SSDATA (output_file), 0666); +#endif /* not DOS_NT */ + if (fd_output < 0) + { + output_file = DECODE_FILE (output_file); + report_file_error ("Opening process output file", + Fcons (output_file, Qnil)); + } + if (STRINGP (error_file) || NILP (error_file)) + output_to_buffer = 0; + } + /* Search for program; barf if not found. */ { struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; @@ -375,10 +421,9 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) SAFE_ALLOCA (new_argv, const unsigned char **, (nargs > 4 ? nargs - 2 : 2) * sizeof *new_argv); - new_argv_volatile = new_argv; if (nargs > 4) { - register size_t i; + ptrdiff_t i; struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5; GCPRO5 (infile, buffer, current_dir, path, error_file); @@ -400,26 +445,32 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) new_argv[0] = SDATA (path); #ifdef MSDOS /* MW, July 1993 */ - if ((outf = egetenv ("TMPDIR"))) - strcpy (tempfile = alloca (strlen (outf) + 20), outf); - else - { - tempfile = alloca (20); - *tempfile = '\0'; - } - 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) + + /* If we're redirecting STDOUT to a file, that file is already open + on fd_output. */ + if (fd_output < 0) { - emacs_close (filefd); - report_file_error ("Opening process output file", - Fcons (build_string (tempfile), Qnil)); + if ((outf = egetenv ("TMPDIR"))) + strcpy (tempfile = alloca (strlen (outf) + 20), outf); + else + { + tempfile = alloca (20); + *tempfile = '\0'; + } + 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) { + emacs_close (filefd); + report_file_error ("Opening process output file", + Fcons (build_string (tempfile), Qnil)); + } } + else + outfilefd = fd_output; fd[0] = filefd; fd[1] = outfilefd; #endif /* MSDOS */ @@ -450,6 +501,8 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) struct sigaction sigpipe_action; #endif + if (fd_output >= 0) + fd1 = fd_output; #if 0 /* Some systems don't have sigblock. */ mask = sigblock (sigmask (SIGCHLD)); #endif @@ -515,15 +568,21 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) if (fd_error != outfilefd) emacs_close (fd_error); fd1 = -1; /* No harm in closing that one! */ - /* Since CRLF is converted to LF within `decode_coding', we can - always open a file with binary mode. */ - fd[0] = emacs_open (tempfile, O_RDONLY | O_BINARY, 0); - if (fd[0] < 0) + if (tempfile) { - unlink (tempfile); - emacs_close (filefd); - report_file_error ("Cannot re-open temporary file", Qnil); + /* Since CRLF is converted to LF within `decode_coding', we + can always open a file with binary mode. */ + fd[0] = emacs_open (tempfile, O_RDONLY | O_BINARY, 0); + if (fd[0] < 0) + { + unlink (tempfile); + emacs_close (filefd); + report_file_error ("Cannot re-open temporary file", + Fcons (build_string (tempfile), Qnil)); + } } + else + fd[0] = -1; /* We are not going to read from tempfile. */ #else /* not MSDOS */ #ifdef WINDOWSNT pid = child_setup (filefd, fd1, fd_error, (char **) new_argv, @@ -538,33 +597,52 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) sigemptyset (&blocked); sigaddset (&blocked, SIGPIPE); sigaction (SIGPIPE, 0, &sigpipe_action); - sigprocmask (SIG_BLOCK, &blocked, &procmask); + pthread_sigmask (SIG_BLOCK, &blocked, &procmask); #endif BLOCK_INPUT; - pid = vfork (); - - new_argv = new_argv_volatile; + /* vfork, and prevent local vars from being clobbered by the vfork. */ + { + Lisp_Object volatile buffer_volatile = buffer; + Lisp_Object volatile coding_systems_volatile = coding_systems; + Lisp_Object volatile current_dir_volatile = current_dir; + int volatile fd1_volatile = fd1; + int volatile fd_error_volatile = fd_error; + int volatile fd_output_volatile = fd_output; + int volatile output_to_buffer_volatile = output_to_buffer; + unsigned char const **volatile new_argv_volatile = new_argv; + + pid = vfork (); + + buffer = buffer_volatile; + coding_systems = coding_systems_volatile; + current_dir = current_dir_volatile; + fd1 = fd1_volatile; + fd_error = fd_error_volatile; + fd_output = fd_output_volatile; + output_to_buffer = output_to_buffer_volatile; + new_argv = new_argv_volatile; + } if (pid == 0) { if (fd[0] >= 0) emacs_close (fd[0]); #ifdef HAVE_SETSID - setsid (); + setsid (); #endif #if defined (USG) - setpgrp (); + setpgrp (); #else - setpgrp (pid, pid); + setpgrp (pid, pid); #endif /* USG */ /* GConf causes us to ignore SIGPIPE, make sure it is restored in the child. */ //signal (SIGPIPE, SIG_DFL); #ifdef HAVE_WORKING_VFORK - sigprocmask (SIG_SETMASK, &procmask, 0); + pthread_sigmask (SIG_SETMASK, &procmask, 0); #endif child_setup (filefd, fd1, fd_error, (char **) new_argv, @@ -576,7 +654,7 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) #ifdef HAVE_WORKING_VFORK /* Restore the signal state. */ sigaction (SIGPIPE, &sigpipe_action, 0); - sigprocmask (SIG_SETMASK, &procmask, 0); + pthread_sigmask (SIG_SETMASK, &procmask, 0); #endif #endif /* not WINDOWSNT */ @@ -591,6 +669,8 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) /* Close most of our fd's, but not fd[0] since we will use that to read input from. */ emacs_close (filefd); + if (fd_output >= 0) + emacs_close (fd_output); if (fd1 >= 0 && fd1 != fd_error) emacs_close (fd1); } @@ -612,12 +692,12 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) /* Enable sending signal if user quits below. */ call_process_exited = 0; -#if defined(MSDOS) +#if defined (MSDOS) /* MSDOS needs different cleanup information. */ record_unwind_protect (call_process_cleanup, Fcons (Fcurrent_buffer (), Fcons (make_number (fd[0]), - build_string (tempfile)))); + build_string (tempfile ? tempfile : "")))); #else record_unwind_protect (call_process_cleanup, Fcons (Fcurrent_buffer (), @@ -633,6 +713,7 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) /* If BUFFER is nil, we must read process output once and then discard it, so setup coding system but with nil. */ setup_coding_system (Qnil, &process_coding); + process_coding.dst_multibyte = 0; } else { @@ -645,9 +726,9 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) { if (EQ (coding_systems, Qt)) { - size_t i; + ptrdiff_t i; - SAFE_ALLOCA (args2, Lisp_Object *, (nargs + 1) * sizeof *args2); + SAFE_NALLOCA (args2, 1, nargs + 1); args2[0] = Qcall_process; for (i = 0; i < nargs; i++) args2[i + 1] = args[i]; coding_systems @@ -668,141 +749,148 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) && !NILP (val)) val = raw_text_coding_system (val); setup_coding_system (val, &process_coding); + process_coding.dst_multibyte + = ! NILP (BVAR (current_buffer, enable_multibyte_characters)); } + process_coding.src_multibyte = 0; immediate_quit = 1; QUIT; - { - register EMACS_INT nread; - int first = 1; - EMACS_INT total_read = 0; - int carryover = 0; - int display_p = display_p_volatile; - int display_on_the_fly = display_p; - struct coding_system saved_coding; - - saved_coding = process_coding; - while (1) - { - /* Repeatedly read until we've filled as much as possible - of the buffer size we have. But don't read - less than 1024--save that for the next bufferful. */ - nread = carryover; - while (nread < bufsize - 1024) - { - int this_read = emacs_read (fd[0], buf + nread, - bufsize - nread); + if (output_to_buffer) + { + register EMACS_INT nread; + int first = 1; + EMACS_INT total_read = 0; + int carryover = 0; + int display_p = display_p_volatile; + int display_on_the_fly = display_p; + struct coding_system saved_coding; + + saved_coding = process_coding; + while (1) + { + /* Repeatedly read until we've filled as much as possible + of the buffer size we have. But don't read + less than 1024--save that for the next bufferful. */ + nread = carryover; + while (nread < bufsize - 1024) + { + int this_read = emacs_read (fd[0], buf + nread, + bufsize - nread); - if (this_read < 0) - goto give_up; + if (this_read < 0) + goto give_up; - if (this_read == 0) - { - process_coding.mode |= CODING_MODE_LAST_BLOCK; - break; - } + if (this_read == 0) + { + process_coding.mode |= CODING_MODE_LAST_BLOCK; + break; + } - nread += this_read; - total_read += this_read; + nread += this_read; + total_read += this_read; - if (display_on_the_fly) - break; - } + if (display_on_the_fly) + break; + } - /* Now NREAD is the total amount of data in the buffer. */ - immediate_quit = 0; + /* Now NREAD is the total amount of data in the buffer. */ + immediate_quit = 0; - if (!NILP (buffer)) - { - 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; - int count1 = SPECPDL_INDEX (); - - XSETBUFFER (curbuf, current_buffer); - /* We cannot allow after-change-functions be run - during decoding, because that might modify the - buffer, while we rely on process_coding.produced to - faithfully reflect inserted text until we - TEMP_SET_PT_BOTH below. */ - specbind (Qinhibit_modification_hooks, Qt); - decode_coding_c_string (&process_coding, (unsigned char *) buf, - nread, curbuf); - unbind_to (count1, Qnil); - if (display_on_the_fly - && CODING_REQUIRE_DETECTION (&saved_coding) - && ! CODING_REQUIRE_DETECTION (&process_coding)) - { - /* We have detected some coding system. But, - there's a possibility that the detection was - done by insufficient data. So, we give up - displaying on the fly. */ - if (process_coding.produced > 0) - del_range_2 (process_coding.dst_pos, - process_coding.dst_pos_byte, - process_coding.dst_pos - + process_coding.produced_char, - process_coding.dst_pos_byte - + process_coding.produced, 0); - display_on_the_fly = 0; - process_coding = saved_coding; - carryover = nread; - /* This is to make the above condition always - fails in the future. */ - saved_coding.common_flags - &= ~CODING_REQUIRE_DETECTION_MASK; - continue; - } - - TEMP_SET_PT_BOTH (PT + process_coding.produced_char, - PT_BYTE + process_coding.produced); - carryover = process_coding.carryover_bytes; - if (carryover > 0) - memcpy (buf, process_coding.carryover, - process_coding.carryover_bytes); - } - } + if (!NILP (buffer)) + { + 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; + int count1 = SPECPDL_INDEX (); + + XSETBUFFER (curbuf, current_buffer); + /* We cannot allow after-change-functions be run + during decoding, because that might modify the + buffer, while we rely on process_coding.produced to + faithfully reflect inserted text until we + TEMP_SET_PT_BOTH below. */ + specbind (Qinhibit_modification_hooks, Qt); + decode_coding_c_string (&process_coding, + (unsigned char *) buf, nread, curbuf); + unbind_to (count1, Qnil); + if (display_on_the_fly + && CODING_REQUIRE_DETECTION (&saved_coding) + && ! CODING_REQUIRE_DETECTION (&process_coding)) + { + /* We have detected some coding system. But, + there's a possibility that the detection was + done by insufficient data. So, we give up + displaying on the fly. */ + if (process_coding.produced > 0) + del_range_2 (process_coding.dst_pos, + process_coding.dst_pos_byte, + process_coding.dst_pos + + process_coding.produced_char, + process_coding.dst_pos_byte + + process_coding.produced, 0); + display_on_the_fly = 0; + process_coding = saved_coding; + carryover = nread; + /* This is to make the above condition always + fails in the future. */ + saved_coding.common_flags + &= ~CODING_REQUIRE_DETECTION_MASK; + continue; + } + + TEMP_SET_PT_BOTH (PT + process_coding.produced_char, + PT_BYTE + process_coding.produced); + carryover = process_coding.carryover_bytes; + if (carryover > 0) + memcpy (buf, process_coding.carryover, + process_coding.carryover_bytes); + } + } - if (process_coding.mode & CODING_MODE_LAST_BLOCK) - break; + if (process_coding.mode & CODING_MODE_LAST_BLOCK) + break; - /* Make the buffer bigger as we continue to read more data, - but not past CALLPROC_BUFFER_SIZE_MAX. */ - if (bufsize < CALLPROC_BUFFER_SIZE_MAX && total_read > 32 * bufsize) - if ((bufsize *= 2) > CALLPROC_BUFFER_SIZE_MAX) - bufsize = CALLPROC_BUFFER_SIZE_MAX; + /* Make the buffer bigger as we continue to read more data, + but not past CALLPROC_BUFFER_SIZE_MAX. */ + if (bufsize < CALLPROC_BUFFER_SIZE_MAX && total_read > 32 * bufsize) + if ((bufsize *= 2) > CALLPROC_BUFFER_SIZE_MAX) + bufsize = CALLPROC_BUFFER_SIZE_MAX; - if (display_p) - { - if (first) - prepare_menu_bars (); - first = 0; - redisplay_preserve_echo_area (1); - /* This variable might have been set to 0 for code - detection. In that case, we set it back to 1 because - we should have already detected a coding system. */ - display_on_the_fly = 1; - } - immediate_quit = 1; - QUIT; - } - give_up: ; - - Vlast_coding_system_used = CODING_ID_NAME (process_coding.id); - /* If the caller required, let the buffer inherit the - coding-system used to decode the process output. */ - if (inherit_process_coding_system) - call1 (intern ("after-insert-file-set-buffer-file-coding-system"), - make_number (total_read)); - } + if (display_p) + { + if (first) + prepare_menu_bars (); + first = 0; + redisplay_preserve_echo_area (1); + /* This variable might have been set to 0 for code + detection. In that case, we set it back to 1 because + we should have already detected a coding system. */ + display_on_the_fly = 1; + } + immediate_quit = 1; + QUIT; + } + give_up: ; + + Vlast_coding_system_used = CODING_ID_NAME (process_coding.id); + /* If the caller required, let the buffer inherit the + coding-system used to decode the process output. */ + if (inherit_process_coding_system) + call1 (intern ("after-insert-file-set-buffer-file-coding-system"), + make_number (total_read)); + } #ifndef MSDOS /* Wait for it to terminate, unless it already has. */ - wait_for_termination (pid); + if (output_to_buffer) + wait_for_termination (pid); + else + interruptible_wait_for_termination (pid); #endif immediate_quit = 0; @@ -822,7 +910,7 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) signame = strsignal (synch_process_termsig); if (signame == 0) - signame = "unknown"; + signame = "unknown"; synch_process_death = signame; } @@ -850,8 +938,10 @@ DEFUN ("call-process-region", Fcall_process_region, Scall_process_region, The remaining arguments are optional. Delete the text if fourth arg DELETE is non-nil. -Insert output in BUFFER before point; t means current buffer; - nil for BUFFER means discard it; 0 means discard and don't wait. +Insert output in BUFFER before point; t means current buffer; nil for + BUFFER means discard it; 0 means discard and don't wait; and `(:file + FILE)', where FILE is a file name string, means that it should be + written to that file (if the file already exists it is overwritten). BUFFER can also have the form (REAL-BUFFER STDERR-FILE); in that case, REAL-BUFFER says what to do with standard output, as above, while STDERR-FILE says what to do with standard error in the child. @@ -867,7 +957,7 @@ and returns a numeric exit status or a signal description string. If you quit, the process is killed with SIGINT, or SIGKILL if you quit again. usage: (call-process-region START END PROGRAM &optional DELETE BUFFER DISPLAY &rest ARGS) */) - (size_t nargs, register Lisp_Object *args) + (ptrdiff_t nargs, Lisp_Object *args) { struct gcpro gcpro1; Lisp_Object filename_string; @@ -876,7 +966,7 @@ usage: (call-process-region START END PROGRAM &optional DELETE BUFFER DISPLAY &r /* Qt denotes we have not yet called Ffind_operation_coding_system. */ Lisp_Object coding_systems; Lisp_Object val, *args2; - size_t i; + ptrdiff_t i; char *tempfile; Lisp_Object tmpdir, pattern; @@ -939,7 +1029,7 @@ usage: (call-process-region START END PROGRAM &optional DELETE BUFFER DISPLAY &r else { USE_SAFE_ALLOCA; - SAFE_ALLOCA (args2, Lisp_Object *, (nargs + 1) * sizeof *args2); + SAFE_NALLOCA (args2, 1, nargs + 1); args2[0] = Qcall_process_region; for (i = 0; i < nargs; i++) args2[i + 1] = args[i]; coding_systems = Ffind_operation_coding_system (nargs + 1, args2); @@ -1003,18 +1093,18 @@ add_env (char **env, char **new_env, char *string) { char *p = *ep, *q = string; while (ok) - { - if (*q != *p) - break; - if (*q == 0) - /* The string is a lone variable name; keep it for now, we - will remove it later. It is a placeholder for a - variable that is not to be included in the environment. */ - break; - if (*q == '=') - ok = 0; - p++, q++; - } + { + if (*q != *p) + break; + if (*q == 0) + /* The string is a lone variable name; keep it for now, we + will remove it later. It is a placeholder for a + variable that is not to be included in the environment. */ + break; + if (*q == '=') + ok = 0; + p++, q++; + } } if (ok) *new_env++ = string; @@ -1068,7 +1158,7 @@ child_setup (int in, int out, int err, register char **new_argv, int set_pgrp, L cleaned up in the usual way. */ { register char *temp; - register int i; + size_t i; /* size_t, because ptrdiff_t might overflow here! */ i = SBYTES (current_dir); #ifdef MSDOS @@ -1118,8 +1208,8 @@ child_setup (int in, int out, int err, register char **new_argv, int set_pgrp, L new_length = 0; for (tem = Vprocess_environment; - CONSP (tem) && STRINGP (XCAR (tem)); - tem = XCDR (tem)) + CONSP (tem) && STRINGP (XCAR (tem)); + tem = XCDR (tem)) { if (strncmp (SSDATA (XCAR (tem)), "DISPLAY", 7) == 0 && (SDATA (XCAR (tem)) [7] == '\0' @@ -1153,8 +1243,7 @@ child_setup (int in, int out, int err, register char **new_argv, int set_pgrp, L if (STRINGP (display)) { - int vlen = strlen ("DISPLAY=") + strlen (SSDATA (display)) + 1; - char *vdata = (char *) alloca (vlen); + char *vdata = (char *) alloca (sizeof "DISPLAY=" + SBYTES (display)); strcpy (vdata, "DISPLAY="); strcat (vdata, SSDATA (display)); new_env = add_env (env, new_env, vdata); @@ -1172,11 +1261,11 @@ child_setup (int in, int out, int err, register char **new_argv, int set_pgrp, L p = q = env; while (*p != 0) { - while (*q != 0 && strchr (*q, '=') == NULL) - q++; - *p = *q++; - if (*p != 0) - p++; + while (*q != 0 && strchr (*q, '=') == NULL) + q++; + *p = *q++; + if (*p != 0) + p++; } } @@ -1231,7 +1320,7 @@ child_setup (int in, int out, int err, register char **new_argv, int set_pgrp, L if (err != in && err != out) emacs_close (err); -#if defined(USG) +#if defined (USG) #ifndef SETPGRP_RELEASES_CTTY setpgrp (); /* No arguments but equivalent in this case */ #endif @@ -1301,8 +1390,8 @@ relocate_fd (int fd, int minfd) #endif /* not WINDOWSNT */ static int -getenv_internal_1 (const char *var, int varlen, char **value, int *valuelen, - Lisp_Object env) +getenv_internal_1 (const char *var, ptrdiff_t varlen, char **value, + ptrdiff_t *valuelen, Lisp_Object env) { for (; CONSP (env); env = XCDR (env)) { @@ -1336,8 +1425,8 @@ getenv_internal_1 (const char *var, int varlen, char **value, int *valuelen, } static int -getenv_internal (const char *var, int varlen, char **value, int *valuelen, - Lisp_Object frame) +getenv_internal (const char *var, ptrdiff_t varlen, char **value, + ptrdiff_t *valuelen, Lisp_Object frame) { /* Try to find VAR in Vprocess_environment first. */ if (getenv_internal_1 (var, varlen, value, valuelen, @@ -1377,7 +1466,7 @@ If optional parameter ENV is a list, then search this list instead of (Lisp_Object variable, Lisp_Object env) { char *value; - int valuelen; + ptrdiff_t valuelen; CHECK_STRING (variable); if (CONSP (env)) @@ -1401,7 +1490,7 @@ char * egetenv (const char *var) { char *value; - int valuelen; + ptrdiff_t valuelen; if (getenv_internal (var, strlen (var), &value, &valuelen, Qnil)) return value; @@ -1526,20 +1615,13 @@ init_callproc (void) void set_initial_environment (void) { - register char **envp; -#ifdef CANNOT_DUMP - Vprocess_environment = Qnil; -#else - if (initialized) -#endif - { - for (envp = environ; *envp; envp++) - Vprocess_environment = Fcons (build_string (*envp), - Vprocess_environment); - /* Ideally, the `copy' shouldn't be necessary, but it seems it's frequent - to use `delete' and friends on process-environment. */ - Vinitial_environment = Fcopy_sequence (Vprocess_environment); - } + char **envp; + for (envp = environ; *envp; envp++) + Vprocess_environment = Fcons (build_string (*envp), + Vprocess_environment); + /* Ideally, the `copy' shouldn't be necessary, but it seems it's frequent + to use `delete' and friends on process-environment. */ + Vinitial_environment = Fcopy_sequence (Vprocess_environment); } void