/* Synchronous subprocess invocation for GNU Emacs.
- Copyright (C) 1985-1988, 1993-1995, 1999-2011
+ Copyright (C) 1985-1988, 1993-1995, 1999-2012
Free Software Foundation, Inc.
This file is part of GNU Emacs.
#include <sys/file.h>
#include <fcntl.h>
+#include "lisp.h"
+
#ifdef WINDOWSNT
#define NOMINMAX
#include <windows.h>
#include <sys/param.h>
#endif /* MSDOS */
-#include "lisp.h"
#include "commands.h"
#include "buffer.h"
#include "character.h"
Lisp_Object fdpid = Fcdr (arg);
#if defined (MSDOS)
Lisp_Object file;
+ int fd;
#else
int pid;
#endif
#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));
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; and `(:file FILE)', where
- FILE is a file name string, means that it should be written to that file.
+ 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.
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;
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;
/* 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)
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);
(nargs > 4 ? nargs - 2 : 2) * sizeof *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);
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);
- /* If we're redirecting STDOUT to a file, this is already opened. */
+ /* If we're redirecting STDOUT to a file, that file is already open
+ on fd_output. */
if (fd_output < 0)
{
+ 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);
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,
sigemptyset (&blocked);
sigaddset (&blocked, SIGPIPE);
sigaction (SIGPIPE, 0, &sigpipe_action);
- sigprocmask (SIG_BLOCK, &blocked, &procmask);
+ pthread_sigmask (SIG_BLOCK, &blocked, &procmask);
#endif
BLOCK_INPUT;
/* 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;
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;
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,
#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 */
/* 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 (),
/* 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
{
{
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
&& !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;
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.
+ 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.
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;
/* 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;
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);
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
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);
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
#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))
{
}
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,
(Lisp_Object variable, Lisp_Object env)
{
char *value;
- int valuelen;
+ ptrdiff_t valuelen;
CHECK_STRING (variable);
if (CONSP (env))
egetenv (const char *var)
{
char *value;
- int valuelen;
+ ptrdiff_t valuelen;
if (getenv_internal (var, strlen (var), &value, &valuelen, Qnil))
return value;
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