X-Git-Url: http://git.chise.org/gitweb/?a=blobdiff_plain;f=src%2Fprocess-unix.c;h=05b50463890c349935cec1a0b5f08f5ba9307b86;hb=818f224de6694aa92bf9ba77b52c8c8d0dd24999;hp=462fb556641bebfbce92643d039158af5279ef0c;hpb=3062d425fac0473eb5aa2efc0bb002f6ce0cb028;p=chise%2Fxemacs-chise.git.1 diff --git a/src/process-unix.c b/src/process-unix.c index 462fb55..05b5046 100644 --- a/src/process-unix.c +++ b/src/process-unix.c @@ -220,6 +220,7 @@ allocate_pty (void) allocate_pty() tries all the different known easy ways of opening a pty. In case of failure, we resort to the old BSD-style pty grovelling code in allocate_pty_the_old_fashioned_way(). */ +#ifndef FORCE_ALLOCATE_PTY_THE_OLD_FASHIONED_WAY int master_fd = -1; const char *slave_name = NULL; const char *clone = NULL; @@ -342,6 +343,7 @@ allocate_pty (void) lose: if (master_fd >= 0) close (master_fd); +#endif /* ndef FORCE_ALLOCATE_PTY_THE_OLD_FASHIONED_WAY */ return allocate_pty_the_old_fashioned_way (); } @@ -890,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. */ @@ -912,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. */ @@ -1286,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; @@ -1320,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 */ @@ -1329,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; @@ -1587,7 +1611,11 @@ unix_canonicalize_host_name (Lisp_Object host) xzero (hints); hints.ai_flags = AI_CANONNAME; +#ifdef IPV6_CANONICALIZE hints.ai_family = AF_UNSPEC; +#else + hints.ai_family = PF_INET; +#endif hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = 0; LISP_STRING_TO_EXTERNAL (host, ext_host, Qnative); @@ -1656,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)); @@ -1764,6 +1792,7 @@ unix_open_network_stream (Lisp_Object name, Lisp_Object host, Lisp_Object servic failed_connect = 1; close (s); + s = -1; speed_up_interrupts (); @@ -1976,7 +2005,7 @@ unix_open_multicast_group (Lisp_Object name, Lisp_Object dest, memset (&sa, 0, sizeof(sa)); sa.sin_family = AF_INET; sa.sin_port = theport; - sa.sin_addr.s_addr = htonl (inet_addr ((char *) XSTRING_DATA (dest))); + sa.sin_addr.s_addr = inet_addr ((char *) XSTRING_DATA (dest)); /* Socket configuration for reading ------------------------ */ @@ -1996,7 +2025,7 @@ unix_open_multicast_group (Lisp_Object name, Lisp_Object dest, } /* join multicast group */ - imr.imr_multiaddr.s_addr = htonl (inet_addr ((char *) XSTRING_DATA (dest))); + imr.imr_multiaddr.s_addr = inet_addr ((char *) XSTRING_DATA (dest)); imr.imr_interface.s_addr = htonl (INADDR_ANY); if (setsockopt (rs, IPPROTO_IP, IP_ADD_MEMBERSHIP, &imr, sizeof (struct ip_mreq)) < 0)