X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/eb2bfdae0a1b6579908f072ab57aec0d80d6c6ec..aaf34461ff5804e5cebe163b31e535da72e81d87:/src/callproc.c diff --git a/src/callproc.c b/src/callproc.c index 25861602c8..5bd4cee9cf 100644 --- a/src/callproc.c +++ b/src/callproc.c @@ -1,12 +1,12 @@ /* Synchronous subprocess invocation for GNU Emacs. Copyright (C) 1985, 1986, 1987, 1988, 1993, 1994, 1995, 1999, 2000, 2001, - 2002, 2003, 2004, 2005 Free Software Foundation, Inc. + 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. This file is part of GNU Emacs. 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 2, or (at your option) +the Free Software Foundation; either version 3, or (at your option) any later version. GNU Emacs is distributed in the hope that it will be useful, @@ -113,14 +113,13 @@ Lisp_Object Vtemp_file_name_pattern; Lisp_Object Vshell_file_name; -Lisp_Object Vglobal_environment; Lisp_Object Vprocess_environment; #ifdef DOS_NT Lisp_Object Qbuffer_file_type; #endif /* DOS_NT */ -/* True iff we are about to fork off a synchronous process or if we +/* True if we are about to fork off a synchronous process or if we are waiting for it. */ int synch_process_alive; @@ -134,9 +133,6 @@ int synch_process_termsig; this is exit code of synchronous subprocess. */ int synch_process_retcode; -/* List of environment variables to look up in emacsclient. */ -Lisp_Object Vlocal_environment_variables; - /* Clean up when exiting Fcall_process. On MSDOS, delete the temporary file on any kind of termination. @@ -210,6 +206,10 @@ t (mix it with ordinary output), or a file name string. Fourth arg DISPLAY non-nil means redisplay buffer as output is inserted. Remaining arguments are strings passed as command arguments to PROGRAM. +If executable PROGRAM can't be found as an executable, `call-process' +signals a Lisp error. `call-process' reports errors in execution of +the program only through its return and output. + If BUFFER is 0, `call-process' returns immediately with value nil. Otherwise it waits for PROGRAM to terminate and returns a numeric exit status or a signal description string. @@ -302,6 +302,10 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) val = Qnil; } setup_coding_system (Fcheck_coding_system (val), &argument_coding); + if (argument_coding.common_flags & CODING_ASCII_INCOMPATIBLE_MASK) + setup_coding_system (Qraw_text, &argument_coding); + if (argument_coding.eol_type == CODING_EOL_UNDECIDED) + argument_coding.eol_type = system_eol_type; } } @@ -1103,7 +1107,11 @@ usage: (call-process-region START END PROGRAM &optional DELETE BUFFER DISPLAY &r #ifdef HAVE_MKSTEMP { - int fd = mkstemp (tempfile); + int fd; + + BLOCK_INPUT; + fd = mkstemp (tempfile); + UNBLOCK_INPUT; if (fd == -1) report_file_error ("Failed to open temporary file", Fcons (Vtemp_file_name_pattern, Qnil)); @@ -1237,6 +1245,8 @@ child_setup (in, out, err, new_argv, set_pgrp, current_dir) { char **env; char *pwd_var; + char *term_var; + char *display_var; #ifdef WINDOWSNT int cpid; HANDLE handles[3]; @@ -1317,9 +1327,12 @@ child_setup (in, out, err, new_argv, set_pgrp, current_dir) register char **new_env; char **p, **q; register int new_length; - Lisp_Object environment = Vglobal_environment; - Lisp_Object local; + Lisp_Object local = selected_frame; /* get_frame_param (XFRAME (Fframe_with_environment (selected_frame)), */ +/* Qenvironment); */ + Lisp_Object term; + Lisp_Object display; + new_length = 0; for (tem = Vprocess_environment; @@ -1327,51 +1340,67 @@ child_setup (in, out, err, new_argv, set_pgrp, current_dir) tem = XCDR (tem)) new_length++; - if (!NILP (Vlocal_environment_variables)) - { - local = get_frame_param (XFRAME (Fframe_with_environment (selected_frame)), - Qenvironment); - if (EQ (Vlocal_environment_variables, Qt) - && !NILP (local)) - environment = local; - else if (CONSP (local)) - { - new_length += Fsafe_length (Vlocal_environment_variables); - } - } - - for (tem = environment; +#if 0 + for (tem = local; CONSP (tem) && STRINGP (XCAR (tem)); tem = XCDR (tem)) new_length++; +#endif + + /* Add TERM and DISPLAY from the frame local values. */ + term = get_frame_param (XFRAME (local), Qterm_environment_variable); + if (! NILP (term)) + new_length++; + + display = get_frame_param (XFRAME (local), Qdisplay_environment_variable); + if (! NILP (display)) + new_length++; /* new_length + 2 to include PWD and terminating 0. */ env = new_env = (char **) alloca ((new_length + 2) * sizeof (char *)); /* If we have a PWD envvar, pass one down, but with corrected value. */ - if (getenv ("PWD")) + if (egetenv ("PWD")) *new_env++ = pwd_var; + if (! NILP (term)) + { + int vlen = strlen ("TERM=") + strlen (SDATA (term)) + 1; + char *vdata = (char *) alloca (vlen); + strcpy (vdata, "TERM="); + strcat (vdata, SDATA (term)); + new_env = add_env (env, new_env, vdata); + } + + if (! NILP (display)) + { + int vlen = strlen ("DISPLAY=") + strlen (SDATA (display)) + 1; + char *vdata = (char *) alloca (vlen); + strcpy (vdata, "DISPLAY="); + strcat (vdata, SDATA (display)); + new_env = add_env (env, new_env, vdata); + } + /* Overrides. */ for (tem = Vprocess_environment; CONSP (tem) && STRINGP (XCAR (tem)); tem = XCDR (tem)) - new_env = add_env (env, new_env, SDATA (XCAR (tem))); + { + if ((strcmp (SDATA (XCAR (tem)), "TERM") != 0) + && (strcmp (SDATA (XCAR (tem)), "DISPLAY") != 0)) + new_env = add_env (env, new_env, SDATA (XCAR (tem))); + } - /* Local part of environment, if Vlocal_environment_variables is a list. */ - for (tem = Vlocal_environment_variables; + +#if 0 + /* Local part of environment. */ + for (tem = local; CONSP (tem) && STRINGP (XCAR (tem)); tem = XCDR (tem)) - new_env = add_env (env, new_env, egetenv (SDATA (XCAR (tem)))); - - /* The rest of the environment (either Vglobal_environment or the - 'environment frame parameter). */ - for (tem = environment; - CONSP (tem) && STRINGP (XCAR (tem)); - tem = XCDR (tem)) new_env = add_env (env, new_env, SDATA (XCAR (tem))); - +#endif + *new_env = 0; /* Remove variable names without values. */ @@ -1385,6 +1414,8 @@ child_setup (in, out, err, new_argv, set_pgrp, current_dir) p++; } } + + #ifdef WINDOWSNT prepare_standard_handles (in, out, err, handles); set_process_dir (SDATA (current_dir)); @@ -1506,79 +1537,100 @@ getenv_internal (var, varlen, value, valuelen, frame) Lisp_Object frame; { Lisp_Object scan; - Lisp_Object environment = Vglobal_environment; + Lisp_Object term; + Lisp_Object display; + - /* Try to find VAR in Vprocess_environment first. */ - for (scan = Vprocess_environment; CONSP (scan); scan = XCDR (scan)) + if (NILP (frame)) { - Lisp_Object entry = XCAR (scan); - if (STRINGP (entry) - && SBYTES (entry) >= varlen + /* Try to find VAR in Vprocess_environment first. */ + for (scan = Vprocess_environment; CONSP (scan); scan = XCDR (scan)) + { + Lisp_Object entry = XCAR (scan); + if (STRINGP (entry) + && SBYTES (entry) >= varlen #ifdef WINDOWSNT - /* NT environment variables are case insensitive. */ - && ! strnicmp (SDATA (entry), var, varlen) + /* NT environment variables are case insensitive. */ + && ! strnicmp (SDATA (entry), var, varlen) #else /* not WINDOWSNT */ - && ! bcmp (SDATA (entry), var, varlen) + && ! bcmp (SDATA (entry), var, varlen) #endif /* not WINDOWSNT */ - ) - { - if (SBYTES (entry) > varlen && SREF (entry, varlen) == '=') + ) { - *value = (char *) SDATA (entry) + (varlen + 1); - *valuelen = SBYTES (entry) - (varlen + 1); - return 1; - } - else if (SBYTES (entry) == varlen) - { - /* Lone variable names in Vprocess_environment mean that - variable should be removed from the environment. */ - return 0; + if (SBYTES (entry) > varlen && SREF (entry, varlen) == '=') + { + *value = (char *) SDATA (entry) + (varlen + 1); + *valuelen = SBYTES (entry) - (varlen + 1); + return 1; + } + else if (SBYTES (entry) == varlen) + { + /* Lone variable names in Vprocess_environment mean that + variable should be removed from the environment. */ + return 0; + } } } + frame = selected_frame; } - /* Find the environment in which to search the variable. */ - if (!NILP (frame)) - { - Lisp_Object local; - - CHECK_FRAME (frame); - frame = Fframe_with_environment (frame); - local = get_frame_param (XFRAME (frame), Qenvironment); - /* Use Vglobal_environment if there is no local environment. */ - if (!NILP (local)) - environment = local; - } - else if (!NILP (Vlocal_environment_variables)) - { - Lisp_Object local = get_frame_param (XFRAME (Fframe_with_environment (selected_frame)), - Qenvironment); - if (EQ (Vlocal_environment_variables, Qt) - && !NILP (local)) - environment = local; - else if (CONSP (local)) - { - for (scan = Vlocal_environment_variables; CONSP (scan); scan = XCDR (scan)) - { - Lisp_Object entry = XCAR (scan); - if (STRINGP (entry) - && SBYTES (entry) == varlen + /* For TERM and DISPLAY first try to get the values from the frame. */ + term = get_frame_param (XFRAME (frame), Qterm_environment_variable); + if (strcmp (var, "TERM") == 0) + if (! NILP (term)) + { + *value = (char *) SDATA (term); + *valuelen = SBYTES (term); + return 1; + } + display = get_frame_param (XFRAME (frame), Qdisplay_environment_variable); + if (strcmp (var, "DISPLAY") == 0) + if (! NILP (display)) + { + *value = (char *) SDATA (display); + *valuelen = SBYTES (display); + return 1; + } + + { + /* Try to find VAR in Vprocess_environment. */ + for (scan = Vprocess_environment; CONSP (scan); scan = XCDR (scan)) + { + Lisp_Object entry = XCAR (scan); + if (STRINGP (entry) + && SBYTES (entry) >= varlen #ifdef WINDOWSNT - /* NT environment variables are case insensitive. */ - && ! strnicmp (SDATA (entry), var, varlen) + /* NT environment variables are case insensitive. */ + && ! strnicmp (SDATA (entry), var, varlen) #else /* not WINDOWSNT */ - && ! bcmp (SDATA (entry), var, varlen) + && ! bcmp (SDATA (entry), var, varlen) #endif /* not WINDOWSNT */ - ) - { - environment = local; - break; - } - } - } - } + ) + { + if (SBYTES (entry) > varlen && SREF (entry, varlen) == '=') + { + *value = (char *) SDATA (entry) + (varlen + 1); + *valuelen = SBYTES (entry) - (varlen + 1); + return 1; + } + else if (SBYTES (entry) == varlen) + { + /* Lone variable names in Vprocess_environment mean that + variable should be removed from the environment. */ + return 0; + } + } + } + } - for (scan = environment; CONSP (scan); scan = XCDR (scan)) +#if 0 + /* Find the environment in which to search the variable. */ + CHECK_FRAME (frame); + frame = Fframe_with_environment (frame); + + for (scan = get_frame_param (XFRAME (frame), Qenvironment); + CONSP (scan); + scan = XCDR (scan)) { Lisp_Object entry; @@ -1599,7 +1651,7 @@ getenv_internal (var, varlen, value, valuelen, frame) return 1; } } - +#endif return 0; } @@ -1608,14 +1660,13 @@ 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. -If optional parameter FRAME is non-nil, then it should be a frame. If -that frame has its own set of environment variables, this function -will look up VARIABLE in there. +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. -Otherwise, this function searches `process-environment' for VARIABLE. -If it is not found there, then it continues the search in either -`global-environment' or the environment list of the selected frame, -depending on the value of `local-environment-variables'. */) +If optional parameter FRAME is non-nil, then this function will ignore +`process-environment' and will simply look up the variable in that +frame's environment. */) (variable, frame) Lisp_Object variable, frame; { @@ -1762,8 +1813,8 @@ init_callproc () { char *dir = getenv ("TMPDIR"); Vtemp_file_name_pattern - = Fexpand_file_name (build_string ("emacsXXXXXX"), - build_string (dir)); + = Fexpand_file_name (build_string ("emacsXXXXXX"), + build_string (dir)); } else Vtemp_file_name_pattern = build_string ("/tmp/emacsXXXXXX"); @@ -1779,17 +1830,19 @@ init_callproc () } void -set_global_environment () +set_initial_environment () { register char **envp; - - Vglobal_environment = Qnil; + Lisp_Object env = Vprocess_environment; #ifndef CANNOT_DUMP if (initialized) #endif - for (envp = environ; *envp; envp++) - Vglobal_environment = Fcons (build_string (*envp), - Vglobal_environment); + { + for (envp = environ; *envp; envp++) + Vprocess_environment = Fcons (build_string (*envp), + Vprocess_environment); + store_frame_param (SELECTED_FRAME(), Qenvironment, Vprocess_environment); + } } void @@ -1802,7 +1855,8 @@ syms_of_callproc () DEFVAR_LISP ("shell-file-name", &Vshell_file_name, doc: /* *File name to load inferior shells from. -Initialized from the SHELL environment variable. */); +Initialized from the SHELL environment variable, or to a system-dependent +default if SHELL is not set. */); DEFVAR_LISP ("exec-path", &Vexec_path, doc: /* *List of directories to search programs to run in subprocesses. @@ -1824,12 +1878,12 @@ These are files intended for Emacs to use while it runs. */); DEFVAR_LISP ("doc-directory", &Vdoc_directory, doc: /* Directory containing the DOC file that comes with GNU Emacs. -This is usually the same as data-directory. */); +This is usually the same as `data-directory'. */); DEFVAR_LISP ("configure-info-directory", &Vconfigure_info_directory, doc: /* For internal use by the build procedure only. This is the name of the directory in which the build procedure installed -Emacs's info files; the default value for Info-default-directory-list +Emacs's info files; the default value for `Info-default-directory-list' includes this. */); Vconfigure_info_directory = build_string (PATH_INFO); @@ -1847,37 +1901,16 @@ If this variable is nil, then Emacs is unable to use a shared directory. */); This is used by `call-process-region'. */); /* This variable is initialized in init_callproc. */ - DEFVAR_LISP ("global-environment", &Vglobal_environment, - doc: /* Global list of environment variables for subprocesses to inherit. -Each element should be a string of the form ENVVARNAME=VALUE. - -The environment which Emacs inherits is placed in this variable when -Emacs starts. - -Some frames may have their own local list of environment variables in -their 'environment parameter, which may override this global list; see -`local-environment-variables' and `frame-with-environment'. See -`process-environment' for a way to modify an environment variable on -all frames. - -If multiple entries define the same variable, the first one always -takes precedence. - -Non-ASCII characters are encoded according to the initial value of -`locale-coding-system', i.e. the elements must normally be decoded for use. -See `setenv' and `getenv'. */); - DEFVAR_LISP ("process-environment", &Vprocess_environment, doc: /* List of overridden environment variables for subprocesses to inherit. Each element should be a string of the form ENVVARNAME=VALUE. -Entries in this list take precedence to those in `global-environment' -or the frame-local environments. (See `local-environment-variables' -and `frame-with-environment'.) Therefore, let-binding -`process-environment' is an easy way to temporarily change the value -of an environment variable, irrespective of where it comes from. To -use `process-environment' to remove an environment variable, include -only its name in the list, without "=VALUE". +Entries in this list take precedence to those in the frame-local +environments. Therefore, let-binding `process-environment' is an easy +way to temporarily change the value of an environment variable, +irrespective of where it comes from. To use `process-environment' to +remove an environment variable, include only its name in the list, +without "=VALUE". This variable is set to nil when Emacs starts. @@ -1896,23 +1929,6 @@ See `setenv' and `getenv'. */); defsubr (&Sgetenv_internal); #endif defsubr (&Scall_process_region); - - DEFVAR_LISP ("local-environment-variables", &Vlocal_environment_variables, - doc: /* Enable or disable frame-local environment variables. -If set to t, `getenv', `setenv' and subprocess creation functions use -the local environment of the selected frame, ignoring -`global-environment'. - -If set to nil, Emacs uses `global-environment' and ignores the -frame-local environment. - -Otherwise, `local-environment-variables' should be a list of variable -names (represented by Lisp strings) to look up in the frame's -environment. The rest will come from `global-environment'. - -The frame-local environment is stored in the 'environment frame -parameter. See `frame-with-environment'. */); - Vlocal_environment_variables = Qt; } /* arch-tag: 769b8045-1df7-4d2b-8968-e3fb49017f95