Mercurial > hg > xemacs-beta
comparison src/process-unix.c @ 853:2b6fa2618f76
[xemacs-hg @ 2002-05-28 08:44:22 by ben]
merge my stderr-proc ws
make-docfile.c: Fix places where we forget to check for EOF.
code-init.el: Don't use CRLF conversion by default on process output. CMD.EXE and
friends work both ways but Cygwin programs don't like the CRs.
code-process.el, multicast.el, process.el: Removed.
Improvements to call-process-internal:
-- allows a buffer to be specified for input and stderr output
-- use it on all systems
-- implement C-g as documented
-- clean up and comment
call-process-region uses new call-process facilities; no temp file.
remove duplicate funs in process.el.
comment exactly how coding systems work and fix various problems.
open-multicast-group now does similar coding-system frobbing to
open-network-stream.
dumped-lisp.el, faces.el, msw-faces.el: Fix some hidden errors due to code not being defined at the right time.
xemacs.mak: Add -DSTRICT.
================================================================
ALLOW SEPARATION OF STDOUT AND STDERR IN PROCESSES
================================================================
Standard output and standard error can be processed separately in
a process. Each can have its own buffer, its own mark in that buffer,
and its filter function. You can specify a separate buffer for stderr
in `start-process' to get things started, or use the new primitives:
set-process-stderr-buffer
process-stderr-buffer
process-stderr-mark
set-process-stderr-filter
process-stderr-filter
Also, process-send-region takes a 4th optional arg, a buffer.
Currently always uses a pipe() under Unix to read the error output.
(#### Would a PTY be better?)
sysdep.h, sysproc.h, unexfreebsd.c, unexsunos4.c, nt.c, emacs.c, callproc.c, symsinit.h, sysdep.c, Makefile.in.in, process-unix.c: Delete callproc.c. Move child_setup() to process-unix.c.
wait_for_termination() now only needed on a few really old systems.
console-msw.h, event-Xt.c, event-msw.c, event-stream.c, event-tty.c, event-unixoid.c, events.h, process-nt.c, process-unix.c, process.c, process.h, procimpl.h: Rewrite the process methods to handle a separate channel for
error input. Create Lstreams for reading in the error channel.
Many process methods need change. In general the changes are
fairly clear as they involve duplicating what's used for reading
the normal stdout and changing for stderr -- although tedious,
as such changes are required throughout the entire process code.
Rewrote the code that reads process output to do two loops, one
for stdout and one for stderr.
gpmevent.c, tooltalk.c: set_process_filter takes an argument for stderr.
================================================================
NEW ERROR-TRAPPING MECHANISM
================================================================
Totally rewrite error trapping code to be unified and support more
features. Basic function is call_trapping_problems(), which lets
you specify, by means of flags, what sorts of problems you want
trapped. these can include
-- quit
-- errors
-- throws past the function
-- creation of "display objects" (e.g. buffers)
-- deletion of already-existing "display objects" (e.g. buffers)
-- modification of already-existing buffers
-- entering the debugger
-- gc
-- errors->warnings (ala suspended errors)
etc. All other error funs rewritten in terms of this one.
Various older mechanisms removed or rewritten.
window.c, insdel.c, console.c, buffer.c, device.c, frame.c: When creating a display object, added call to
note_object_created(), for use with trapping_problems mechanism.
When deleting, call check_allowed_operation() and note_object
deleted().
The trapping-problems code records the objects created since the
call-trapping-problems began. Those objects can be deleted, but
none others (i.e. previously existing ones).
bytecode.c, cmdloop.c: internal_catch takes another arg.
eval.c: Add long comments describing the "five lists" used to maintain
state (backtrace, gcpro, specbind, etc.) in the Lisp engine.
backtrace.h, eval.c: Implement trapping-problems mechanism, eliminate old mechanisms or
redo in terms of new one.
frame.c, gutter.c: Flush out the concept of "critical display section", defined by
the in_display() var. Use an internal_bind() to get it reset,
rather than just doing it at end, because there may be a non-local
exit.
event-msw.c, event-stream.c, console-msw.h, device.c, dialog-msw.c, frame.c, frame.h, intl.c, toolbar.c, menubar-msw.c, redisplay.c, alloc.c, menubar-x.c: Make use of new trapping-errors stuff and rewrite code based on
old mechanisms.
glyphs-widget.c, redisplay.h: Protect calling Lisp in redisplay.
insdel.c: Protect hooks against deleting existing buffers.
frame-msw.c: Use EQ, not EQUAL in hash tables whose keys are just numbers.
Otherwise we run into stickiness in redisplay because
internal_equal() can QUIT.
================================================================
SIGNAL, C-G CHANGES
================================================================
Here we change the way that C-g interacts with event reading. The
idea is that a C-g occurring while we're reading a user event
should be read as C-g, but elsewhere should be a QUIT. The former
code did all sorts of bizarreness -- requiring that no QUIT occurs
anywhere in event-reading code (impossible to enforce given the
stuff called or Lisp code invoked), and having some weird system
involving enqueue/dequeue of a C-g and interaction with Vquit_flag
-- and it didn't work.
Now, we simply enclose all code where we want C-g read as an event
with {begin/end}_dont_check_for_quit(). This completely turns off
the mechanism that checks (and may remove or alter) C-g in the
read-ahead queues, so we just get the C-g normal.
Signal.c documents this very carefully.
cmdloop.c: Correct use of dont_check_for_quit to new scheme, remove old
out-of-date comments.
event-stream.c: Fix C-g handling to actually work.
device-x.c: Disable quit checking when err out.
signal.c: Cleanup. Add large descriptive comment.
process-unix.c, process-nt.c, sysdep.c: Use QUIT instead of REALLY_QUIT.
It's not necessary to use REALLY_QUIT and just confuses the issue.
lisp.h: Comment quit handlers.
================================================================
CONS CHANGES
================================================================
free_cons() now takes a Lisp_Object not the result of XCONS().
car and cdr have been renamed so that they don't get used directly;
go through XCAR(), XCDR() instead.
alloc.c, dired.c, editfns.c, emodules.c, fns.c, glyphs-msw.c, glyphs-x.c, glyphs.c, keymap.c, minibuf.c, search.c, eval.c, lread.c, lisp.h: Correct free_cons calling convention: now takes Lisp_Object,
not Lisp_Cons
chartab.c: Eliminate direct use of ->car, ->cdr, should be black box.
callint.c: Rewrote using EXTERNAL_LIST_LOOP to avoid use of Lisp_Cons.
================================================================
USE INTERNAL-BIND-*
================================================================
eval.c: Cleanups of these funs.
alloc.c, fileio.c, undo.c, specifier.c, text.c, profile.c, lread.c, redisplay.c, menubar-x.c, macros.c: Rewrote to use internal_bind_int() and internal_bind_lisp_object()
in place of whatever varied and cumbersome mechanisms were
formerly there.
================================================================
SPECBIND SANITY
================================================================
backtrace.h: - Improved comments
backtrace.h, bytecode.c, eval.c: Add new mechanism check_specbind_stack_sanity() for sanity
checking code each time the catchlist or specbind stack change.
Removed older prototype of same mechanism.
================================================================
MISC
================================================================
lisp.h, insdel.c, window.c, device.c, console.c, buffer.c: Fleshed out authorship.
device-msw.c: Correct bad Unicode-ization.
print.c: Be more careful when not initialized or in fatal error handling.
search.c: Eliminate running_asynch_code, an FSF holdover.
alloc.c: Added comments about gc-cons-threshold.
dialog-x.c: Use begin_gc_forbidden() around code to build up a widget value
tree, like in menubar-x.c.
gui.c: Use Qunbound not Qnil as the default for
gethash.
lisp-disunion.h, lisp-union.h: Added warnings on use of VOID_TO_LISP().
lisp.h: Use ERROR_CHECK_STRUCTURES to turn on
ERROR_CHECK_TRAPPING_PROBLEMS and ERROR_CHECK_TYPECHECK
lisp.h: Add assert_with_message.
lisp.h: Add macros for gcproing entire arrays. (You could do this before
but it required manual twiddling the gcpro structure.)
lisp.h: Add prototypes for new functions defined elsewhere.
author | ben |
---|---|
date | Tue, 28 May 2002 08:45:36 +0000 |
parents | 6728e641994e |
children | 1d8fb2eee1bb |
comparison
equal
deleted
inserted
replaced
852:d83885ef293b | 853:2b6fa2618f76 |
---|---|
49 #include "sysdep.h" | 49 #include "sysdep.h" |
50 #include "window.h" | 50 #include "window.h" |
51 #include "file-coding.h" | 51 #include "file-coding.h" |
52 | 52 |
53 #include <setjmp.h> | 53 #include <setjmp.h> |
54 #include "sysdir.h" | |
54 #include "sysfile.h" | 55 #include "sysfile.h" |
55 #include "sysproc.h" | 56 #include "sysproc.h" |
56 #include "systime.h" | 57 #include "systime.h" |
57 #include "syssignal.h" /* Always include before systty.h */ | 58 #include "syssignal.h" /* Always include before systty.h */ |
58 #include "systty.h" | 59 #include "systty.h" |
75 { | 76 { |
76 /* Non-0 if this is really a ToolTalk channel. */ | 77 /* Non-0 if this is really a ToolTalk channel. */ |
77 int connected_via_filedesc_p; | 78 int connected_via_filedesc_p; |
78 /* Descriptor by which we read from this process. -1 for dead process */ | 79 /* Descriptor by which we read from this process. -1 for dead process */ |
79 int infd; | 80 int infd; |
81 /* Descriptor by which we read stderr from this process. -1 for | |
82 dead process */ | |
83 int errfd; | |
80 /* Descriptor for the tty which this process is using. | 84 /* Descriptor for the tty which this process is using. |
81 -1 if we didn't record it (on some systems, there's no need). */ | 85 -1 if we didn't record it (on some systems, there's no need). */ |
82 int subtty; | 86 int subtty; |
83 /* Name of subprocess terminal. */ | 87 /* Name of subprocess terminal. */ |
84 Lisp_Object tty_name; | 88 Lisp_Object tty_name; |
85 /* Non-false if communicating through a pty. */ | 89 /* Non-false if communicating through a pty. */ |
86 char pty_flag; | 90 char pty_flag; |
87 }; | 91 }; |
88 | 92 |
89 #define UNIX_DATA(p) ((struct unix_process_data*)((p)->process_data)) | 93 #define UNIX_DATA(p) ((struct unix_process_data*) ((p)->process_data)) |
90 | 94 |
91 | 95 |
92 | 96 |
93 /**********************************************************************/ | 97 /**********************************************************************/ |
94 /* Static helper routines */ | 98 /* Static helper routines */ |
124 /* Close all descriptors currently in use for communication | 128 /* Close all descriptors currently in use for communication |
125 with subprocess. This is used in a newly-forked subprocess | 129 with subprocess. This is used in a newly-forked subprocess |
126 to get rid of irrelevant descriptors. */ | 130 to get rid of irrelevant descriptors. */ |
127 | 131 |
128 static int | 132 static int |
129 close_process_descs_mapfun (const void* key, void* contents, void* arg) | 133 close_process_descs_mapfun (const void *key, void *contents, void *arg) |
130 { | 134 { |
131 Lisp_Object proc; | 135 Lisp_Object proc = VOID_TO_LISP (contents); |
132 proc = VOID_TO_LISP (contents); | 136 USID vaffan, culo; |
133 event_stream_delete_stream_pair (XPROCESS(proc)->pipe_instream, | 137 |
134 XPROCESS(proc)->pipe_outstream); | 138 event_stream_delete_io_streams (XPROCESS (proc)->pipe_instream, |
139 XPROCESS (proc)->pipe_outstream, | |
140 XPROCESS (proc)->pipe_errstream, | |
141 &vaffan, &culo); | |
135 return 0; | 142 return 0; |
136 } | 143 } |
137 | 144 |
138 /* #### This function is currently called from child_setup | |
139 in callproc.c. It should become static though - kkm */ | |
140 void | 145 void |
141 close_process_descs (void) | 146 close_process_descs (void) |
142 { | 147 { |
143 maphash (close_process_descs_mapfun, usid_to_process, 0); | 148 maphash (close_process_descs_mapfun, usid_to_process, 0); |
144 } | 149 } |
184 buffer = Fget_buffer_create (buffer); | 189 buffer = Fget_buffer_create (buffer); |
185 proc = make_process_internal (name); | 190 proc = make_process_internal (name); |
186 | 191 |
187 XPROCESS (proc)->pid = Fcons (infd, name); | 192 XPROCESS (proc)->pid = Fcons (infd, name); |
188 XPROCESS (proc)->buffer = buffer; | 193 XPROCESS (proc)->buffer = buffer; |
189 init_process_io_handles (XPROCESS (proc), (void*)inch, (void*)XINT (outfd), | 194 init_process_io_handles (XPROCESS (proc), (void *) inch, |
190 0); | 195 (void *) XINT (outfd), (void *) -1, 0); |
191 UNIX_DATA (XPROCESS (proc))->connected_via_filedesc_p = 1; | 196 UNIX_DATA (XPROCESS (proc))->connected_via_filedesc_p = 1; |
192 | 197 |
193 event_stream_select_process (XPROCESS (proc)); | 198 event_stream_select_process (XPROCESS (proc), 1, 1); |
194 | 199 |
195 return proc; | 200 return proc; |
196 } | 201 } |
197 | 202 |
198 static int allocate_pty_the_old_fashioned_way (void); | 203 static int allocate_pty_the_old_fashioned_way (void); |
510 return 1; | 515 return 1; |
511 } | 516 } |
512 #endif /* !USE_GETADDRINFO */ | 517 #endif /* !USE_GETADDRINFO */ |
513 | 518 |
514 static void | 519 static void |
515 set_socket_nonblocking_maybe (int fd, int port, const char* proto) | 520 set_socket_nonblocking_maybe (int fd, int port, const char *proto) |
516 { | 521 { |
517 #ifdef PROCESS_IO_BLOCKING | 522 #ifdef PROCESS_IO_BLOCKING |
518 Lisp_Object tail; | 523 Lisp_Object tail; |
519 | 524 |
520 for (tail = network_stream_blocking_port_list; CONSP (tail); tail = XCDR (tail)) | 525 for (tail = network_stream_blocking_port_list; CONSP (tail); tail = XCDR (tail)) |
718 | 723 |
719 static int | 724 static int |
720 process_signal_char (int tty_fd, int signo) | 725 process_signal_char (int tty_fd, int signo) |
721 { | 726 { |
722 /* If it's not a tty, pray that these default values work */ | 727 /* If it's not a tty, pray that these default values work */ |
723 if (! isatty (tty_fd)) { | 728 if (! isatty (tty_fd)) |
729 { | |
724 #define CNTL(ch) (037 & (ch)) | 730 #define CNTL(ch) (037 & (ch)) |
725 switch (signo) | 731 switch (signo) |
726 { | 732 { |
727 case SIGINT: return CNTL ('C'); | 733 case SIGINT: return CNTL ('C'); |
728 case SIGQUIT: return CNTL ('\\'); | 734 case SIGQUIT: return CNTL ('\\'); |
729 #ifdef SIGTSTP | 735 #ifdef SIGTSTP |
730 case SIGTSTP: return CNTL ('Z'); | 736 case SIGTSTP: return CNTL ('Z'); |
731 #endif | 737 #endif |
732 } | 738 } |
733 } | 739 } |
734 | 740 |
735 #ifdef HAVE_TERMIOS | 741 #ifdef HAVE_TERMIOS |
736 /* TERMIOS is the latest and bestest, and seems most likely to work. | 742 /* TERMIOS is the latest and bestest, and seems most likely to work. |
737 If the system has it, use it. */ | 743 If the system has it, use it. */ |
738 { | 744 { |
803 { | 809 { |
804 p->process_data = xnew (struct unix_process_data); | 810 p->process_data = xnew (struct unix_process_data); |
805 | 811 |
806 UNIX_DATA(p)->connected_via_filedesc_p = 0; | 812 UNIX_DATA(p)->connected_via_filedesc_p = 0; |
807 UNIX_DATA(p)->infd = -1; | 813 UNIX_DATA(p)->infd = -1; |
814 UNIX_DATA(p)->errfd = -1; | |
808 UNIX_DATA(p)->subtty = -1; | 815 UNIX_DATA(p)->subtty = -1; |
809 UNIX_DATA(p)->tty_name = Qnil; | 816 UNIX_DATA(p)->tty_name = Qnil; |
810 UNIX_DATA(p)->pty_flag = 0; | 817 UNIX_DATA(p)->pty_flag = 0; |
811 } | 818 } |
812 | 819 |
841 * handles are generally represented by void* type, but are | 848 * handles are generally represented by void* type, but are |
842 * of type int (file descriptors) for UNIX. | 849 * of type int (file descriptors) for UNIX. |
843 */ | 850 */ |
844 | 851 |
845 static void | 852 static void |
846 unix_init_process_io_handles (Lisp_Process *p, void* in, void* out, int flags) | 853 unix_init_process_io_handles (Lisp_Process *p, void *in, void *out, void *err, |
847 { | 854 int flags) |
848 UNIX_DATA(p)->infd = (int)in; | 855 { |
856 UNIX_DATA(p)->infd = (int) in; | |
857 UNIX_DATA(p)->errfd = (int) err; | |
858 } | |
859 | |
860 /* Move the file descriptor FD so that its number is not less than MIN. * | |
861 The original file descriptor remains open. */ | |
862 static int | |
863 relocate_fd (int fd, int min) | |
864 { | |
865 if (fd >= min) | |
866 return fd; | |
867 else | |
868 { | |
869 int newfd = dup (fd); | |
870 if (newfd == -1) | |
871 { | |
872 Intbyte *errmess; | |
873 GET_STRERROR (errmess, errno); | |
874 stderr_out ("Error while setting up child: %s\n", errmess); | |
875 _exit (1); | |
876 } | |
877 return relocate_fd (newfd, min); | |
878 } | |
879 } | |
880 | |
881 /* This is the last thing run in a newly forked inferior process. | |
882 Copy descriptors IN, OUT and ERR | |
883 as descriptors STDIN_FILENO, STDOUT_FILENO, and STDERR_FILENO. | |
884 Initialize inferior's priority, pgrp, connected dir and environment. | |
885 then exec another program based on new_argv. | |
886 | |
887 XEmacs: We've removed the SET_PGRP argument because it's already | |
888 done by the callers of child_setup. | |
889 | |
890 CURRENT_DIR is an elisp string giving the path of the current | |
891 directory the subprocess should have. Since we can't really signal | |
892 a decent error from within the child (#### not quite correct in | |
893 XEmacs?), this should be verified as an executable directory by the | |
894 parent. */ | |
895 | |
896 static void | |
897 child_setup (int in, int out, int err, Intbyte **new_argv, | |
898 Lisp_Object current_dir) | |
899 { | |
900 Intbyte **env; | |
901 Intbyte *pwd; | |
902 | |
903 #ifdef SET_EMACS_PRIORITY | |
904 if (emacs_priority != 0) | |
905 nice (- emacs_priority); | |
906 #endif | |
907 | |
908 #if !defined (NO_SUBPROCESSES) | |
909 /* Close Emacs's descriptors that this process should not have. */ | |
910 close_process_descs (); | |
911 #endif /* not NO_SUBPROCESSES */ | |
912 close_load_descs (); | |
913 | |
914 /* [[Note that use of alloca is always safe here. It's obvious for systems | |
915 that do not have true vfork or that have true (stack) alloca. | |
916 If using vfork and C_ALLOCA it is safe because that changes | |
917 the superior's static variables as if the superior had done alloca | |
918 and will be cleaned up in the usual way.]] -- irrelevant because | |
919 XEmacs does not use vfork. */ | |
920 { | |
921 REGISTER Bytecount i; | |
922 | |
923 i = XSTRING_LENGTH (current_dir); | |
924 pwd = alloca_array (Intbyte, i + 6); | |
925 memcpy (pwd, "PWD=", 4); | |
926 memcpy (pwd + 4, XSTRING_DATA (current_dir), i); | |
927 i += 4; | |
928 if (!IS_DIRECTORY_SEP (pwd[i - 1])) | |
929 pwd[i++] = DIRECTORY_SEP; | |
930 pwd[i] = 0; | |
931 | |
932 /* [[We can't signal an Elisp error here; we're in a vfork. Since | |
933 the callers check the current directory before forking, this | |
934 should only return an error if the directory's permissions | |
935 are changed between the check and this chdir, but we should | |
936 at least check.]] -- irrelevant because XEmacs does not use vfork. */ | |
937 if (qxe_chdir (pwd + 4) < 0) | |
938 { | |
939 /* Don't report the chdir error, or ange-ftp.el doesn't work. */ | |
940 /* (FSFmacs does _exit (errno) here.) */ | |
941 pwd = 0; | |
942 } | |
943 else | |
944 { | |
945 /* Strip trailing "/". Cretinous *[]&@$#^%@#$% Un*x */ | |
946 /* leave "//" (from FSF) */ | |
947 while (i > 6 && IS_DIRECTORY_SEP (pwd[i - 1])) | |
948 pwd[--i] = 0; | |
949 } | |
950 } | |
951 | |
952 /* Set `env' to a vector of the strings in Vprocess_environment. */ | |
953 /* + 2 to include PWD and terminating 0. */ | |
954 env = alloca_array (Intbyte *, XINT (Flength (Vprocess_environment)) + 2); | |
955 { | |
956 REGISTER Lisp_Object tail; | |
957 Intbyte **new_env = env; | |
958 | |
959 /* If we have a PWD envvar and we know the real current directory, | |
960 pass one down, but with corrected value. */ | |
961 if (pwd && egetenv ("PWD")) | |
962 *new_env++ = pwd; | |
963 | |
964 /* Copy the Vprocess_environment strings into new_env. */ | |
965 for (tail = Vprocess_environment; | |
966 CONSP (tail) && STRINGP (XCAR (tail)); | |
967 tail = XCDR (tail)) | |
968 { | |
969 Intbyte **ep = env; | |
970 Intbyte *envvar = XSTRING_DATA (XCAR (tail)); | |
971 | |
972 /* See if envvar duplicates any string already in the env. | |
973 If so, don't put it in. | |
974 When an env var has multiple definitions, | |
975 we keep the definition that comes first in process-environment. */ | |
976 for (; ep != new_env; ep++) | |
977 { | |
978 Intbyte *p = *ep, *q = envvar; | |
979 while (1) | |
980 { | |
981 if (*q == 0) | |
982 /* The string is malformed; might as well drop it. */ | |
983 goto duplicate; | |
984 if (*q != *p) | |
985 break; | |
986 if (*q == '=') | |
987 goto duplicate; | |
988 p++, q++; | |
989 } | |
990 } | |
991 if (pwd && !qxestrncmp ((Intbyte *) "PWD=", envvar, 4)) | |
992 { | |
993 *new_env++ = pwd; | |
994 pwd = 0; | |
995 } | |
996 else | |
997 *new_env++ = envvar; | |
998 | |
999 duplicate: ; | |
1000 } | |
1001 | |
1002 *new_env = 0; | |
1003 } | |
1004 | |
1005 /* Make sure that in, out, and err are not actually already in | |
1006 descriptors zero, one, or two; this could happen if Emacs is | |
1007 started with its standard in, out, or error closed, as might | |
1008 happen under X. */ | |
1009 in = relocate_fd (in, 3); | |
1010 out = relocate_fd (out, 3); | |
1011 err = relocate_fd (err, 3); | |
1012 | |
1013 /* Set the standard input/output channels of the new process. */ | |
1014 retry_close (STDIN_FILENO); | |
1015 retry_close (STDOUT_FILENO); | |
1016 retry_close (STDERR_FILENO); | |
1017 | |
1018 dup2 (in, STDIN_FILENO); | |
1019 dup2 (out, STDOUT_FILENO); | |
1020 dup2 (err, STDERR_FILENO); | |
1021 | |
1022 retry_close (in); | |
1023 retry_close (out); | |
1024 retry_close (err); | |
1025 | |
1026 /* I can't think of any reason why child processes need any more | |
1027 than the standard 3 file descriptors. It would be cleaner to | |
1028 close just the ones that need to be, but the following brute | |
1029 force approach is certainly effective, and not too slow. | |
1030 | |
1031 #### Who the hell added this? We already close the descriptors | |
1032 by using close_process_descs()!!! --ben */ | |
1033 { | |
1034 int fd; | |
1035 for (fd = 3; fd <= 64; fd++) | |
1036 retry_close (fd); | |
1037 } | |
1038 | |
1039 /* we've wrapped execve; it translates its arguments */ | |
1040 qxe_execve (new_argv[0], new_argv, env); | |
1041 | |
1042 stdout_out ("Can't exec program %s\n", new_argv[0]); | |
1043 _exit (1); | |
849 } | 1044 } |
850 | 1045 |
851 /* | 1046 /* |
852 * Fork off a subprocess. P is a pointer to a newly created subprocess | 1047 * Fork off a subprocess. P is a pointer to a newly created subprocess |
853 * object. If this function signals, the caller is responsible for | 1048 * object. If this function signals, the caller is responsible for |
859 */ | 1054 */ |
860 | 1055 |
861 static int | 1056 static int |
862 unix_create_process (Lisp_Process *p, | 1057 unix_create_process (Lisp_Process *p, |
863 Lisp_Object *argv, int nargv, | 1058 Lisp_Object *argv, int nargv, |
864 Lisp_Object program, Lisp_Object cur_dir) | 1059 Lisp_Object program, Lisp_Object cur_dir, |
1060 int separate_err) | |
865 { | 1061 { |
866 int pid; | 1062 int pid; |
867 int inchannel = -1; | 1063 int inchannel = -1; |
868 int outchannel = -1; | 1064 int outchannel = -1; |
1065 int errchannel = -1; | |
869 /* Use volatile to protect variables from being clobbered by longjmp. */ | 1066 /* Use volatile to protect variables from being clobbered by longjmp. */ |
870 volatile int forkin = -1; | 1067 volatile int forkin = -1; |
871 volatile int forkout = -1; | 1068 volatile int forkout = -1; |
1069 volatile int forkerr = -1; | |
872 volatile int pty_flag = 0; | 1070 volatile int pty_flag = 0; |
873 | 1071 |
874 if (!NILP (Vprocess_connection_type)) | 1072 if (!NILP (Vprocess_connection_type)) |
875 { | 1073 { |
876 /* find a new pty, open the master side, return the opened | 1074 /* find a new pty, open the master side, return the opened |
885 On some systems, we can open it here; this allows for | 1083 On some systems, we can open it here; this allows for |
886 better error checking. */ | 1084 better error checking. */ |
887 #if !defined(USG) | 1085 #if !defined(USG) |
888 /* On USG systems it does not work to open the pty's tty here | 1086 /* On USG systems it does not work to open the pty's tty here |
889 and then close and reopen it in the child. */ | 1087 and then close and reopen it in the child. */ |
890 #ifdef O_NOCTTY | 1088 # ifdef O_NOCTTY |
891 /* Don't let this terminal become our controlling terminal | 1089 /* Don't let this terminal become our controlling terminal |
892 (in case we don't have one). */ | 1090 (in case we don't have one). */ |
893 forkout = forkin = qxe_open (pty_name, | 1091 forkout = forkin = qxe_open (pty_name, |
894 O_RDWR | O_NOCTTY | OPEN_BINARY, 0); | 1092 O_RDWR | O_NOCTTY | OPEN_BINARY, 0); |
895 #else | 1093 # else |
896 forkout = forkin = qxe_open (pty_name, O_RDWR | OPEN_BINARY, 0); | 1094 forkout = forkin = qxe_open (pty_name, O_RDWR | OPEN_BINARY, 0); |
897 #endif | 1095 # endif |
898 if (forkin < 0) | 1096 if (forkin < 0) |
899 goto io_failure; | 1097 goto io_failure; |
900 #endif /* not USG */ | 1098 #endif /* not USG */ |
901 UNIX_DATA(p)->pty_flag = pty_flag = 1; | 1099 UNIX_DATA (p)->pty_flag = pty_flag = 1; |
902 } | 1100 } |
903 else | 1101 else |
904 if (create_bidirectional_pipe (&inchannel, &outchannel, | 1102 if (create_bidirectional_pipe (&inchannel, &outchannel, |
905 &forkin, &forkout) < 0) | 1103 &forkin, &forkout) < 0) |
906 goto io_failure; | 1104 goto io_failure; |
907 | 1105 |
1106 if (separate_err) | |
1107 { | |
1108 int sv[2]; | |
1109 | |
1110 if (pipe (sv) < 0) | |
1111 goto io_failure; | |
1112 forkerr = sv[1]; | |
1113 errchannel = sv[0]; | |
1114 } | |
1115 | |
908 #if 0 | 1116 #if 0 |
909 /* Replaced by close_process_descs */ | 1117 /* Replaced by close_process_descs */ |
910 set_exclusive_use (inchannel); | 1118 set_exclusive_use (inchannel); |
911 set_exclusive_use (outchannel); | 1119 set_exclusive_use (outchannel); |
912 #endif | 1120 #endif |
913 | 1121 |
914 set_descriptor_non_blocking (inchannel); | 1122 set_descriptor_non_blocking (inchannel); |
1123 if (errchannel >= 0) | |
1124 set_descriptor_non_blocking (errchannel); | |
915 | 1125 |
916 /* Record this as an active process, with its channels. | 1126 /* Record this as an active process, with its channels. |
917 As a result, child_setup will close Emacs's side of the pipes. */ | 1127 As a result, child_setup will close Emacs's side of the pipes. */ |
918 init_process_io_handles (p, (void*)inchannel, (void*)outchannel, | 1128 init_process_io_handles (p, (void *) inchannel, (void *) outchannel, |
1129 (void *) errchannel, | |
919 pty_flag ? STREAM_PTY_FLUSHING : 0); | 1130 pty_flag ? STREAM_PTY_FLUSHING : 0); |
920 /* Record the tty descriptor used in the subprocess. */ | 1131 /* Record the tty descriptor used in the subprocess. */ |
921 UNIX_DATA(p)->subtty = forkin; | 1132 UNIX_DATA (p)->subtty = forkin; |
922 | 1133 |
923 { | 1134 { |
924 pid = fork (); | 1135 pid = fork (); |
925 if (pid == 0) | 1136 if (pid == 0) |
926 { | 1137 { |
927 /**** Now we're in the child process ****/ | 1138 /**** Now we're in the child process ****/ |
928 int xforkin = forkin; | 1139 int xforkin = forkin; |
929 int xforkout = forkout; | 1140 int xforkout = forkout; |
1141 int xforkerr = forkerr; | |
930 | 1142 |
931 /* Disconnect the current controlling terminal, pursuant to | 1143 /* Disconnect the current controlling terminal, pursuant to |
932 making the pty be the controlling terminal of the process. | 1144 making the pty be the controlling terminal of the process. |
933 Also put us in our own process group. */ | 1145 Also put us in our own process group. */ |
934 | 1146 |
965 I deleted it. So sue me. */ | 1177 I deleted it. So sue me. */ |
966 | 1178 |
967 /* SunOS has TIOCSCTTY but the close/open method | 1179 /* SunOS has TIOCSCTTY but the close/open method |
968 also works. */ | 1180 also works. */ |
969 | 1181 |
970 # if defined (USG) || !defined (TIOCSCTTY) | 1182 #if defined (USG) || !defined (TIOCSCTTY) |
971 /* Now close the pty (if we had it open) and reopen it. | 1183 /* Now close the pty (if we had it open) and reopen it. |
972 This makes the pty the controlling terminal of the | 1184 This makes the pty the controlling terminal of the |
973 subprocess. */ | 1185 subprocess. */ |
974 /* I wonder if retry_close (qxe_open (pty_name, ...)) would work? */ | 1186 /* I wonder if retry_close (qxe_open (pty_name, ...)) would |
1187 work? */ | |
975 if (xforkin >= 0) | 1188 if (xforkin >= 0) |
976 retry_close (xforkin); | 1189 retry_close (xforkin); |
977 xforkout = xforkin = qxe_open (pty_name, O_RDWR | OPEN_BINARY, 0); | 1190 xforkout = xforkin = qxe_open (pty_name, O_RDWR | OPEN_BINARY, 0); |
978 if (xforkin < 0) | 1191 if (xforkin < 0) |
979 { | 1192 { |
980 retry_write (1, "Couldn't open the pty terminal ", 31); | 1193 retry_write (1, "Couldn't open the pty terminal ", 31); |
981 retry_write (1, pty_name, qxestrlen (pty_name)); | 1194 retry_write (1, pty_name, qxestrlen (pty_name)); |
982 retry_write (1, "\n", 1); | 1195 retry_write (1, "\n", 1); |
983 _exit (1); | 1196 _exit (1); |
984 } | 1197 } |
985 # endif /* USG or not TIOCSCTTY */ | 1198 #endif /* USG or not TIOCSCTTY */ |
986 | 1199 |
987 /* Miscellaneous setup required for some systems. | 1200 /* Miscellaneous setup required for some systems. |
988 Must be done before using tc* functions on xforkin. | 1201 Must be done before using tc* functions on xforkin. |
989 This guarantees that isatty(xforkin) is true. */ | 1202 This guarantees that isatty(xforkin) is true. */ |
990 | 1203 |
991 # if defined (HAVE_ISASTREAM) && defined (I_PUSH) | 1204 #if defined (HAVE_ISASTREAM) && defined (I_PUSH) |
992 if (isastream (xforkin)) | 1205 if (isastream (xforkin)) |
993 { | 1206 { |
994 # if defined (I_FIND) | 1207 # if defined (I_FIND) |
995 # define stream_module_pushed(fd, module) (ioctl (fd, I_FIND, module) == 1) | 1208 # define stream_module_pushed(fd, module) (ioctl (fd, I_FIND, module) == 1) |
996 # else | 1209 # else |
997 # define stream_module_pushed(fd, module) 0 | 1210 # define stream_module_pushed(fd, module) 0 |
998 # endif | 1211 # endif |
999 if (! stream_module_pushed (xforkin, "ptem")) | 1212 if (! stream_module_pushed (xforkin, "ptem")) |
1000 ioctl (xforkin, I_PUSH, "ptem"); | 1213 ioctl (xforkin, I_PUSH, "ptem"); |
1001 if (! stream_module_pushed (xforkin, "ldterm")) | 1214 if (! stream_module_pushed (xforkin, "ldterm")) |
1002 ioctl (xforkin, I_PUSH, "ldterm"); | 1215 ioctl (xforkin, I_PUSH, "ldterm"); |
1003 if (! stream_module_pushed (xforkin, "ttcompat")) | 1216 if (! stream_module_pushed (xforkin, "ttcompat")) |
1004 ioctl (xforkin, I_PUSH, "ttcompat"); | 1217 ioctl (xforkin, I_PUSH, "ttcompat"); |
1005 } | 1218 } |
1006 # endif /* HAVE_ISASTREAM */ | 1219 #endif /* defined (HAVE_ISASTREAM) && defined (I_PUSH) */ |
1007 | 1220 |
1008 # ifdef TIOCSCTTY | 1221 #ifdef TIOCSCTTY |
1009 /* We ignore the return value | 1222 /* We ignore the return value |
1010 because faith@cs.unc.edu says that is necessary on Linux. */ | 1223 because faith@cs.unc.edu says that is necessary on Linux. */ |
1011 assert (isatty (xforkin)); | 1224 assert (isatty (xforkin)); |
1012 ioctl (xforkin, TIOCSCTTY, 0); | 1225 ioctl (xforkin, TIOCSCTTY, 0); |
1013 # endif /* TIOCSCTTY */ | 1226 #endif /* TIOCSCTTY */ |
1014 | 1227 |
1015 /* Change the line discipline. */ | 1228 /* Change the line discipline. */ |
1016 | 1229 |
1017 # if defined (HAVE_TERMIOS) && defined (LDISC1) | 1230 #if defined (HAVE_TERMIOS) && defined (LDISC1) |
1018 { | 1231 { |
1019 struct termios t; | 1232 struct termios t; |
1020 assert (isatty (xforkin)); | 1233 assert (isatty (xforkin)); |
1021 tcgetattr (xforkin, &t); | 1234 tcgetattr (xforkin, &t); |
1022 t.c_lflag = LDISC1; | 1235 t.c_lflag = LDISC1; |
1023 if (tcsetattr (xforkin, TCSANOW, &t) < 0) | 1236 if (tcsetattr (xforkin, TCSANOW, &t) < 0) |
1024 perror ("create_process/tcsetattr LDISC1 failed\n"); | 1237 perror ("create_process/tcsetattr LDISC1 failed\n"); |
1025 } | 1238 } |
1026 # elif defined (NTTYDISC) && defined (TIOCSETD) | 1239 #elif defined (NTTYDISC) && defined (TIOCSETD) |
1027 { | 1240 { |
1028 /* Use new line discipline. TIOCSETD is accepted and | 1241 /* Use new line discipline. TIOCSETD is accepted and |
1029 ignored on Sys5.4 systems with ttcompat. */ | 1242 ignored on Sys5.4 systems with ttcompat. */ |
1030 int ldisc = NTTYDISC; | 1243 int ldisc = NTTYDISC; |
1031 assert (isatty (xforkin)); | 1244 assert (isatty (xforkin)); |
1032 ioctl (xforkin, TIOCSETD, &ldisc); | 1245 ioctl (xforkin, TIOCSETD, &ldisc); |
1033 } | 1246 } |
1034 # endif /* TIOCSETD & NTTYDISC */ | 1247 #endif /* TIOCSETD & NTTYDISC */ |
1035 | 1248 |
1036 /* Make our process group be the foreground group | 1249 /* Make our process group be the foreground group |
1037 of our new controlling terminal. */ | 1250 of our new controlling terminal. */ |
1038 | 1251 |
1039 { | 1252 { |
1069 CHECK_STRING (argv[i]); | 1282 CHECK_STRING (argv[i]); |
1070 new_argv[i + 1] = XSTRING_DATA (argv[i]); | 1283 new_argv[i + 1] = XSTRING_DATA (argv[i]); |
1071 } | 1284 } |
1072 new_argv[i + 1] = 0; | 1285 new_argv[i + 1] = 0; |
1073 | 1286 |
1074 child_setup (xforkin, xforkout, xforkout, new_argv, cur_dir); | 1287 child_setup (xforkin, xforkout, separate_err ? xforkerr : xforkout, |
1288 new_argv, cur_dir); | |
1075 } | 1289 } |
1076 | 1290 |
1077 } /**** End of child code ****/ | 1291 } /**** End of child code ****/ |
1078 | 1292 |
1079 /**** Back in parent process ****/ | 1293 /**** Back in parent process ****/ |
1080 } | 1294 } |
1081 | 1295 |
1082 if (pid < 0) | 1296 if (pid < 0) |
1083 { | 1297 { |
1298 /* Note: The caller set up an unwind-protect to automatically delete | |
1299 the process if we fail. This will correctly deselect and close | |
1300 inchannel, outchannel, and errchannel. */ | |
1084 int save_errno = errno; | 1301 int save_errno = errno; |
1085 close_descriptor_pair (forkin, forkout); | 1302 close_descriptor_pair (forkin, forkout); |
1303 if (separate_err) | |
1304 retry_close (forkerr); | |
1086 errno = save_errno; | 1305 errno = save_errno; |
1087 report_process_error ("Doing fork", Qunbound); | 1306 report_process_error ("Doing fork", Qunbound); |
1088 } | 1307 } |
1089 | 1308 |
1090 /* #### dmoore - why is this commented out, otherwise we leave | 1309 /* #### dmoore - why is this commented out, otherwise we leave |
1091 subtty = forkin, but then we close forkin just below. */ | 1310 subtty = forkin, but then we close forkin just below. */ |
1092 /* UNIX_DATA(p)->subtty = -1; */ | 1311 /* UNIX_DATA (p)->subtty = -1; */ |
1093 | 1312 |
1094 /* If the subfork execv fails, and it exits, | 1313 /* If the subfork execv fails, and it exits, |
1095 this close hangs. I don't know why. | 1314 this close hangs. I don't know why. |
1096 So have an interrupt jar it loose. */ | 1315 So have an interrupt jar it loose. */ |
1097 if (forkin >= 0) | 1316 if (forkin >= 0) |
1098 close_safely (forkin); | 1317 close_safely (forkin); |
1099 if (forkin != forkout && forkout >= 0) | 1318 if (forkin != forkout && forkout >= 0) |
1100 retry_close (forkout); | 1319 retry_close (forkout); |
1320 if (separate_err) | |
1321 retry_close (forkerr); | |
1101 | 1322 |
1102 UNIX_DATA (p)->tty_name = pty_flag ? build_intstring (pty_name) : Qnil; | 1323 UNIX_DATA (p)->tty_name = pty_flag ? build_intstring (pty_name) : Qnil; |
1103 | 1324 |
1104 /* Notice that SIGCHLD was not blocked. (This is not possible on | 1325 /* Notice that SIGCHLD was not blocked. (This is not possible on |
1105 some systems.) No biggie if SIGCHLD occurs right around the | 1326 some systems.) No biggie if SIGCHLD occurs right around the |
1106 time that this call happens, because SIGCHLD() does not actually | 1327 time that this call happens, because SIGCHLD() does not actually |
1107 deselect the process (that doesn't occur until the next time | 1328 deselect the process (that doesn't occur until the next time |
1108 we're waiting for an event, when status_notify() is called). */ | 1329 we're waiting for an event, when status_notify() is called). */ |
1109 return pid; | 1330 return pid; |
1110 | 1331 |
1111 io_failure: | 1332 io_failure: |
1112 { | 1333 { |
1113 int save_errno = errno; | 1334 int save_errno = errno; |
1114 close_descriptor_pair (forkin, forkout); | 1335 close_descriptor_pair (forkin, forkout); |
1115 close_descriptor_pair (inchannel, outchannel); | 1336 close_descriptor_pair (inchannel, outchannel); |
1337 close_descriptor_pair (forkerr, errchannel); | |
1116 errno = save_errno; | 1338 errno = save_errno; |
1117 report_process_error ("Opening pty or pipe", Qunbound); | 1339 report_process_error ("Opening pty or pipe", Qunbound); |
1118 RETURN_NOT_REACHED (0) | 1340 RETURN_NOT_REACHED (0) |
1119 } | 1341 } |
1120 } | 1342 } |
1122 /* Return nonzero if this process is a ToolTalk connection. */ | 1344 /* Return nonzero if this process is a ToolTalk connection. */ |
1123 | 1345 |
1124 static int | 1346 static int |
1125 unix_tooltalk_connection_p (Lisp_Process *p) | 1347 unix_tooltalk_connection_p (Lisp_Process *p) |
1126 { | 1348 { |
1127 return UNIX_DATA(p)->connected_via_filedesc_p; | 1349 return UNIX_DATA (p)->connected_via_filedesc_p; |
1128 } | 1350 } |
1129 | 1351 |
1130 /* This is called to set process' virtual terminal size */ | 1352 /* This is called to set process' virtual terminal size */ |
1131 | 1353 |
1132 static int | 1354 static int |
1133 unix_set_window_size (Lisp_Process* p, int cols, int rows) | 1355 unix_set_window_size (Lisp_Process *p, int cols, int rows) |
1134 { | 1356 { |
1135 return set_window_size (UNIX_DATA(p)->infd, cols, rows); | 1357 return set_window_size (UNIX_DATA (p)->infd, cols, rows); |
1136 } | 1358 } |
1137 | 1359 |
1138 /* | 1360 /* |
1139 * This method is called to update status fields of the process | 1361 * This method is called to update status fields of the process |
1140 * structure. If the process has not existed, this method is | 1362 * structure. If the process has not existed, this method is |
1143 * The method is called only for real child processes. | 1365 * The method is called only for real child processes. |
1144 */ | 1366 */ |
1145 | 1367 |
1146 #ifdef HAVE_WAITPID | 1368 #ifdef HAVE_WAITPID |
1147 static void | 1369 static void |
1148 unix_update_status_if_terminated (Lisp_Process* p) | 1370 unix_update_status_if_terminated (Lisp_Process *p) |
1149 { | 1371 { |
1150 int w; | 1372 int w; |
1151 #ifdef SIGCHLD | 1373 #ifdef SIGCHLD |
1152 EMACS_BLOCK_SIGNAL (SIGCHLD); | 1374 EMACS_BLOCK_SIGNAL (SIGCHLD); |
1153 #endif | 1375 #endif |
1180 if (exited_processes_index <= 0) | 1402 if (exited_processes_index <= 0) |
1181 { | 1403 { |
1182 return; | 1404 return; |
1183 } | 1405 } |
1184 | 1406 |
1185 #ifdef EMACS_BLOCK_SIGNAL | 1407 #ifdef EMACS_BLOCK_SIGNAL |
1186 EMACS_BLOCK_SIGNAL (SIGCHLD); | 1408 EMACS_BLOCK_SIGNAL (SIGCHLD); |
1187 #endif | 1409 #endif |
1188 for (i = 0; i < exited_processes_index; i++) | 1410 for (i = 0; i < exited_processes_index; i++) |
1189 { | 1411 { |
1190 int pid = exited_processes[i]; | 1412 int pid = exited_processes[i]; |
1213 update_status_from_wait_code (p, &w); | 1435 update_status_from_wait_code (p, &w); |
1214 | 1436 |
1215 /* If process has terminated, stop waiting for its output. */ | 1437 /* If process has terminated, stop waiting for its output. */ |
1216 if (WIFSIGNALED (w) || WIFEXITED (w)) | 1438 if (WIFSIGNALED (w) || WIFEXITED (w)) |
1217 { | 1439 { |
1218 if (!NILP(p->pipe_instream)) | 1440 if (!NILP (p->pipe_instream)) |
1219 { | 1441 { |
1220 /* We can't just call event_stream->unselect_process_cb (p) | 1442 /* We can't just call event_stream->unselect_process_cb (p) |
1221 here, because that calls XtRemoveInput, which is not | 1443 here, because that calls XtRemoveInput, which is not |
1222 necessarily reentrant, so we can't call this at interrupt | 1444 necessarily reentrant, so we can't call this at interrupt |
1223 level. | 1445 level. |
1224 */ | 1446 */ |
1225 } | 1447 } |
1226 } | 1448 } |
1227 } | 1449 } |
1450 #ifdef NEED_SYNC_PROCESS_CODE | |
1228 else | 1451 else |
1229 { | 1452 { |
1230 /* There was no asynchronous process found for that id. Check | 1453 /* There was no asynchronous process found for that id. Check |
1231 if we have a synchronous process. Only set sync process status | 1454 if we have a synchronous process. Only set sync process status |
1232 if there is one, so we work OK with the waitpid() call in | 1455 if there is one, so we work OK with the waitpid() call in |
1240 synch_process_retcode = WEXITSTATUS (w); | 1463 synch_process_retcode = WEXITSTATUS (w); |
1241 else if (WIFSIGNALED (w)) | 1464 else if (WIFSIGNALED (w)) |
1242 synch_process_death = signal_name (WTERMSIG (w)); | 1465 synch_process_death = signal_name (WTERMSIG (w)); |
1243 } | 1466 } |
1244 } | 1467 } |
1468 #endif /* NEED_SYNC_PROCESS_CODE */ | |
1245 } | 1469 } |
1246 | 1470 |
1247 exited_processes_index = 0; | 1471 exited_processes_index = 0; |
1248 | 1472 |
1249 EMACS_UNBLOCK_SIGNAL (SIGCHLD); | 1473 EMACS_UNBLOCK_SIGNAL (SIGCHLD); |
1263 EMACS_UNBLOCK_SIGNAL (signum); | 1487 EMACS_UNBLOCK_SIGNAL (signum); |
1264 LONGJMP (send_process_frame, 1); | 1488 LONGJMP (send_process_frame, 1); |
1265 } | 1489 } |
1266 | 1490 |
1267 static void | 1491 static void |
1268 unix_send_process (Lisp_Object proc, struct lstream* lstream) | 1492 unix_send_process (Lisp_Object proc, struct lstream *lstream) |
1269 { | 1493 { |
1270 /* Use volatile to protect variables from being clobbered by longjmp. */ | 1494 /* Use volatile to protect variables from being clobbered by longjmp. */ |
1271 SIGTYPE (*volatile old_sigpipe) (int) = 0; | 1495 SIGTYPE (*volatile old_sigpipe) (int) = 0; |
1272 volatile Lisp_Object vol_proc = proc; | 1496 volatile Lisp_Object vol_proc = proc; |
1273 Lisp_Process *volatile p = XPROCESS (proc); | 1497 Lisp_Process *volatile p = XPROCESS (proc); |
1379 * Called before the process is deactivated. The process object | 1603 * Called before the process is deactivated. The process object |
1380 * is not immediately finalized, just undergoes a transition to | 1604 * is not immediately finalized, just undergoes a transition to |
1381 * inactive state. | 1605 * inactive state. |
1382 * | 1606 * |
1383 * The return value is a unique stream ID, as returned by | 1607 * The return value is a unique stream ID, as returned by |
1384 * event_stream_delete_stream_pair | 1608 * event_stream_delete_io_streams |
1385 * | 1609 * |
1386 * In the lack of this method, only event_stream_delete_stream_pair | 1610 * In the lack of this method, only event_stream_delete_io_streams |
1387 * is called on both I/O streams of the process. | 1611 * is called on both I/O streams of the process. |
1388 * | 1612 * |
1389 * The UNIX version guards this by ignoring possible SIGPIPE. | 1613 * The UNIX version guards this by ignoring possible SIGPIPE. |
1390 */ | 1614 */ |
1391 | 1615 |
1392 static USID | 1616 static void |
1393 unix_deactivate_process (Lisp_Process *p) | 1617 unix_deactivate_process (Lisp_Process *p, |
1618 USID *in_usid, | |
1619 USID *err_usid) | |
1394 { | 1620 { |
1395 SIGTYPE (*old_sigpipe) (int) = 0; | 1621 SIGTYPE (*old_sigpipe) (int) = 0; |
1396 USID usid; | |
1397 | 1622 |
1398 if (UNIX_DATA(p)->infd >= 0) | 1623 if (UNIX_DATA(p)->infd >= 0) |
1399 flush_pending_output (UNIX_DATA(p)->infd); | 1624 flush_pending_output (UNIX_DATA(p)->infd); |
1625 if (UNIX_DATA(p)->errfd >= 0) | |
1626 flush_pending_output (UNIX_DATA(p)->errfd); | |
1400 | 1627 |
1401 /* closing the outstream could result in SIGPIPE, so ignore it. */ | 1628 /* closing the outstream could result in SIGPIPE, so ignore it. */ |
1402 old_sigpipe = (SIGTYPE (*) (int)) EMACS_SIGNAL (SIGPIPE, SIG_IGN); | 1629 old_sigpipe = (SIGTYPE (*) (int)) EMACS_SIGNAL (SIGPIPE, SIG_IGN); |
1403 usid = event_stream_delete_stream_pair (p->pipe_instream, p->pipe_outstream); | 1630 event_stream_delete_io_streams (p->pipe_instream, p->pipe_outstream, |
1631 p->pipe_errstream, in_usid, err_usid); | |
1404 EMACS_SIGNAL (SIGPIPE, old_sigpipe); | 1632 EMACS_SIGNAL (SIGPIPE, old_sigpipe); |
1405 | 1633 |
1406 UNIX_DATA(p)->infd = -1; | 1634 UNIX_DATA(p)->infd = -1; |
1407 | 1635 UNIX_DATA(p)->errfd = -1; |
1408 return usid; | |
1409 } | 1636 } |
1410 | 1637 |
1411 /* If the subtty field of the process data is not filled in, do so now. */ | 1638 /* If the subtty field of the process data is not filled in, do so now. */ |
1412 static void | 1639 static void |
1413 try_to_initialize_subtty (struct unix_process_data *upd) | 1640 try_to_initialize_subtty (struct unix_process_data *upd) |
1454 #endif /* ! defined (SIGCONT) */ | 1681 #endif /* ! defined (SIGCONT) */ |
1455 case SIGINT: | 1682 case SIGINT: |
1456 case SIGQUIT: | 1683 case SIGQUIT: |
1457 case SIGKILL: | 1684 case SIGKILL: |
1458 flush_pending_output (d->infd); | 1685 flush_pending_output (d->infd); |
1686 flush_pending_output (d->errfd); | |
1459 break; | 1687 break; |
1460 } | 1688 } |
1461 | 1689 |
1462 if (! d->pty_flag) | 1690 if (! d->pty_flag) |
1463 current_group = 0; | 1691 current_group = 0; |
1502 | 1730 |
1503 #ifdef SIGNALS_VIA_CHARACTERS | 1731 #ifdef SIGNALS_VIA_CHARACTERS |
1504 /* If possible, send signals to the entire pgrp | 1732 /* If possible, send signals to the entire pgrp |
1505 by sending an input character to it. */ | 1733 by sending an input character to it. */ |
1506 { | 1734 { |
1507 char sigchar = process_signal_char (d->subtty, signo); | 1735 Intbyte sigchar = process_signal_char (d->subtty, signo); |
1508 if (sigchar) | 1736 if (sigchar) |
1509 { | 1737 { |
1510 send_process (proc, Qnil, (Intbyte *) &sigchar, 0, 1); | 1738 send_process (proc, Qnil, &sigchar, 0, 1); |
1511 return; | 1739 return; |
1512 } | 1740 } |
1513 } | 1741 } |
1514 #endif /* SIGNALS_VIA_CHARACTERS */ | 1742 #endif /* SIGNALS_VIA_CHARACTERS */ |
1515 | 1743 |
1783 if (QUITP) | 2011 if (QUITP) |
1784 { | 2012 { |
1785 #ifdef CONNECT_NEEDS_SLOWED_INTERRUPTS | 2013 #ifdef CONNECT_NEEDS_SLOWED_INTERRUPTS |
1786 speed_up_interrupts (); | 2014 speed_up_interrupts (); |
1787 #endif | 2015 #endif |
1788 REALLY_QUIT; | 2016 QUIT; |
1789 /* In case something really weird happens ... */ | 2017 /* In case something really weird happens ... */ |
1790 #ifdef CONNECT_NEEDS_SLOWED_INTERRUPTS | 2018 #ifdef CONNECT_NEEDS_SLOWED_INTERRUPTS |
1791 slow_down_interrupts (); | 2019 slow_down_interrupts (); |
1792 #endif | 2020 #endif |
1793 } | 2021 } |
1918 important issue. | 2146 important issue. |
1919 */ | 2147 */ |
1920 | 2148 |
1921 static void | 2149 static void |
1922 unix_open_multicast_group (Lisp_Object name, Lisp_Object dest, | 2150 unix_open_multicast_group (Lisp_Object name, Lisp_Object dest, |
1923 Lisp_Object port, Lisp_Object ttl, void** vinfd, | 2151 Lisp_Object port, Lisp_Object ttl, void **vinfd, |
1924 void** voutfd) | 2152 void **voutfd) |
1925 { | 2153 { |
1926 struct ip_mreq imr; | 2154 struct ip_mreq imr; |
1927 struct sockaddr_in sa; | 2155 struct sockaddr_in sa; |
1928 struct protoent *udp; | 2156 struct protoent *udp; |
1929 int ws, rs; | 2157 int ws, rs; |
2015 if (QUITP) | 2243 if (QUITP) |
2016 { | 2244 { |
2017 #ifdef CONNECT_NEEDS_SLOWED_INTERRUPTS | 2245 #ifdef CONNECT_NEEDS_SLOWED_INTERRUPTS |
2018 speed_up_interrupts (); | 2246 speed_up_interrupts (); |
2019 #endif | 2247 #endif |
2020 REALLY_QUIT; | 2248 QUIT; |
2021 /* In case something really weird happens ... */ | 2249 /* In case something really weird happens ... */ |
2022 #ifdef CONNECT_NEEDS_SLOWED_INTERRUPTS | 2250 #ifdef CONNECT_NEEDS_SLOWED_INTERRUPTS |
2023 slow_down_interrupts (); | 2251 slow_down_interrupts (); |
2024 #endif | 2252 #endif |
2025 } | 2253 } |