diff options
| author | Tom Tromey | 2013-07-12 18:44:13 -0600 |
|---|---|---|
| committer | Tom Tromey | 2013-07-12 18:44:13 -0600 |
| commit | b34a529f177a6ea32da5cb1254f91bf9d71838db (patch) | |
| tree | 477131abc15d3107b30b635223d87a22550b480b /src/callproc.c | |
| parent | e6f63071a3f7721f55220514b6d9a8ee8c1232d8 (diff) | |
| parent | 5e301d7651c0691bb2bc7f3fbe711fdbe26ac471 (diff) | |
| download | emacs-b34a529f177a6ea32da5cb1254f91bf9d71838db.tar.gz emacs-b34a529f177a6ea32da5cb1254f91bf9d71838db.zip | |
Merge from trunk
Diffstat (limited to 'src/callproc.c')
| -rw-r--r-- | src/callproc.c | 115 |
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; |