X-Git-Url: http://git.chise.org/gitweb/?a=blobdiff_plain;f=src%2Fprocess-unix.c;h=05b50463890c349935cec1a0b5f08f5ba9307b86;hb=e47e95aae354b619b35d5770cc67ca8ec0fe56ad;hp=c0d1989f9a6ca2811e98025200402f6f621d9ed9;hpb=21db8709c0c2dcedbd278c7fe571290d5ce80a71;p=chise%2Fxemacs-chise.git.1 diff --git a/src/process-unix.c b/src/process-unix.c index c0d1989..05b5046 100644 --- a/src/process-unix.c +++ b/src/process-unix.c @@ -892,6 +892,7 @@ unix_create_process (Lisp_Process *p, #endif set_descriptor_non_blocking (inchannel); + set_descriptor_non_blocking (outchannel); /* Record this as an active process, with its channels. As a result, child_setup will close Emacs's side of the pipes. */ @@ -914,6 +915,10 @@ unix_create_process (Lisp_Process *p, int xforkin = forkin; int xforkout = forkout; + /* Checking for quit in the child is bad because that will + cause I/O, and that, in turn, can confuse the X connection. */ + begin_dont_check_for_quit(); + /* Disconnect the current controlling terminal, pursuant to making the pty be the controlling terminal of the process. Also put us in our own process group. */ @@ -1288,26 +1293,38 @@ unix_send_process (Lisp_Object proc, struct lstream* lstream) Bufbyte chunkbuf[512]; Bytecount chunklen; - while (1) + do { Lstream_data_count writeret; chunklen = Lstream_read (lstream, chunkbuf, 512); - if (chunklen <= 0) - break; /* perhaps should abort() if < 0? - This should never happen. */ old_sigpipe = (SIGTYPE (*) (int)) signal (SIGPIPE, send_process_trap); - /* Lstream_write() will never successfully write less than - the amount sent in. In the worst case, it just buffers - the unwritten data. */ - writeret = Lstream_write (XLSTREAM (DATA_OUTSTREAM(p)), chunkbuf, - chunklen); - signal (SIGPIPE, old_sigpipe); - if (writeret < 0) - /* This is a real error. Blocking errors are handled - specially inside of the filedesc stream. */ - report_file_error ("writing to process", list1 (proc)); + if (chunklen > 0) + { + int save_errno; + + /* Lstream_write() will never successfully write less than + the amount sent in. In the worst case, it just buffers + the unwritten data. */ + writeret = Lstream_write (XLSTREAM (DATA_OUTSTREAM(p)), chunkbuf, + chunklen); + save_errno = errno; + signal (SIGPIPE, old_sigpipe); + errno = save_errno; + if (writeret < 0) + /* This is a real error. Blocking errors are handled + specially inside of the filedesc stream. */ + report_file_error ("writing to process", list1 (proc)); + } + else + { + /* Need to make sure that everything up to and including the + last chunk is flushed, even when the pipe is currently + blocked. */ + Lstream_flush (XLSTREAM (DATA_OUTSTREAM(p))); + signal (SIGPIPE, old_sigpipe); + } while (Lstream_was_blocked_p (XLSTREAM (p->pipe_outstream))) { /* Buffer is full. Wait, accepting input; @@ -1322,7 +1339,9 @@ unix_send_process (Lisp_Object proc, struct lstream* lstream) Lstream_flush (XLSTREAM (p->pipe_outstream)); signal (SIGPIPE, old_sigpipe); } + /* Perhaps should abort() if < 0? This should never happen. */ } + while (chunklen > 0); } else { /* We got here from a longjmp() from the SIGPIPE handler */ @@ -1331,6 +1350,9 @@ unix_send_process (Lisp_Object proc, struct lstream* lstream) /* #### There is controversy over whether this might cause fd leakage */ /* my tests say no. -slb */ XLSTREAM (p->pipe_outstream)->flags &= ~LSTREAM_FL_IS_OPEN; +#ifdef FILE_CODING + XLSTREAM (p->coding_outstream)->flags &= ~LSTREAM_FL_IS_OPEN; +#endif p->status_symbol = Qexit; p->exit_code = 256; /* #### SIGPIPE ??? */ p->core_dumped = 0; @@ -1662,13 +1684,13 @@ unix_open_network_stream (Lisp_Object name, Lisp_Object host, Lisp_Object servic volatile int xerrno = 0; volatile int failed_connect = 0; char *ext_host; + char portbuf[sizeof(long)*3 + 2]; /* * Caution: service can either be a string or int. * Convert to a C string for later use by getaddrinfo. */ if (INTP (service)) { - char portbuf[128]; snprintf (portbuf, sizeof (portbuf), "%ld", (long) XINT (service)); portstring = portbuf; port = htons ((unsigned short) XINT (service));