summaryrefslogtreecommitdiff
path: root/src/callproc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/callproc.c')
-rw-r--r--src/callproc.c102
1 files changed, 33 insertions, 69 deletions
diff --git a/src/callproc.c b/src/callproc.c
index 76b5caa4465..f0fe5c66611 100644
--- a/src/callproc.c
+++ b/src/callproc.c
@@ -22,6 +22,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include <config.h>
#include <errno.h>
#include <stdio.h>
+#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
@@ -31,7 +32,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include "lisp.h"
#ifdef WINDOWSNT
-#define NOMINMAX
#include <sys/socket.h> /* for fcntl */
#include <windows.h>
#include "w32.h"
@@ -292,7 +292,6 @@ call_process (ptrdiff_t nargs, Lisp_Object *args, int filefd,
Lisp_Object output_file = Qnil;
#ifdef MSDOS /* Demacs 1.1.1 91/10/16 HIRANO Satoshi */
char *tempfile = NULL;
- int pid;
#else
sigset_t oldset;
pid_t pid;
@@ -537,11 +536,9 @@ 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);
+ status = child_setup (filefd, fd_output, fd_error, new_argv, 0, current_dir);
- if (pid < 0)
+ if (status < 0)
{
child_errno = errno;
unbind_to (count, Qnil);
@@ -550,7 +547,6 @@ call_process (ptrdiff_t nargs, Lisp_Object *args, int filefd,
code_convert_string_norecord (build_string (strerror (child_errno)),
Vlocale_coding_system, 0);
}
- status = pid;
for (i = 0; i < CALLPROC_FDS; i++)
if (0 <= callproc_fd[i])
@@ -565,8 +561,7 @@ call_process (ptrdiff_t nargs, Lisp_Object *args, int filefd,
{
/* Since CRLF is converted to LF within `decode_coding', we
can always open a file with binary mode. */
- callproc_fd[CALLPROC_PIPEREAD] = emacs_open (tempfile,
- O_RDONLY | O_BINARY, 0);
+ callproc_fd[CALLPROC_PIPEREAD] = emacs_open (tempfile, O_RDONLY, 0);
if (callproc_fd[CALLPROC_PIPEREAD] < 0)
{
int open_errno = errno;
@@ -1085,10 +1080,6 @@ usage: (call-process-region START END PROGRAM &optional DELETE BUFFER DISPLAY &r
return unbind_to (count, val);
}
-#ifndef WINDOWSNT
-static int relocate_fd (int fd, int minfd);
-#endif
-
static char **
add_env (char **env, char **new_env, char *string)
{
@@ -1167,9 +1158,13 @@ exec_failed (char const *name, int err)
CURRENT_DIR is an elisp string giving the path of the current
directory the subprocess should have. Since we can't really signal
a decent error from within the child, this should be verified as an
- executable directory by the parent. */
+ executable directory by the parent.
-int
+ On GNUish hosts, either exec or return an error number.
+ On MS-Windows, either return a pid or signal an error.
+ On MS-DOS, either return an exit status or signal an error. */
+
+CHILD_SETUP_TYPE
child_setup (int in, int out, int err, char **new_argv, bool set_pgrp,
Lisp_Object current_dir)
{
@@ -1307,7 +1302,7 @@ child_setup (int in, int out, int err, char **new_argv, bool set_pgrp,
#ifdef WINDOWSNT
prepare_standard_handles (in, out, err, handles);
- set_process_dir (SDATA (current_dir));
+ set_process_dir (SSDATA (current_dir));
/* Spawn the child. (See w32proc.c:sys_spawnve). */
cpid = spawnve (_P_NOWAIT, new_argv[0], new_argv, env);
reset_standard_handles (in, out, err, handles);
@@ -1317,43 +1312,23 @@ child_setup (int in, int out, int err, char **new_argv, bool set_pgrp,
return cpid;
#else /* not WINDOWSNT */
- /* Make sure that in, out, and err are not actually already in
- descriptors zero, one, or two; this could happen if Emacs is
- started with its standard in, out, or error closed, as might
- happen under X. */
- {
- int oin = in, oout = out;
-
- /* We have to avoid relocating the same descriptor twice! */
-
- in = relocate_fd (in, 3);
- if (out == oin)
- out = in;
- else
- out = relocate_fd (out, 3);
+#ifndef MSDOS
- if (err == oin)
- err = in;
- else if (err == oout)
- err = out;
- else
- err = relocate_fd (err, 3);
- }
+ restore_nofile_limit ();
-#ifndef MSDOS
/* Redirect file descriptors and clear the close-on-exec flag on the
redirected ones. IN, OUT, and ERR are close-on-exec so they
need not be closed explicitly. */
- dup2 (in, 0);
- dup2 (out, 1);
- dup2 (err, 2);
+ dup2 (in, STDIN_FILENO);
+ dup2 (out, STDOUT_FILENO);
+ dup2 (err, STDERR_FILENO);
setpgid (0, 0);
tcsetpgrp (0, pid);
- execve (new_argv[0], new_argv, env);
- exec_failed (new_argv[0], errno);
+ int errnum = emacs_exec_file (new_argv[0], new_argv, env);
+ exec_failed (new_argv[0], errnum);
#else /* MSDOS */
pid = run_msdos_command (new_argv, pwd_var + 4, in, out, err, env);
@@ -1366,31 +1341,6 @@ child_setup (int in, int out, int err, char **new_argv, bool set_pgrp,
#endif /* not WINDOWSNT */
}
-#ifndef WINDOWSNT
-/* Move the file descriptor FD so that its number is not less than MINFD.
- If the file descriptor is moved at all, the original is closed on MSDOS,
- but not elsewhere as the caller will close it anyway. */
-static int
-relocate_fd (int fd, int minfd)
-{
- if (fd >= minfd)
- return fd;
- else
- {
- int new = fcntl (fd, F_DUPFD_CLOEXEC, minfd);
- if (new == -1)
- {
- emacs_perror ("while setting up child");
- _exit (EXIT_CANCELED);
- }
-#ifdef MSDOS
- emacs_close (fd);
-#endif
- return new;
- }
-}
-#endif /* not WINDOWSNT */
-
static bool
getenv_internal_1 (const char *var, ptrdiff_t varlen, char **value,
ptrdiff_t *valuelen, Lisp_Object env)
@@ -1402,7 +1352,7 @@ getenv_internal_1 (const char *var, ptrdiff_t varlen, char **value,
&& SBYTES (entry) >= varlen
#ifdef WINDOWSNT
/* NT environment variables are case insensitive. */
- && ! strnicmp (SDATA (entry), var, varlen)
+ && ! strnicmp (SSDATA (entry), var, varlen)
#else /* not WINDOWSNT */
&& ! memcmp (SDATA (entry), var, varlen)
#endif /* not WINDOWSNT */
@@ -1435,6 +1385,20 @@ getenv_internal (const char *var, ptrdiff_t varlen, char **value,
Vprocess_environment))
return *value ? 1 : 0;
+ /* On Windows we make some modifications to Emacs' environment
+ without recording them in Vprocess_environment. */
+#ifdef WINDOWSNT
+ {
+ char* tmpval = getenv (var);
+ if (tmpval)
+ {
+ *value = tmpval;
+ *valuelen = strlen (tmpval);
+ return 1;
+ }
+ }
+#endif
+
/* For DISPLAY try to get the values from the frame or the initial env. */
if (strcmp (var, "DISPLAY") == 0)
{