aboutsummaryrefslogtreecommitdiffstats
path: root/src/callproc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/callproc.c')
-rw-r--r--src/callproc.c115
1 files changed, 56 insertions, 59 deletions
diff --git a/src/callproc.c b/src/callproc.c
index 6de8113dc14..30f9dc58d46 100644
--- a/src/callproc.c
+++ b/src/callproc.c
@@ -31,6 +31,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
31 31
32#ifdef WINDOWSNT 32#ifdef WINDOWSNT
33#define NOMINMAX 33#define NOMINMAX
34#include <sys/socket.h> /* for fcntl */
34#include <windows.h> 35#include <windows.h>
35#include "w32.h" 36#include "w32.h"
36#define _P_NOWAIT 1 /* from process.h */ 37#define _P_NOWAIT 1 /* from process.h */
@@ -418,9 +419,10 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) *
418 default_output_mode); 419 default_output_mode);
419 if (fd_output < 0) 420 if (fd_output < 0)
420 { 421 {
422 int open_errno = errno;
421 output_file = DECODE_FILE (output_file); 423 output_file = DECODE_FILE (output_file);
422 report_file_error ("Opening process output file", 424 report_file_errno ("Opening process output file",
423 Fcons (output_file, Qnil)); 425 Fcons (output_file, Qnil), open_errno);
424 } 426 }
425 if (STRINGP (error_file) || NILP (error_file)) 427 if (STRINGP (error_file) || NILP (error_file))
426 output_to_buffer = 0; 428 output_to_buffer = 0;
@@ -429,16 +431,19 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) *
429 /* Search for program; barf if not found. */ 431 /* Search for program; barf if not found. */
430 { 432 {
431 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; 433 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
434 int ok;
432 435
433 GCPRO4 (infile, buffer, current_dir, error_file); 436 GCPRO4 (infile, buffer, current_dir, error_file);
434 openp (Vexec_path, args[0], Vexec_suffixes, &path, make_number (X_OK)); 437 ok = openp (Vexec_path, args[0], Vexec_suffixes, &path, make_number (X_OK));
435 UNGCPRO; 438 UNGCPRO;
439 if (ok < 0)
440 {
441 int openp_errno = errno;
442 emacs_close (filefd);
443 report_file_errno ("Searching for program",
444 Fcons (args[0], Qnil), openp_errno);
445 }
436 } 446 }
437 if (NILP (path))
438 {
439 emacs_close (filefd);
440 report_file_error ("Searching for program", Fcons (args[0], Qnil));
441 }
442 447
443 /* If program file name starts with /: for quoting a magic name, 448 /* If program file name starts with /: for quoting a magic name,
444 discard that. */ 449 discard that. */
@@ -496,11 +501,13 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) *
496 mktemp (tempfile); 501 mktemp (tempfile);
497 outfilefd = emacs_open (tempfile, O_WRONLY | O_CREAT | O_TRUNC, 502 outfilefd = emacs_open (tempfile, O_WRONLY | O_CREAT | O_TRUNC,
498 S_IREAD | S_IWRITE); 503 S_IREAD | S_IWRITE);
499 if (outfilefd < 0) { 504 if (outfilefd < 0)
500 emacs_close (filefd); 505 {
501 report_file_error ("Opening process output file", 506 int open_errno = errno;
502 Fcons (build_string (tempfile), Qnil)); 507 emacs_close (filefd);
503 } 508 report_file_errno ("Opening process output file",
509 Fcons (build_string (tempfile), Qnil), open_errno);
510 }
504 } 511 }
505 else 512 else
506 outfilefd = fd_output; 513 outfilefd = fd_output;
@@ -517,12 +524,11 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) *
517 { 524 {
518#ifndef MSDOS 525#ifndef MSDOS
519 int fd[2]; 526 int fd[2];
520 if (pipe (fd) == -1) 527 if (pipe2 (fd, O_CLOEXEC) != 0)
521 { 528 {
522 int pipe_errno = errno; 529 int pipe_errno = errno;
523 emacs_close (filefd); 530 emacs_close (filefd);
524 errno = pipe_errno; 531 report_file_errno ("Creating process pipe", Qnil, pipe_errno);
525 report_file_error ("Creating process pipe", Qnil);
526 } 532 }
527 fd0 = fd[0]; 533 fd0 = fd[0];
528 fd1 = fd[1]; 534 fd1 = fd[1];
@@ -544,6 +550,7 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) *
544 550
545 if (fd_error < 0) 551 if (fd_error < 0)
546 { 552 {
553 int open_errno = errno;
547 emacs_close (filefd); 554 emacs_close (filefd);
548 if (fd0 != filefd) 555 if (fd0 != filefd)
549 emacs_close (fd0); 556 emacs_close (fd0);
@@ -556,7 +563,8 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) *
556 error_file = build_string (NULL_DEVICE); 563 error_file = build_string (NULL_DEVICE);
557 else if (STRINGP (error_file)) 564 else if (STRINGP (error_file))
558 error_file = DECODE_FILE (error_file); 565 error_file = DECODE_FILE (error_file);
559 report_file_error ("Cannot redirect stderr", Fcons (error_file, Qnil)); 566 report_file_errno ("Cannot redirect stderr",
567 Fcons (error_file, Qnil), open_errno);
560 } 568 }
561 569
562#ifdef MSDOS /* MW, July 1993 */ 570#ifdef MSDOS /* MW, July 1993 */
@@ -584,10 +592,12 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) *
584 fd0 = emacs_open (tempfile, O_RDONLY | O_BINARY, 0); 592 fd0 = emacs_open (tempfile, O_RDONLY | O_BINARY, 0);
585 if (fd0 < 0) 593 if (fd0 < 0)
586 { 594 {
595 int open_errno = errno;
587 unlink (tempfile); 596 unlink (tempfile);
588 emacs_close (filefd); 597 emacs_close (filefd);
589 report_file_error ("Cannot re-open temporary file", 598 report_file_errno ("Cannot re-open temporary file",
590 Fcons (build_string (tempfile), Qnil)); 599 Fcons (build_string (tempfile), Qnil),
600 open_errno);
591 } 601 }
592 } 602 }
593 else 603 else
@@ -705,10 +715,7 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) *
705 } 715 }
706 716
707 if (pid < 0) 717 if (pid < 0)
708 { 718 report_file_errno ("Doing vfork", Qnil, child_errno);
709 errno = child_errno;
710 report_file_error ("Doing vfork", Qnil);
711 }
712 719
713 if (INTEGERP (buffer)) 720 if (INTEGERP (buffer))
714 return unbind_to (count, Qnil); 721 return unbind_to (count, Qnil);
@@ -1034,29 +1041,29 @@ usage: (call-process-region START END PROGRAM &optional DELETE BUFFER DISPLAY &r
1034 memcpy (tempfile, SDATA (encoded_tem), SBYTES (encoded_tem) + 1); 1041 memcpy (tempfile, SDATA (encoded_tem), SBYTES (encoded_tem) + 1);
1035 coding_systems = Qt; 1042 coding_systems = Qt;
1036 1043
1037#ifdef HAVE_MKSTEMP 1044#if defined HAVE_MKOSTEMP || defined HAVE_MKSTEMP
1038 { 1045 {
1039 int fd; 1046 int fd, open_errno;
1040 1047
1041 block_input (); 1048 block_input ();
1049# ifdef HAVE_MKOSTEMP
1050 fd = mkostemp (tempfile, O_CLOEXEC);
1051# else
1042 fd = mkstemp (tempfile); 1052 fd = mkstemp (tempfile);
1053# endif
1054 open_errno = errno;
1043 unblock_input (); 1055 unblock_input ();
1044 if (fd == -1) 1056 if (fd < 0)
1045 report_file_error ("Failed to open temporary file", 1057 report_file_errno ("Failed to open temporary file",
1046 Fcons (build_string (tempfile), Qnil)); 1058 Fcons (build_string (tempfile), Qnil), open_errno);
1047 else 1059 emacs_close (fd);
1048 close (fd);
1049 } 1060 }
1050#else 1061#else
1051 errno = 0; 1062 errno = EEXIST;
1052 mktemp (tempfile); 1063 mktemp (tempfile);
1053 if (!*tempfile) 1064 if (!*tempfile)
1054 { 1065 report_file_error ("Failed to open temporary file using pattern",
1055 if (!errno) 1066 Fcons (pattern, Qnil));
1056 errno = EEXIST;
1057 report_file_error ("Failed to open temporary file using pattern",
1058 Fcons (pattern, Qnil));
1059 }
1060#endif 1067#endif
1061 1068
1062 filename_string = build_string (tempfile); 1069 filename_string = build_string (tempfile);
@@ -1182,15 +1189,6 @@ child_setup (int in, int out, int err, char **new_argv, bool set_pgrp,
1182 1189
1183 pid_t pid = getpid (); 1190 pid_t pid = getpid ();
1184 1191
1185 /* Close Emacs's descriptors that this process should not have. */
1186 close_process_descs ();
1187
1188 /* DOS_NT isn't in a vfork, so if we are in the middle of load-file,
1189 we will lose if we call close_load_descs here. */
1190#ifndef DOS_NT
1191 close_load_descs ();
1192#endif
1193
1194 /* Note that use of alloca is always safe here. It's obvious for systems 1192 /* Note that use of alloca is always safe here. It's obvious for systems
1195 that do not have true vfork or that have true (stack) alloca. 1193 that do not have true vfork or that have true (stack) alloca.
1196 If using vfork and C_ALLOCA (when Emacs used to include 1194 If using vfork and C_ALLOCA (when Emacs used to include
@@ -1223,7 +1221,7 @@ child_setup (int in, int out, int err, char **new_argv, bool set_pgrp,
1223 are changed between the check and this chdir, but we should 1221 are changed between the check and this chdir, but we should
1224 at least check. */ 1222 at least check. */
1225 if (chdir (temp) < 0) 1223 if (chdir (temp) < 0)
1226 _exit (errno); 1224 _exit (EXIT_CANCELED);
1227#else /* DOS_NT */ 1225#else /* DOS_NT */
1228 /* Get past the drive letter, so that d:/ is left alone. */ 1226 /* Get past the drive letter, so that d:/ is left alone. */
1229 if (i > 2 && IS_DEVICE_SEP (temp[1]) && IS_DIRECTORY_SEP (temp[2])) 1227 if (i > 2 && IS_DEVICE_SEP (temp[1]) && IS_DIRECTORY_SEP (temp[2]))
@@ -1352,9 +1350,11 @@ child_setup (int in, int out, int err, char **new_argv, bool set_pgrp,
1352 emacs_close (1); 1350 emacs_close (1);
1353 emacs_close (2); 1351 emacs_close (2);
1354 1352
1353 /* Redirect file descriptors and clear FD_CLOEXEC on the redirected ones. */
1355 dup2 (in, 0); 1354 dup2 (in, 0);
1356 dup2 (out, 1); 1355 dup2 (out, 1);
1357 dup2 (err, 2); 1356 dup2 (err, 2);
1357
1358 emacs_close (in); 1358 emacs_close (in);
1359 if (out != in) 1359 if (out != in)
1360 emacs_close (out); 1360 emacs_close (out);
@@ -1366,10 +1366,12 @@ child_setup (int in, int out, int err, char **new_argv, bool set_pgrp,
1366 1366
1367 execve (new_argv[0], new_argv, env); 1367 execve (new_argv[0], new_argv, env);
1368 1368
1369 emacs_write (1, "Can't exec program: ", 20); 1369 /* Don't output the program name here, as it can be arbitrarily long,
1370 emacs_write (1, new_argv[0], strlen (new_argv[0])); 1370 and a long write from a vforked child to its parent can cause a
1371 emacs_write (1, "\n", 1); 1371 deadlock. */
1372 _exit (1); 1372 emacs_perror ("child process");
1373
1374 _exit (errno == ENOENT ? EXIT_ENOENT : EXIT_CANNOT_INVOKE);
1373 1375
1374#else /* MSDOS */ 1376#else /* MSDOS */
1375 pid = run_msdos_command (new_argv, pwd_var + 4, in, out, err, env); 1377 pid = run_msdos_command (new_argv, pwd_var + 4, in, out, err, env);
@@ -1392,16 +1394,11 @@ relocate_fd (int fd, int minfd)
1392 return fd; 1394 return fd;
1393 else 1395 else
1394 { 1396 {
1395 int new = fcntl (fd, F_DUPFD, minfd); 1397 int new = fcntl (fd, F_DUPFD_CLOEXEC, minfd);
1396 if (new == -1) 1398 if (new == -1)
1397 { 1399 {
1398 const char *message_1 = "Error while setting up child: "; 1400 emacs_perror ("while setting up child");
1399 const char *errmessage = strerror (errno); 1401 _exit (EXIT_CANCELED);
1400 const char *message_2 = "\n";
1401 emacs_write (2, message_1, strlen (message_1));
1402 emacs_write (2, errmessage, strlen (errmessage));
1403 emacs_write (2, message_2, strlen (message_2));
1404 _exit (1);
1405 } 1402 }
1406 emacs_close (fd); 1403 emacs_close (fd);
1407 return new; 1404 return new;