aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog11
-rw-r--r--src/callproc.c86
2 files changed, 59 insertions, 38 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index efa404afc2f..da15a612a19 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,14 @@
12012-11-28 Paul Eggert <eggert@cs.ucla.edu>
2
3 * callproc.c (Fcall_process): Fix vfork portability problems.
4 Do not assume that fd[0], count, filefd, and save_environ survive
5 vfork. Fix bug whereby wrong errno value could be reported for
6 pipe failure. Some minor cleanups, too, as follows. Move buf and
7 bufsize to the context where they're needed. Change new_argv to
8 be of type char **, as this is more convenient and avoids casts.
9 (CALLPROC_BUFFER_SIZE_MIN, CALLPROC_BUFFER_SIZE_MAX):
10 Now local constants, not macros.
11
12012-11-18 Kenichi Handa <handa@gnu.org> 122012-11-18 Kenichi Handa <handa@gnu.org>
2 13
3 * font.c (font_unparse_xlfd): Fix previous change. Keep "const" 14 * font.c (font_unparse_xlfd): Fix previous change. Keep "const"
diff --git a/src/callproc.c b/src/callproc.c
index c9a504746b3..bba1c043b4c 100644
--- a/src/callproc.c
+++ b/src/callproc.c
@@ -183,16 +183,11 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */)
183{ 183{
184 Lisp_Object infile, buffer, current_dir, path, cleanup_info_tail; 184 Lisp_Object infile, buffer, current_dir, path, cleanup_info_tail;
185 bool display_p; 185 bool display_p;
186 int fd[2]; 186 int fd0, fd1, filefd;
187 int filefd;
188#define CALLPROC_BUFFER_SIZE_MIN (16 * 1024)
189#define CALLPROC_BUFFER_SIZE_MAX (4 * CALLPROC_BUFFER_SIZE_MIN)
190 char buf[CALLPROC_BUFFER_SIZE_MAX];
191 int bufsize = CALLPROC_BUFFER_SIZE_MIN;
192 ptrdiff_t count = SPECPDL_INDEX (); 187 ptrdiff_t count = SPECPDL_INDEX ();
193 USE_SAFE_ALLOCA; 188 USE_SAFE_ALLOCA;
194 189
195 register const unsigned char **new_argv; 190 char **new_argv;
196 /* File to use for stderr in the child. 191 /* File to use for stderr in the child.
197 t means use same as standard output. */ 192 t means use same as standard output. */
198 Lisp_Object error_file; 193 Lisp_Object error_file;
@@ -432,12 +427,12 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */)
432 } 427 }
433 UNGCPRO; 428 UNGCPRO;
434 for (i = 4; i < nargs; i++) 429 for (i = 4; i < nargs; i++)
435 new_argv[i - 3] = SDATA (args[i]); 430 new_argv[i - 3] = SSDATA (args[i]);
436 new_argv[i - 3] = 0; 431 new_argv[i - 3] = 0;
437 } 432 }
438 else 433 else
439 new_argv[1] = 0; 434 new_argv[1] = 0;
440 new_argv[0] = SDATA (path); 435 new_argv[0] = SSDATA (path);
441 436
442#ifdef MSDOS /* MW, July 1993 */ 437#ifdef MSDOS /* MW, July 1993 */
443 438
@@ -466,29 +461,35 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */)
466 } 461 }
467 else 462 else
468 outfilefd = fd_output; 463 outfilefd = fd_output;
469 fd[0] = filefd; 464 fd0 = filefd;
470 fd[1] = outfilefd; 465 fd1 = outfilefd;
471#endif /* MSDOS */ 466#endif /* MSDOS */
472 467
473 if (INTEGERP (buffer)) 468 if (INTEGERP (buffer))
474 fd[1] = emacs_open (NULL_DEVICE, O_WRONLY, 0), fd[0] = -1; 469 {
470 fd0 = -1;
471 fd1 = emacs_open (NULL_DEVICE, O_WRONLY, 0);
472 }
475 else 473 else
476 { 474 {
477#ifndef MSDOS 475#ifndef MSDOS
478 errno = 0; 476 int fd[2];
479 if (pipe (fd) == -1) 477 if (pipe (fd) == -1)
480 { 478 {
479 int pipe_errno = errno;
481 emacs_close (filefd); 480 emacs_close (filefd);
481 errno = pipe_errno;
482 report_file_error ("Creating process pipe", Qnil); 482 report_file_error ("Creating process pipe", Qnil);
483 } 483 }
484 fd0 = fd[0];
485 fd1 = fd[1];
484#endif 486#endif
485 } 487 }
486 488
487 { 489 {
488 /* child_setup must clobber environ in systems with true vfork. 490 /* child_setup must clobber environ in systems with true vfork.
489 Protect it from permanent change. */ 491 Protect it from permanent change. */
490 register char **save_environ = environ; 492 char **save_environ = environ;
491 register int fd1 = fd[1];
492 int fd_error = fd1; 493 int fd_error = fd1;
493 494
494 if (fd_output >= 0) 495 if (fd_output >= 0)
@@ -520,8 +521,8 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */)
520 if (fd_error < 0) 521 if (fd_error < 0)
521 { 522 {
522 emacs_close (filefd); 523 emacs_close (filefd);
523 if (fd[0] != filefd) 524 if (fd0 != filefd)
524 emacs_close (fd[0]); 525 emacs_close (fd0);
525 if (fd1 >= 0) 526 if (fd1 >= 0)
526 emacs_close (fd1); 527 emacs_close (fd1);
527#ifdef MSDOS 528#ifdef MSDOS
@@ -538,8 +539,7 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */)
538 /* Note that on MSDOS `child_setup' actually returns the child process 539 /* Note that on MSDOS `child_setup' actually returns the child process
539 exit status, not its PID, so we assign it to `synch_process_retcode' 540 exit status, not its PID, so we assign it to `synch_process_retcode'
540 below. */ 541 below. */
541 pid = child_setup (filefd, outfilefd, fd_error, (char **) new_argv, 542 pid = child_setup (filefd, outfilefd, fd_error, new_argv, 0, current_dir);
542 0, current_dir);
543 543
544 /* Record that the synchronous process exited and note its 544 /* Record that the synchronous process exited and note its
545 termination status. */ 545 termination status. */
@@ -559,8 +559,8 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */)
559 { 559 {
560 /* Since CRLF is converted to LF within `decode_coding', we 560 /* Since CRLF is converted to LF within `decode_coding', we
561 can always open a file with binary mode. */ 561 can always open a file with binary mode. */
562 fd[0] = emacs_open (tempfile, O_RDONLY | O_BINARY, 0); 562 fd0 = emacs_open (tempfile, O_RDONLY | O_BINARY, 0);
563 if (fd[0] < 0) 563 if (fd0 < 0)
564 { 564 {
565 unlink (tempfile); 565 unlink (tempfile);
566 emacs_close (filefd); 566 emacs_close (filefd);
@@ -569,11 +569,10 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */)
569 } 569 }
570 } 570 }
571 else 571 else
572 fd[0] = -1; /* We are not going to read from tempfile. */ 572 fd0 = -1; /* We are not going to read from tempfile. */
573#else /* not MSDOS */ 573#else /* not MSDOS */
574#ifdef WINDOWSNT 574#ifdef WINDOWSNT
575 pid = child_setup (filefd, fd1, fd_error, (char **) new_argv, 575 pid = child_setup (filefd, fd1, fd_error, new_argv, 0, current_dir);
576 0, current_dir);
577#else /* not WINDOWSNT */ 576#else /* not WINDOWSNT */
578 577
579 block_input (); 578 block_input ();
@@ -586,11 +585,15 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */)
586 bool volatile display_p_volatile = display_p; 585 bool volatile display_p_volatile = display_p;
587 bool volatile output_to_buffer_volatile = output_to_buffer; 586 bool volatile output_to_buffer_volatile = output_to_buffer;
588 bool volatile sa_must_free_volatile = sa_must_free; 587 bool volatile sa_must_free_volatile = sa_must_free;
588 int volatile fd0_volatile = fd0;
589 int volatile fd1_volatile = fd1; 589 int volatile fd1_volatile = fd1;
590 int volatile fd_error_volatile = fd_error; 590 int volatile fd_error_volatile = fd_error;
591 int volatile fd_output_volatile = fd_output; 591 int volatile fd_output_volatile = fd_output;
592 int volatile filefd_volatile = filefd;
593 ptrdiff_t volatile count_volatile = count;
592 ptrdiff_t volatile sa_count_volatile = sa_count; 594 ptrdiff_t volatile sa_count_volatile = sa_count;
593 unsigned char const **volatile new_argv_volatile = new_argv; 595 char **volatile new_argv_volatile = new_argv;
596 char **volatile new_save_environ = save_environ;
594 597
595 pid = vfork (); 598 pid = vfork ();
596 599
@@ -598,27 +601,30 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */)
598 coding_systems = coding_systems_volatile; 601 coding_systems = coding_systems_volatile;
599 current_dir = current_dir_volatile; 602 current_dir = current_dir_volatile;
600 display_p = display_p_volatile; 603 display_p = display_p_volatile;
604 output_to_buffer = output_to_buffer_volatile;
605 sa_must_free = sa_must_free_volatile;
606 fd0 = fd0_volatile;
601 fd1 = fd1_volatile; 607 fd1 = fd1_volatile;
602 fd_error = fd_error_volatile; 608 fd_error = fd_error_volatile;
603 fd_output = fd_output_volatile; 609 fd_output = fd_output_volatile;
604 output_to_buffer = output_to_buffer_volatile; 610 filefd = filefd_volatile;
605 sa_must_free = sa_must_free_volatile; 611 count = count_volatile;
606 sa_count = sa_count_volatile; 612 sa_count = sa_count_volatile;
607 new_argv = new_argv_volatile; 613 new_argv = new_argv_volatile;
614 save_environ = new_save_environ;
608 } 615 }
609 616
610 if (pid == 0) 617 if (pid == 0)
611 { 618 {
612 if (fd[0] >= 0) 619 if (fd0 >= 0)
613 emacs_close (fd[0]); 620 emacs_close (fd0);
614 621
615 setsid (); 622 setsid ();
616 623
617 /* Emacs ignores SIGPIPE, but the child should not. */ 624 /* Emacs ignores SIGPIPE, but the child should not. */
618 signal (SIGPIPE, SIG_DFL); 625 signal (SIGPIPE, SIG_DFL);
619 626
620 child_setup (filefd, fd1, fd_error, (char **) new_argv, 627 child_setup (filefd, fd1, fd_error, new_argv, 0, current_dir);
621 0, current_dir);
622 } 628 }
623 629
624 unblock_input (); 630 unblock_input ();
@@ -632,7 +638,7 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */)
632 638
633 environ = save_environ; 639 environ = save_environ;
634 640
635 /* Close most of our fd's, but not fd[0] 641 /* Close most of our file descriptors, but not fd0
636 since we will use that to read input from. */ 642 since we will use that to read input from. */
637 emacs_close (filefd); 643 emacs_close (filefd);
638 if (fd_output >= 0) 644 if (fd_output >= 0)
@@ -643,15 +649,15 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */)
643 649
644 if (pid < 0) 650 if (pid < 0)
645 { 651 {
646 if (fd[0] >= 0) 652 if (fd0 >= 0)
647 emacs_close (fd[0]); 653 emacs_close (fd0);
648 report_file_error ("Doing vfork", Qnil); 654 report_file_error ("Doing vfork", Qnil);
649 } 655 }
650 656
651 if (INTEGERP (buffer)) 657 if (INTEGERP (buffer))
652 { 658 {
653 if (fd[0] >= 0) 659 if (fd0 >= 0)
654 emacs_close (fd[0]); 660 emacs_close (fd0);
655 return Qnil; 661 return Qnil;
656 } 662 }
657 663
@@ -666,7 +672,7 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */)
666#endif /* not MSDOS */ 672#endif /* not MSDOS */
667 record_unwind_protect (call_process_cleanup, 673 record_unwind_protect (call_process_cleanup,
668 Fcons (Fcurrent_buffer (), 674 Fcons (Fcurrent_buffer (),
669 Fcons (INTEGER_TO_CONS (fd[0]), 675 Fcons (INTEGER_TO_CONS (fd0),
670 cleanup_info_tail))); 676 cleanup_info_tail)));
671 677
672 if (BUFFERP (buffer)) 678 if (BUFFERP (buffer))
@@ -723,6 +729,10 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */)
723 729
724 if (output_to_buffer) 730 if (output_to_buffer)
725 { 731 {
732 enum { CALLPROC_BUFFER_SIZE_MIN = 16 * 1024 };
733 enum { CALLPROC_BUFFER_SIZE_MAX = 4 * CALLPROC_BUFFER_SIZE_MIN };
734 char buf[CALLPROC_BUFFER_SIZE_MAX];
735 int bufsize = CALLPROC_BUFFER_SIZE_MIN;
726 int nread; 736 int nread;
727 bool first = 1; 737 bool first = 1;
728 EMACS_INT total_read = 0; 738 EMACS_INT total_read = 0;
@@ -739,7 +749,7 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */)
739 nread = carryover; 749 nread = carryover;
740 while (nread < bufsize - 1024) 750 while (nread < bufsize - 1024)
741 { 751 {
742 int this_read = emacs_read (fd[0], buf + nread, 752 int this_read = emacs_read (fd0, buf + nread,
743 bufsize - nread); 753 bufsize - nread);
744 754
745 if (this_read < 0) 755 if (this_read < 0)