X-Git-Url: https://git.hcoop.net/bpt/emacs.git/blobdiff_plain/f23d76bdefbd4c06e14d69e99e50d35ce91c8226..cde4c3f133e7aa85e28383988797e2f9802cf268:/src/callproc.c diff --git a/src/callproc.c b/src/callproc.c index 567fe3a284..d55fe695e7 100644 --- a/src/callproc.c +++ b/src/callproc.c @@ -1,13 +1,14 @@ /* Synchronous subprocess invocation for GNU Emacs. Copyright (C) 1985, 1986, 1987, 1988, 1993, 1994, 1995, 1999, 2000, 2001, - 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. + 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 + Free Software Foundation, Inc. This file is part of GNU Emacs. -GNU Emacs is free software; you can redistribute it and/or modify +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 3, or (at your option) -any later version. +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. GNU Emacs is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -15,9 +16,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License -along with GNU Emacs; see the file COPYING. If not, write to -the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -Boston, MA 02110-1301, USA. */ +along with GNU Emacs. If not, see . */ #include @@ -91,13 +90,9 @@ extern int errno; #include "msdos.h" #endif -#ifdef VMS -extern noshare char **environ; -#else #ifndef USE_CRT_DLL extern char **environ; #endif -#endif #ifdef HAVE_SETPGID #if !defined (USG) || defined (BSD_PGRPS) @@ -109,7 +104,11 @@ extern char **environ; Lisp_Object Vexec_path, Vexec_directory, Vexec_suffixes; Lisp_Object Vdata_directory, Vdoc_directory; Lisp_Object Vconfigure_info_directory, Vshared_game_score_directory; -Lisp_Object Vtemp_file_name_pattern; + +/* Pattern used by call-process-region to make temp files. */ +static Lisp_Object Vtemp_file_name_pattern; + +extern Lisp_Object Vtemporary_file_directory; Lisp_Object Vshell_file_name; @@ -143,8 +142,6 @@ static int call_process_exited; EXFUN (Fgetenv_internal, 2); -#ifndef VMS /* VMS version is in vmsproc.c. */ - static Lisp_Object call_process_kill (fdpid) Lisp_Object fdpid; @@ -159,14 +156,14 @@ Lisp_Object call_process_cleanup (fdpid) Lisp_Object fdpid; { -#if defined (MSDOS) || defined (MAC_OS8) +#if defined (MSDOS) /* for MSDOS fdpid is really (fd . tempfile) */ register Lisp_Object file; file = Fcdr (fdpid); emacs_close (XFASTINT (Fcar (fdpid))); if (strcmp (SDATA (file), NULL_DEVICE) != 0) unlink (SDATA (file)); -#else /* not MSDOS and not MAC_OS8 */ +#else /* not MSDOS */ register int pid = XFASTINT (Fcdr (fdpid)); if (call_process_exited) @@ -233,8 +230,7 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) int bufsize = CALLPROC_BUFFER_SIZE_MIN; int count = SPECPDL_INDEX (); - register const unsigned char **new_argv - = (const unsigned char **) alloca ((max (2, nargs - 2)) * sizeof (char *)); + register const unsigned char **new_argv; struct buffer *old = current_buffer; /* File to use for stderr in the child. t means use same as standard output. */ @@ -242,13 +238,6 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) #ifdef MSDOS /* Demacs 1.1.1 91/10/16 HIRANO Satoshi */ char *outf, *tempfile; int outfilefd; -#endif -#ifdef MAC_OS8 - char *tempfile; - int outfilefd; -#endif -#if 0 - int mask; #endif struct coding_system process_coding; /* coding-system of process output */ struct coding_system argument_coding; /* coding-system of arguments */ @@ -379,9 +368,14 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) GCPRO4 (infile, buffer, current_dir, error_file); - current_dir - = expand_and_dir_to_file (Funhandled_file_name_directory (current_dir), - Qnil); + current_dir = Funhandled_file_name_directory (current_dir); + if (NILP (current_dir)) + /* If the file name handler says that current_dir is unreachable, use + a sensible default. */ + current_dir = build_string ("~/"); + current_dir = expand_and_dir_to_file (current_dir, Qnil); + current_dir = Ffile_name_as_directory (current_dir); + if (NILP (Ffile_accessible_directory_p (current_dir))) report_file_error ("Setting current directory", Fcons (current_buffer->directory, Qnil)); @@ -423,7 +417,8 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) && SREF (path, 1) == ':') path = Fsubstring (path, make_number (2), Qnil); - new_argv[0] = SDATA (path); + new_argv = (const unsigned char **) + alloca (max (2, nargs - 2) * sizeof (char *)); if (nargs > 4) { register int i; @@ -437,13 +432,15 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) if (CODING_REQUIRE_ENCODING (&argument_coding)) /* We must encode this argument. */ args[i] = encode_coding_string (&argument_coding, args[i], 1); - new_argv[i - 3] = SDATA (args[i]); } UNGCPRO; - new_argv[nargs - 3] = 0; + for (i = 4; i < nargs; i++) + new_argv[i - 3] = SDATA (args[i]); + new_argv[i - 3] = 0; } else new_argv[1] = 0; + new_argv[0] = SDATA (path); #ifdef MSDOS /* MW, July 1993 */ if ((outf = egetenv ("TMPDIR"))) @@ -470,43 +467,17 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) fd[1] = outfilefd; #endif /* MSDOS */ -#ifdef MAC_OS8 - /* Since we don't have pipes on the Mac, create a temporary file to - hold the output of the subprocess. */ - tempfile = (char *) alloca (SBYTES (Vtemp_file_name_pattern) + 1); - bcopy (SDATA (Vtemp_file_name_pattern), tempfile, - SBYTES (Vtemp_file_name_pattern) + 1); - - mktemp (tempfile); - - outfilefd = creat (tempfile, S_IREAD | S_IWRITE); - if (outfilefd < 0) - { - close (filefd); - report_file_error ("Opening process output file", - Fcons (build_string (tempfile), Qnil)); - } - fd[0] = filefd; - fd[1] = outfilefd; -#endif /* MAC_OS8 */ - if (INTEGERP (buffer)) fd[1] = emacs_open (NULL_DEVICE, O_WRONLY, 0), fd[0] = -1; else { #ifndef MSDOS -#ifndef MAC_OS8 errno = 0; if (pipe (fd) == -1) { emacs_close (filefd); report_file_error ("Creating process pipe", Qnil); } -#endif -#endif -#if 0 - /* Replaced by close_process_descs */ - set_exclusive_use (fd[0]); #endif } @@ -561,52 +532,6 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) report_file_error ("Cannot redirect stderr", Fcons (error_file, Qnil)); } -#ifdef MAC_OS8 - { - /* Call run_mac_command in sysdep.c here directly instead of doing - a child_setup as for MSDOS and other platforms. Note that this - code does not handle passing the environment to the synchronous - Mac subprocess. */ - char *infn, *outfn, *errfn, *currdn; - - /* close these files so subprocess can write to them */ - close (outfilefd); - if (fd_error != outfilefd) - close (fd_error); - fd1 = -1; /* No harm in closing that one! */ - - infn = SDATA (infile); - outfn = tempfile; - if (NILP (error_file)) - errfn = NULL_DEVICE; - else if (EQ (Qt, error_file)) - errfn = outfn; - else - errfn = SDATA (error_file); - currdn = SDATA (current_dir); - pid = run_mac_command (new_argv, currdn, infn, outfn, errfn); - - /* Record that the synchronous process exited and note its - termination status. */ - synch_process_alive = 0; - synch_process_retcode = pid; - if (synch_process_retcode < 0) /* means it couldn't be exec'ed */ - { - synchronize_system_messages_locale (); - synch_process_death = strerror (errno); - } - - /* Since CRLF is converted to LF within `decode_coding', we can - always open a file with binary mode. */ - fd[0] = open (tempfile, O_BINARY); - if (fd[0] < 0) - { - unlink (tempfile); - close (filefd); - report_file_error ("Cannot re-open temporary file", Qnil); - } - } -#else /* not MAC_OS8 */ #ifdef MSDOS /* MW, July 1993 */ /* Note that on MSDOS `child_setup' actually returns the child process exit status, not its PID, so we assign it to `synch_process_retcode' @@ -669,7 +594,6 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) if (fd_error >= 0) emacs_close (fd_error); #endif /* not MSDOS */ -#endif /* not MAC_OS8 */ environ = save_environ; @@ -703,14 +627,14 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) /* Enable sending signal if user quits below. */ call_process_exited = 0; -#if defined(MSDOS) || defined(MAC_OS8) +#if defined(MSDOS) /* MSDOS needs different cleanup information. */ record_unwind_protect (call_process_cleanup, Fcons (make_number (fd[0]), build_string (tempfile))); #else record_unwind_protect (call_process_cleanup, Fcons (make_number (fd[0]), make_number (pid))); -#endif /* not MSDOS and not MAC_OS8 */ +#endif /* not MSDOS */ if (BUFFERP (buffer)) @@ -808,10 +732,18 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) 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, buf, nread, curbuf); + unbind_to (count1, Qnil); if (display_on_the_fly && CODING_REQUIRE_DETECTION (&saved_coding) && ! CODING_REQUIRE_DETECTION (&process_coding)) @@ -914,7 +846,6 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) Vlocale_coding_system, 0); return make_number (synch_process_retcode); } -#endif static Lisp_Object delete_temp_file (name) @@ -963,36 +894,32 @@ usage: (call-process-region START END PROGRAM &optional DELETE BUFFER DISPLAY &r Lisp_Object coding_systems; Lisp_Object val, *args2; int i; -#ifdef DOS_NT char *tempfile; - char *outf = '\0'; + Lisp_Object tmpdir, pattern; - if ((outf = egetenv ("TMPDIR")) - || (outf = egetenv ("TMP")) - || (outf = egetenv ("TEMP"))) - strcpy (tempfile = alloca (strlen (outf) + 20), outf); + if (STRINGP (Vtemporary_file_directory)) + tmpdir = Vtemporary_file_directory; else { - tempfile = alloca (20); - *tempfile = '\0'; - } - if (!IS_DIRECTORY_SEP (tempfile[strlen (tempfile) - 1])) - strcat (tempfile, "/"); - if ('/' == DIRECTORY_SEP) - dostounix_filename (tempfile); - else - unixtodos_filename (tempfile); -#ifdef WINDOWSNT - strcat (tempfile, "emXXXXXX"); -#else - strcat (tempfile, "detmp.XXX"); +#ifndef DOS_NT + if (getenv ("TMPDIR")) + tmpdir = build_string (getenv ("TMPDIR")); + else + tmpdir = build_string ("/tmp/"); +#else /* DOS_NT */ + char *outf; + if ((outf = egetenv ("TMPDIR")) + || (outf = egetenv ("TMP")) + || (outf = egetenv ("TEMP"))) + tmpdir = build_string (outf); + else + tmpdir = Ffile_name_as_directory (build_string ("c:/temp")); #endif -#else /* not DOS_NT */ - char *tempfile = (char *) alloca (SBYTES (Vtemp_file_name_pattern) + 1); - bcopy (SDATA (Vtemp_file_name_pattern), tempfile, - SBYTES (Vtemp_file_name_pattern) + 1); -#endif /* not DOS_NT */ + } + pattern = Fexpand_file_name (Vtemp_file_name_pattern, tmpdir); + tempfile = (char *) alloca (SBYTES (pattern) + 1); + bcopy (SDATA (pattern), tempfile, SBYTES (pattern) + 1); coding_systems = Qt; #ifdef HAVE_MKSTEMP @@ -1070,8 +997,6 @@ usage: (call-process-region START END PROGRAM &optional DELETE BUFFER DISPLAY &r RETURN_UNGCPRO (unbind_to (count, Fcall_process (nargs, args))); } -#ifndef VMS /* VMS version is in vmsproc.c. */ - static int relocate_fd (); static char ** @@ -1473,15 +1398,11 @@ DEFUN ("getenv-internal", Fgetenv_internal, Sgetenv_internal, 1, 2, 0, VARIABLE should be a string. Value is nil if VARIABLE is undefined in the environment. Otherwise, value is a string. -This function searches `process-environment' for VARIABLE. If it is -not found there, then it continues the search in the environment list -of the selected frame. +This function searches `process-environment' for VARIABLE. If optional parameter ENV is a list, then search this list instead of -`process-environment', and return t when encountering a negative entry. - -If it is a frame, then this function will ignore `process-environment' and -will simply look up the variable in that frame's environment. */) +`process-environment', and return t when encountering a negative entry +\(an entry for a variable with no value). */) (variable, env) Lisp_Object variable, env; { @@ -1519,7 +1440,6 @@ egetenv (var) return 0; } -#endif /* not VMS */ /* This is run before init_cmdargs. */ @@ -1622,26 +1542,8 @@ init_callproc () dir_warning ("Warning: arch-independent data dir (%s) does not exist.\n", Vdata_directory); -#ifdef VMS - Vshell_file_name = build_string ("*dcl*"); -#else sh = (char *) getenv ("SHELL"); Vshell_file_name = build_string (sh ? sh : "/bin/sh"); -#endif - -#ifdef VMS - Vtemp_file_name_pattern = build_string ("tmp:emacsXXXXXX."); -#else - if (getenv ("TMPDIR")) - { - char *dir = getenv ("TMPDIR"); - Vtemp_file_name_pattern - = Fexpand_file_name (build_string ("emacsXXXXXX"), - build_string (dir)); - } - else - Vtemp_file_name_pattern = build_string ("/tmp/emacsXXXXXX"); -#endif #ifdef DOS_NT Vshared_game_score_directory = Qnil; @@ -1658,8 +1560,11 @@ set_initial_environment () register char **envp; #ifndef CANNOT_DUMP if (initialized) -#endif { +#else + { + Vprocess_environment = Qnil; +#endif for (envp = environ; *envp; envp++) Vprocess_environment = Fcons (build_string (*envp), Vprocess_environment); @@ -1677,6 +1582,15 @@ syms_of_callproc () staticpro (&Qbuffer_file_type); #endif /* DOS_NT */ +#ifndef DOS_NT + Vtemp_file_name_pattern = build_string ("emacsXXXXXX"); +#elif defined (WINDOWSNT) + Vtemp_file_name_pattern = build_string ("emXXXXXX"); +#else + Vtemp_file_name_pattern = build_string ("detmp.XXX"); +#endif + staticpro (&Vtemp_file_name_pattern); + DEFVAR_LISP ("shell-file-name", &Vshell_file_name, doc: /* *File name to load inferior shells from. Initialized from the SHELL environment variable, or to a system-dependent @@ -1720,11 +1634,6 @@ If this variable is nil, then Emacs is unable to use a shared directory. */); Vshared_game_score_directory = build_string (PATH_GAME); #endif - DEFVAR_LISP ("temp-file-name-pattern", &Vtemp_file_name_pattern, - doc: /* Pattern for making names for temporary files. -This is used by `call-process-region'. */); - /* This variable is initialized in init_callproc. */ - DEFVAR_LISP ("initial-environment", &Vinitial_environment, doc: /* List of environment variables inherited from the parent process. Each element should be a string of the form ENVVARNAME=VALUE. @@ -1754,10 +1663,8 @@ use. See `setenv' and `getenv'. */); Vprocess_environment = Qnil; -#ifndef VMS defsubr (&Scall_process); defsubr (&Sgetenv_internal); -#endif defsubr (&Scall_process_region); }