X-Git-Url: http://git.hcoop.net/bpt/emacs.git/blobdiff_plain/83502605bef92e975139e695792bcb333d80736e..418cd8ca018261799bafe504423cc109ebd58929:/src/process.c diff --git a/src/process.c b/src/process.c index 1b8174299f..17fc467e6d 100644 --- a/src/process.c +++ b/src/process.c @@ -107,6 +107,8 @@ Boston, MA 02111-1307, USA. */ #include "frame.h" #include "blockinput.h" +#define max(a, b) ((a) > (b) ? (a) : (b)) + Lisp_Object Qprocessp; Lisp_Object Qrun, Qstop, Qsignal, Qopen, Qclosed; Lisp_Object Qlast_nonmenu_event; @@ -264,6 +266,8 @@ extern int timers_run; /* Maximum number of bytes to send to a pty without an eof. */ static int pty_max_bytes; +extern Lisp_Object Vfile_name_coding_system; + #ifdef HAVE_PTYS /* The file name of the pty opened by allocate_pty. */ @@ -1085,12 +1089,12 @@ Remaining arguments are strings to give program as arguments.") #ifdef VMS /* Make a one member argv with all args concatenated together separated by a blank. */ - len = XSTRING (program)->size + 2; + len = XSTRING (program)->size_byte + 2; for (i = 3; i < nargs; i++) { tem = args[i]; CHECK_STRING (tem, i); - len += XSTRING (tem)->size + 1; /* count the blank */ + len += XSTRING (tem)->size_byte + 1; /* count the blank */ } new_argv = (unsigned char *) alloca (len); strcpy (new_argv, XSTRING (program)->data); @@ -1155,8 +1159,9 @@ Remaining arguments are strings to give program as arguments.") /* Make the process marker point into the process buffer (if any). */ if (!NILP (buffer)) - Fset_marker (XPROCESS (proc)->mark, - make_number (BUF_ZV (XBUFFER (buffer))), buffer); + set_marker_both (XPROCESS (proc)->mark, buffer, + BUF_ZV (XBUFFER (buffer)), + BUF_ZV_BYTE (XBUFFER (buffer))); if (!NILP (buffer) && NILP (XBUFFER (buffer)->enable_multibyte_characters) || NILP (buffer) && NILP (buffer_defaults.enable_multibyte_characters)) @@ -1167,27 +1172,37 @@ Remaining arguments are strings to give program as arguments.") else { /* Setup coding systems for communicating with the process. */ - /* Qt denotes that we have not yet called Ffind_coding_system. */ + /* Qt denotes we have not yet called Ffind_operation_coding_system. */ Lisp_Object coding_systems = Qt; Lisp_Object val, *args2; struct gcpro gcpro1; - if (NILP (val = Vcoding_system_for_read)) + if (!NILP (Vcoding_system_for_read)) + val = Vcoding_system_for_read; + else if (NILP (current_buffer->enable_multibyte_characters)) + val = Qemacs_mule; + else { args2 = (Lisp_Object *) alloca ((nargs + 1) * sizeof *args2); args2[0] = Qstart_process; for (i = 0; i < nargs; i++) args2[i + 1] = args[i]; GCPRO1 (proc); - coding_systems = Ffind_coding_system (nargs + 1, args2); + coding_systems = Ffind_operation_coding_system (nargs + 1, args2); UNGCPRO; if (CONSP (coding_systems)) val = XCONS (coding_systems)->car; else if (CONSP (Vdefault_process_coding_system)) val = XCONS (Vdefault_process_coding_system)->car; + else + val = Qnil; } XPROCESS (proc)->decode_coding_system = val; - if (NILP (val = Vcoding_system_for_write)) + if (!NILP (Vcoding_system_for_write)) + val = Vcoding_system_for_write; + else if (NILP (current_buffer->enable_multibyte_characters)) + val = Qnil; + else { if (EQ (coding_systems, Qt)) { @@ -1195,13 +1210,16 @@ Remaining arguments are strings to give program as arguments.") args2[0] = Qstart_process; for (i = 0; i < nargs; i++) args2[i + 1] = args[i]; GCPRO1 (proc); - coding_systems = Ffind_coding_system (nargs + 1, args2); + coding_systems = + Ffind_operation_coding_system (nargs + 1, args2); UNGCPRO; } if (CONSP (coding_systems)) val = XCONS (coding_systems)->cdr; else if (CONSP (Vdefault_process_coding_system)) val = XCONS (Vdefault_process_coding_system)->cdr; + else + val = Qnil; } XPROCESS (proc)->encode_coding_system = val; } @@ -1209,7 +1227,7 @@ Remaining arguments are strings to give program as arguments.") XPROCESS (proc)->decoding_buf = make_uninit_string (0); XPROCESS (proc)->encoding_buf = make_uninit_string (0); - create_process (proc, new_argv, current_dir); + create_process (proc, (char **) new_argv, current_dir); return unbind_to (count, proc); } @@ -1264,6 +1282,7 @@ create_process_sigchld () #endif #ifndef VMS /* VMS version of this function is in vmsproc.c. */ +void create_process (process, new_argv, current_dir) Lisp_Object process; char **new_argv; @@ -1382,6 +1401,35 @@ create_process (process, new_argv, current_dir) setup_coding_system (XPROCESS (process)->encode_coding_system, proc_encode_coding_system[outchannel]); + if (CODING_REQUIRE_ENCODING (proc_encode_coding_system[outchannel])) + { + /* Here we encode arguments by the coding system used for + sending data to the process. We don't support using + different coding systems for encoding arguments and for + encoding data sent to the process. */ + struct gcpro gcpro1; + int i = 1; + struct coding_system *coding = proc_encode_coding_system[outchannel]; + + coding->last_block = 1; + GCPRO1 (process); + while (new_argv[i] != 0) + { + int len = strlen (new_argv[i]); + int size = encoding_buffer_size (coding, len); + unsigned char *buf = (unsigned char *) alloca (size); + int produced, dmy; + + produced = encode_coding (coding, new_argv[i], buf, len, size, &dmy); + buf[produced] = 0; + /* We don't have to free new_argv[i] because it points to a + Lisp string given as an argument to `start-process'. */ + new_argv[i++] = buf; + } + UNGCPRO; + coding->last_block = 0; + } + /* Delay interrupts until we have a chance to store the new fork's pid in its process structure */ #ifdef POSIX_SIGNALS @@ -1438,6 +1486,9 @@ create_process (process, new_argv, current_dir) Protect it from permanent change. */ char **save_environ = environ; + current_dir + = Fencode_coding_string (current_dir, Vfile_name_coding_system, Qt); + #ifndef WINDOWSNT pid = vfork (); if (pid == 0) @@ -1900,38 +1951,54 @@ Fourth arg SERVICE is name of the service desired, or an integer\n\ { /* Setup coding systems for communicating with the network stream. */ struct gcpro gcpro1; - /* Qt denotes that we have not yet called Ffind_coding_system. */ + /* Qt denotes we have not yet called Ffind_operation_coding_system. */ Lisp_Object coding_systems = Qt; Lisp_Object args[5], val; - if (NILP (val = Vcoding_system_for_read)) + if (!NILP (Vcoding_system_for_read)) + val = Vcoding_system_for_read; + else if (NILP (current_buffer->enable_multibyte_characters)) + /* We dare not decode end-of-line format by setting VAL to + Qemacs_mule, because the existing Emacs Lisp libraries + assume that they receive bare code including a sequene of + CR LF. */ + val = Qnil; + else { args[0] = Qopen_network_stream, args[1] = name, args[2] = buffer, args[3] = host, args[4] = service; GCPRO1 (proc); - coding_systems = Ffind_coding_system (5, args); + coding_systems = Ffind_operation_coding_system (5, args); UNGCPRO; if (CONSP (coding_systems)) val = XCONS (coding_systems)->car; else if (CONSP (Vdefault_process_coding_system)) val = XCONS (Vdefault_process_coding_system)->car; + else + val = Qnil; } XPROCESS (proc)->decode_coding_system = val; - if (NILP (val = Vcoding_system_for_write)) + if (!NILP (Vcoding_system_for_write)) + val = Vcoding_system_for_write; + else if (NILP (current_buffer->enable_multibyte_characters)) + val = Qnil; + else { if (EQ (coding_systems, Qt)) { args[0] = Qopen_network_stream, args[1] = name, args[2] = buffer, args[3] = host, args[4] = service; GCPRO1 (proc); - coding_systems = Ffind_coding_system (5, args); + coding_systems = Ffind_operation_coding_system (5, args); UNGCPRO; } if (CONSP (coding_systems)) val = XCONS (coding_systems)->cdr; else if (CONSP (Vdefault_process_coding_system)) val = XCONS (Vdefault_process_coding_system)->cdr; + else + val = Qnil; } XPROCESS (proc)->encode_coding_system = val; } @@ -1955,6 +2022,7 @@ Fourth arg SERVICE is name of the service desired, or an integer\n\ } #endif /* HAVE_SOCKETS */ +void deactivate_process (proc) Lisp_Object proc; { @@ -2004,6 +2072,7 @@ deactivate_process (proc) with subprocess. This is used in a newly-forked subprocess to get rid of irrelevant descriptors. */ +void close_process_descs () { #ifndef WINDOWSNT @@ -2248,6 +2317,11 @@ wait_reading_process_input (time_limit, microsecs, read_kbd, do_display) goto retry; } + /* If there is unread keyboard input, also return. */ + if (XINT (read_kbd) != 0 + && requeued_events_pending_p ()) + break; + if (! EMACS_TIME_NEG_P (timer_delay) && time_limit != -1) { EMACS_TIME difference; @@ -2283,7 +2357,8 @@ wait_reading_process_input (time_limit, microsecs, read_kbd, do_display) { Atemp = input_wait_mask; EMACS_SET_SECS_USECS (timeout, 0, 0); - if ((select (MAXDESC, &Atemp, (SELECT_TYPE *)0, (SELECT_TYPE *)0, + if ((select (max (max_process_desc, max_keyboard_desc) + 1, + &Atemp, (SELECT_TYPE *)0, (SELECT_TYPE *)0, &timeout) <= 0)) { @@ -2300,7 +2375,26 @@ wait_reading_process_input (time_limit, microsecs, read_kbd, do_display) if (wait_proc != 0 && ! EQ (wait_proc->status, Qrun)) { + int nread, total_nread = 0; + clear_waiting_for_input (); + XSETPROCESS (proc, wait_proc); + + /* Read data from the process, until we exhaust it. */ + while (XINT (wait_proc->infd) >= 0 + && (nread + = read_process_output (proc, XINT (wait_proc->infd)))) + { + if (0 < nread) + total_nread += nread; +#ifdef EIO + else if (nread == -1 && EIO == errno) + break; +#endif + } + if (total_nread > 0 && do_display) + redisplay_preserve_echo_area (); + break; } @@ -2332,7 +2426,8 @@ wait_reading_process_input (time_limit, microsecs, read_kbd, do_display) FD_ZERO (&Available); } else - nfds = select (MAXDESC, &Available, (SELECT_TYPE *)0, (SELECT_TYPE *)0, + nfds = select (max (max_process_desc, max_keyboard_desc) + 1, + &Available, (SELECT_TYPE *)0, (SELECT_TYPE *)0, &timeout); xerrno = errno; @@ -2396,11 +2491,26 @@ wait_reading_process_input (time_limit, microsecs, read_kbd, do_display) kill (getpid (), SIGIO); #endif +#if 0 /* When polling is used, interrupt_input is 0, + so get_input_pending should read the input. + So this should not be needed. */ + /* If we are using polling for input, + and we see input available, make it get read now. + Otherwise it might not actually get read for a second. + And on hpux, since we turn off polling in wait_reading_process_input, + it might never get read at all if we don't spend much time + outside of wait_reading_process_input. */ + if (XINT (read_kbd) && interrupt_input + && keyboard_bit_set (&Available) + && input_polling_used ()) + kill (getpid (), SIGALRM); +#endif + /* Check for keyboard input */ /* If there is any, return immediately to give it higher priority than subprocesses */ - if ((XINT (read_kbd) != 0) + if (XINT (read_kbd) != 0 && detect_input_pending_run_timers (do_display)) { swallow_events (do_display); @@ -2408,18 +2518,25 @@ wait_reading_process_input (time_limit, microsecs, read_kbd, do_display) break; } - /* If wait_for_cell. check for keyboard input - but don't run any timers. - ??? (It seems wrong to me to check for keyboard - input at all when wait_for_cell, but the code - has been this way since July 1994. - Try changing this after version 19.31.) */ - if (wait_for_cell - && detect_input_pending ()) + /* If there is unread keyboard input, also return. */ + if (XINT (read_kbd) != 0 + && requeued_events_pending_p ()) + break; + + /* If we are not checking for keyboard input now, + do process events (but don't run any timers). + This is so that X events will be processed. + Otherwise they may have to wait until polling takes place. + That would causes delays in pasting selections, for example. + + (We used to do this only if wait_for_cell.) */ + if (XINT (read_kbd) == 0 && detect_input_pending ()) { swallow_events (do_display); +#if 0 /* Exiting when read_kbd doesn't request that seems wrong, though. */ if (detect_input_pending ()) break; +#endif } /* Exit now if the cell we're waiting for became non-nil. */ @@ -2427,13 +2544,13 @@ wait_reading_process_input (time_limit, microsecs, read_kbd, do_display) break; #ifdef SIGIO - /* If we think we have keyboard input waiting, but didn't get SIGIO + /* If we think we have keyboard input waiting, but didn't get SIGIO, go read it. This can happen with X on BSD after logging out. In that case, there really is no input and no SIGIO, but select says there is input. */ if (XINT (read_kbd) && interrupt_input - && (keyboard_bit_set (&Available))) + && keyboard_bit_set (&Available)) kill (getpid (), SIGIO); #endif @@ -2553,7 +2670,7 @@ wait_reading_process_input (time_limit, microsecs, read_kbd, do_display) Causes "poll: interrupted system call" messages when Emacs is run in an X window Turn periodic alarms back on */ - start_polling(); + start_polling (); #endif return got_some_input; @@ -2578,12 +2695,6 @@ read_process_output_error_handler (error) Fsleep_for (make_number (2), Qnil); } -#ifdef WINDOWSNT -#define READ_CHILD_OUTPUT read_child_output -#else -#define READ_CHILD_OUTPUT read -#endif - /* Read pending output from the process channel, starting with our buffered-ahead character if we have one. Yield number of decoded characters read. @@ -2599,7 +2710,7 @@ read_process_output (proc, channel) Lisp_Object proc; register int channel; { - register int nchars; + register int nchars, nbytes; char *chars; #ifdef VMS int chars_allocated = 0; /* If 1, `chars' should be freed later. */ @@ -2613,6 +2724,7 @@ read_process_output (proc, channel) struct coding_system *coding = proc_decode_coding_system[channel]; int chars_in_decoding_buf = 0; /* If 1, `chars' points XSTRING (p->decoding_buf)->data. */ + int multibyte; #ifdef VMS VMS_PROC_STUFF *vs, *get_vms_process_pointer(); @@ -2628,8 +2740,8 @@ read_process_output (proc, channel) else error ("Could not get VMS process pointer"); chars = vs->inputBuffer; - nchars = clean_vms_buffer (chars, vs->iosb[1]); - if (nchars <= 0) + nbytes = clean_vms_buffer (chars, vs->iosb[1]); + if (nbytes <= 0) { start_vms_process_read (vs); /* Crank up the next read on the process */ return 1; /* Nothing worth printing, say we got 1 */ @@ -2638,10 +2750,10 @@ read_process_output (proc, channel) { /* The data carried over in the previous decoding should be prepended to the new data read to decode all together. */ - char *buf = (char *) xmalloc (nchars + coding->carryover_size); + char *buf = (char *) xmalloc (nbytes + coding->carryover_size); bcopy (coding->carryover, buf, coding->carryover_size); - bcopy (chars, buf + coding->carryover_size, nchars); + bcopy (chars, buf + coding->carryover_size, nbytes); chars = buf; chars_allocated = 1; } @@ -2653,55 +2765,66 @@ read_process_output (proc, channel) bcopy (coding->carryover, buf, coding->carryover_size); if (proc_buffered_char[channel] < 0) - nchars = READ_CHILD_OUTPUT (channel, buf + coding->carryover_size, - (sizeof buf) - coding->carryover_size); + nbytes = read (channel, buf + coding->carryover_size, + (sizeof buf) - coding->carryover_size); else { buf[coding->carryover_size] = proc_buffered_char[channel]; proc_buffered_char[channel] = -1; - nchars = READ_CHILD_OUTPUT (channel, buf + coding->carryover_size + 1, - (sizeof buf) - coding->carryover_size - 1); - if (nchars < 0) - nchars = 1; + nbytes = read (channel, buf + coding->carryover_size + 1, + (sizeof buf) - coding->carryover_size - 1); + if (nbytes < 0) + nbytes = 1; else - nchars = nchars + 1; + nbytes = nbytes + 1; } chars = buf; #endif /* not VMS */ - /* At this point, NCHARS holds number of characters just received + /* At this point, NBYTES holds number of characters just received (including the one in proc_buffered_char[channel]). */ - if (nchars <= 0) return nchars; + if (nbytes <= 0) return nbytes; - /* Now set NCHARS how many bytes we must decode. */ - nchars += coding->carryover_size; + /* Now set NBYTES how many bytes we must decode. */ + nbytes += coding->carryover_size; - if (CODING_REQUIRE_CONVERSION (coding)) + if (CODING_REQUIRE_DECODING (coding) + || CODING_REQUIRE_DETECTION (coding)) { - int require = decoding_buffer_size (coding, nchars); + int require = decoding_buffer_size (coding, nbytes); int consumed, produced; - if (XSTRING (p->decoding_buf)->size < require) + if (XSTRING (p->decoding_buf)->size_byte < require) p->decoding_buf = make_uninit_string (require); produced = decode_coding (coding, chars, XSTRING (p->decoding_buf)->data, - nchars, XSTRING (p->decoding_buf)->size, + nbytes, XSTRING (p->decoding_buf)->size_byte, &consumed); /* New coding-system might be found by `decode_coding'. */ if (!EQ (p->decode_coding_system, coding->symbol)) { p->decode_coding_system = coding->symbol; - setup_coding_system (coding->symbol, - proc_decode_coding_system[channel]); - /* If coding-system for encoding is not yet decided, we set it - as the same as coding-system for decoding. */ - if (NILP (p->encode_coding_system)) + + /* Don't call setup_coding_system for + proc_decode_coding_system[channel] here. It is done in + detect_coding called via decode_coding above. */ + + /* If coding-system for encoding is not yet decided, we set + it as the same as coding-system for decoding. + + But, before doing that we must check if + proc_encode_coding_system[p->outfd] surely points to a + valid memory because p->outfd will be changed once EOF is + sent to the process. */ + if (NILP (p->encode_coding_system) + && proc_encode_coding_system[p->outfd]) { p->encode_coding_system = coding->symbol; setup_coding_system (coding->symbol, - proc_encode_coding_system[channel]); + proc_encode_coding_system[p->outfd]); } } + #ifdef VMS /* Now we don't need the contents of `chars'. */ if (chars_allocated) @@ -2709,8 +2832,8 @@ read_process_output (proc, channel) #endif if (produced == 0) return 0; - chars = XSTRING (p->decoding_buf)->data; - nchars = produced; + chars = (char *) XSTRING (p->decoding_buf)->data; + nbytes = produced; chars_in_decoding_buf = 1; } #ifdef VMS @@ -2719,15 +2842,28 @@ read_process_output (proc, channel) /* Although we don't have to decode the received data, we must move it to an area which we don't have to free. */ if (! STRINGP (p->decoding_buf) - || XSTRING (p->decoding_buf)->size < nchars) - p->decoding_buf = make_uninit_string (nchars); - bcopy (chars, XSTRING (p->decoding_buf)->data, nchars); + || XSTRING (p->decoding_buf)->size < nbytes) + p->decoding_buf = make_uninit_string (nbytes); + bcopy (chars, XSTRING (p->decoding_buf)->data, nbytes); free (chars); chars = XSTRING (p->decoding_buf)->data; chars_in_decoding_buf = 1; } #endif + Vlast_coding_system_used = coding->symbol; + + multibyte = (coding->type != coding_type_emacs_mule + && coding->type != coding_type_no_conversion + && coding->type != coding_type_undecided + && coding->type != coding_type_raw_text); + + /* Read and dispose of the process output. */ + if (multibyte) + nchars = multibyte_chars_in_text (chars, nbytes); + else + nchars = nbytes; + outstream = p->filter; if (!NILP (outstream)) { @@ -2737,6 +2873,7 @@ read_process_output (proc, channel) int count = specpdl_ptr - specpdl; Lisp_Object odeactivate; Lisp_Object obuffer, okeymap; + Lisp_Object text; int outer_running_asynch_code = running_asynch_code; /* No need to gcpro these, because all we do with them later @@ -2765,13 +2902,10 @@ read_process_output (proc, channel) save the match data in a special nonrecursive fashion. */ running_asynch_code = 1; - /* Read and dispose of the process output. */ + text = make_multibyte_string (chars, nchars, nbytes); internal_condition_case_1 (read_process_output_call, Fcons (outstream, - Fcons (proc, - Fcons (make_string (chars, - nchars), - Qnil))), + Fcons (proc, Fcons (text, Qnil))), !NILP (Vdebug_on_error) ? Qnil : Qerror, read_process_output_error_handler); @@ -2806,16 +2940,21 @@ read_process_output (proc, channel) { Lisp_Object old_read_only; int old_begv, old_zv; + int old_begv_byte, old_zv_byte; Lisp_Object odeactivate; - int before; + int before, before_byte; + int opoint_byte; odeactivate = Vdeactivate_mark; Fset_buffer (p->buffer); opoint = PT; + opoint_byte = PT_BYTE; old_read_only = current_buffer->read_only; old_begv = BEGV; old_zv = ZV; + old_begv_byte = BEGV_BYTE; + old_zv_byte = ZV_BYTE; current_buffer->read_only = Qnil; @@ -2823,10 +2962,13 @@ read_process_output (proc, channel) at the current end-of-output marker, thus preserving logical ordering of input and output. */ if (XMARKER (p->mark)->buffer) - SET_PT (clip_to_bounds (BEGV, marker_position (p->mark), ZV)); + SET_PT_BOTH (clip_to_bounds (BEGV, marker_position (p->mark), ZV), + clip_to_bounds (BEGV_BYTE, marker_byte_position (p->mark), + ZV_BYTE)); else - SET_PT (ZV); + SET_PT_BOTH (ZV, ZV_BYTE); before = PT; + before_byte = PT_BYTE; /* If the output marker is outside of the visible region, save the restriction and widen. */ @@ -2836,21 +2978,31 @@ read_process_output (proc, channel) /* Insert before markers in case we are inserting where the buffer's mark is, and the user's next command is Meta-y. */ if (chars_in_decoding_buf) - insert_from_string_before_markers (p->decoding_buf, 0, nchars, 0); + insert_from_string_before_markers (p->decoding_buf, 0, 0, + nchars, nbytes, 0); else - insert_before_markers (chars, nchars); - Fset_marker (p->mark, make_number (PT), p->buffer); + insert_1_both (chars, nchars, nbytes, 0, 1, 1); + set_marker_both (p->mark, p->buffer, PT, PT_BYTE); update_mode_lines++; /* Make sure opoint and the old restrictions float ahead of any new text just as point would. */ if (opoint >= before) - opoint += PT - before; + { + opoint += PT - before; + opoint_byte += PT_BYTE - before_byte; + } if (old_begv > before) - old_begv += PT - before; + { + old_begv += PT - before; + old_begv_byte += PT_BYTE - before_byte; + } if (old_zv >= before) - old_zv += PT - before; + { + old_zv += PT - before; + old_zv_byte += PT_BYTE - before_byte; + } /* If the restriction isn't what it should be, set it. */ if (old_begv != BEGV || old_zv != ZV) @@ -2860,13 +3012,13 @@ read_process_output (proc, channel) Vdeactivate_mark = odeactivate; current_buffer->read_only = old_read_only; - SET_PT (opoint); + SET_PT_BOTH (opoint, opoint_byte); set_buffer_internal (old); } #ifdef VMS start_vms_process_read (vs); #endif - return nchars; + return nbytes; } DEFUN ("waiting-for-user-input-p", Fwaiting_for_user_input_p, Swaiting_for_user_input_p, @@ -2904,7 +3056,7 @@ send_process_trap () send_process (proc, buf, len, object) volatile Lisp_Object proc; - char *buf; + unsigned char *buf; int len; Lisp_Object object; { @@ -2929,31 +3081,33 @@ send_process (proc, buf, len, object) error ("Output file descriptor of %s is closed", procname); coding = proc_encode_coding_system[XINT (XPROCESS (proc)->outfd)]; - if (CODING_REQUIRE_CONVERSION (coding)) + Vlast_coding_system_used = coding->symbol; + + if (CODING_REQUIRE_ENCODING (coding)) { int require = encoding_buffer_size (coding, len); int offset, dummy; - char *temp_buf = NULL; + unsigned char *temp_buf = NULL; /* Remember the offset of data because a string or a buffer may be relocated. Setting OFFSET to -1 means we don't have to care relocation. */ offset = (BUFFERP (object) - ? BUF_PTR_CHAR_POS (XBUFFER (object), (unsigned char *) buf) + ? BUF_PTR_BYTE_POS (XBUFFER (object), buf) : (STRINGP (object) - ? offset = buf - (char *) XSTRING (object)->data + ? offset = buf - XSTRING (object)->data : -1)); if (coding->carryover_size > 0) { - temp_buf = (char *) xmalloc (len + coding->carryover_size); + temp_buf = (unsigned char *) xmalloc (len + coding->carryover_size); if (offset >= 0) { if (BUFFERP (object)) - buf = (char *) BUF_CHAR_ADDRESS (XBUFFER (object), offset); + buf = BUF_BYTE_ADDRESS (XBUFFER (object), offset); else if (STRINGP (object)) - buf = offset + (char *) XSTRING (object)->data; + buf = offset + XSTRING (object)->data; /* Now we don't have to care relocation. */ offset = -1; } @@ -2962,21 +3116,21 @@ send_process (proc, buf, len, object) buf = temp_buf; } - if (XSTRING (XPROCESS (proc)->encoding_buf)->size < require) + if (XSTRING (XPROCESS (proc)->encoding_buf)->size_byte < require) { XPROCESS (proc)->encoding_buf = make_uninit_string (require); if (offset >= 0) { if (BUFFERP (object)) - buf = (char *) BUF_CHAR_ADDRESS (XBUFFER (object), offset); + buf = BUF_BYTE_ADDRESS (XBUFFER (object), offset); else if (STRINGP (object)) - buf = offset + (char *) XSTRING (object)->data; + buf = offset + XSTRING (object)->data; } } object = XPROCESS (proc)->encoding_buf; len = encode_coding (coding, buf, XSTRING (object)->data, - len, XSTRING (object)->size, &dummy); + len, XSTRING (object)->size_byte, &dummy); buf = XSTRING (object)->data; if (temp_buf) xfree (temp_buf); @@ -3022,8 +3176,8 @@ send_process (proc, buf, len, object) If that proves worth handling, we need to save linepos in the process object. */ int linepos = 0; - char *ptr = buf; - char *end = buf + len; + unsigned char *ptr = buf; + unsigned char *end = buf + len; /* Scan through this text for a line that is too long. */ while (ptr != end && linepos < pty_max_bytes) @@ -3066,10 +3220,9 @@ send_process (proc, buf, len, object) /* Running filters might relocate buffers or strings. Arrange to relocate BUF. */ if (BUFFERP (object)) - offset = BUF_PTR_CHAR_POS (XBUFFER (object), - (unsigned char *) buf); + offset = BUF_PTR_BYTE_POS (XBUFFER (object), buf); else if (STRINGP (object)) - offset = buf - (char *) XSTRING (object)->data; + offset = buf - XSTRING (object)->data; XSETFASTINT (zero, 0); #ifdef EMACS_HAS_USECS @@ -3079,9 +3232,9 @@ send_process (proc, buf, len, object) #endif if (BUFFERP (object)) - buf = (char *) BUF_CHAR_ADDRESS (XBUFFER (object), offset); + buf = BUF_BYTE_ADDRESS (XBUFFER (object), offset); else if (STRINGP (object)) - buf = offset + (char *) XSTRING (object)->data; + buf = offset + XSTRING (object)->data; rv = 0; } @@ -3130,16 +3283,17 @@ Output from processes can arrive in between bunches.") Lisp_Object process, start, end; { Lisp_Object proc; - int start1; + int start1, end1; proc = get_process (process); validate_region (&start, &end); if (XINT (start) < GPT && XINT (end) > GPT) - move_gap (start); + move_gap (XINT (start)); - start1 = XINT (start); - send_process (proc, POS_ADDR (start1), XINT (end) - XINT (start), + start1 = CHAR_TO_BYTE (XINT (start)); + end1 = CHAR_TO_BYTE (XINT (end)); + send_process (proc, BYTE_POS_ADDR (start1), end1 - start1, Fcurrent_buffer ()); return Qnil; @@ -3159,7 +3313,8 @@ Output from processes can arrive in between bunches.") Lisp_Object proc; CHECK_STRING (string, 1); proc = get_process (process); - send_process (proc, XSTRING (string)->data, XSTRING (string)->size, string); + send_process (proc, XSTRING (string)->data, + XSTRING (string)->size_byte, string); return Qnil; } @@ -3596,7 +3751,20 @@ text to PROCESS after you call this function.") send_process (proc, "\004", 1, Qnil); else { +#ifdef HAVE_SHUTDOWN + /* If this is a network connection, or socketpair is used + for communication with the subprocess, call shutdown to cause EOF. + (In some old system, shutdown to socketpair doesn't work. + Then we just can't win.) */ + if (NILP (XPROCESS (proc)->pid) + || XINT (XPROCESS (proc)->outfd) == XINT (XPROCESS (proc)->infd)) + shutdown (XINT (XPROCESS (proc)->outfd), 1); + /* In case of socketpair, outfd == infd, so don't close it. */ + if (XINT (XPROCESS (proc)->outfd) != XINT (XPROCESS (proc)->infd)) + close (XINT (XPROCESS (proc)->outfd)); +#else /* not HAVE_SHUTDOWN */ close (XINT (XPROCESS (proc)->outfd)); +#endif /* not HAVE_SHUTDOWN */ XSETINT (XPROCESS (proc)->outfd, open (NULL_DEVICE, O_WRONLY)); } #endif /* VMS */ @@ -3606,6 +3774,7 @@ text to PROCESS after you call this function.") /* Kill all processes associated with `buffer'. If `buffer' is nil, kill all processes */ +void kill_buffer_processes (buffer) Lisp_Object buffer; { @@ -3891,6 +4060,7 @@ exec_sentinel (proc, reason) (either run the sentinel or output a message). This is done while Emacs is waiting for keyboard input. */ +void status_notify () { register Lisp_Object proc, buffer; @@ -3961,8 +4131,8 @@ status_notify () { Lisp_Object ro, tem; struct buffer *old = current_buffer; - int opoint; - int before; + int opoint, opoint_byte; + int before, before_byte; ro = XBUFFER (buffer)->read_only; @@ -3973,15 +4143,17 @@ status_notify () Fset_buffer (buffer); opoint = PT; + opoint_byte = PT_BYTE; /* Insert new output into buffer at the current end-of-output marker, thus preserving logical ordering of input and output. */ if (XMARKER (p->mark)->buffer) - SET_PT (marker_position (p->mark)); + Fgoto_char (p->mark); else - SET_PT (ZV); + SET_PT_BOTH (ZV, ZV_BYTE); before = PT; + before_byte = PT_BYTE; tem = current_buffer->read_only; current_buffer->read_only = Qnil; @@ -3990,12 +4162,13 @@ status_notify () insert_string (" "); Finsert (1, &msg); current_buffer->read_only = tem; - Fset_marker (p->mark, make_number (PT), p->buffer); + set_marker_both (p->mark, p->buffer, PT, PT_BYTE); if (opoint >= before) - SET_PT (opoint + (PT - before)); + SET_PT_BOTH (opoint + (PT - before), + opoint_byte + (PT_BYTE - before_byte)); else - SET_PT (opoint); + SET_PT_BOTH (opoint, opoint_byte); set_buffer_internal (old); } @@ -4011,7 +4184,7 @@ status_notify () DEFUN ("set-process-coding-system", Fset_process_coding_system, Sset_process_coding_system, 1, 3, 0, - "Set coding-systems of PROCESS to DECODING (input from the process) and\n\ + "Set coding systems of PROCESS to DECODING (input from the process) and\n\ ENCODING (output to the process).") (proc, decoding, encoding) register Lisp_Object proc, decoding, encoding; @@ -4037,7 +4210,7 @@ ENCODING (output to the process).") DEFUN ("process-coding-system", Fprocess_coding_system, Sprocess_coding_system, 1, 1, 0, - "Return a cons of coding-system for decoding and encoding of PROCESS.") + "Return a cons of coding systems for decoding and encoding of PROCESS.") (proc) register Lisp_Object proc; {