/* Asynchronous subprocess control for GNU Emacs.
- Copyright (C) 1985, 86, 87, 88, 93, 94, 95, 1996
+ Copyright (C) 1985, 86, 87, 88, 93, 94, 95, 96, 1998
Free Software Foundation, Inc.
This file is part of GNU Emacs.
#include "commands.h"
#include "frame.h"
#include "blockinput.h"
+#include "keyboard.h"
+#include "dispextern.h"
+
+#define max(a, b) ((a) > (b) ? (a) : (b))
Lisp_Object Qprocessp;
Lisp_Object Qrun, Qstop, Qsignal, Qopen, Qclosed;
/* Maximum number of bytes to send to a pty without an eof. */
static int pty_max_bytes;
+extern Lisp_Object Vfile_name_coding_system, Vdefault_file_name_coding_system;
+
#ifdef HAVE_PTYS
/* The file name of the pty opened by allocate_pty. */
Lisp_Object status_convert ();
+void
update_status (p)
struct Lisp_Process *p;
{
allocate_pty ()
{
struct stat stb;
- register c, i;
+ register int c, i;
int fd;
/* Some systems name their pseudoterminals so that there are gaps in
return val;
}
+void
remove_process (proc)
register Lisp_Object proc;
{
an output stream or filter function to handle the output.\n\
BUFFER may be also nil, meaning that this process is not associated\n\
with any buffer.\n\
-Third arg is program file name. It is searched for as in the shell.\n\
+Third arg is program file name. It is searched for in PATH.\n\
Remaining arguments are strings to give program as arguments.")
(nargs, args)
int nargs;
#ifdef VMS
/* Make a one member argv with all args concatenated
together separated by a blank. */
- len = XSTRING (program)->size + 2;
+ len = STRING_BYTES (XSTRING (program)) + 2;
for (i = 3; i < nargs; i++)
{
tem = args[i];
CHECK_STRING (tem, i);
- len += XSTRING (tem)->size + 1; /* count the blank */
+ len += STRING_BYTES (XSTRING (tem)) + 1; /* count the blank */
}
new_argv = (unsigned char *) alloca (len);
strcpy (new_argv, XSTRING (program)->data);
/* 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))
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 = Qraw_text;
+ 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))
{
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;
}
XPROCESS (proc)->decoding_buf = make_uninit_string (0);
+ XPROCESS (proc)->decoding_carryover = make_number (0);
XPROCESS (proc)->encoding_buf = make_uninit_string (0);
+ XPROCESS (proc)->encoding_carryover = make_number (0);
- create_process (proc, new_argv, current_dir);
+ create_process (proc, (char **) new_argv, current_dir);
return unbind_to (count, proc);
}
#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;
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->mode |= CODING_MODE_LAST_BLOCK;
+ 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);
+
+ encode_coding (coding, new_argv[i], buf, len, size);
+ buf[coding->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->mode &= ~CODING_MODE_LAST_BLOCK;
+ }
+
/* Delay interrupts until we have a chance to store
the new fork's pid in its process structure */
#ifdef POSIX_SIGNALS
Protect it from permanent change. */
char **save_environ = environ;
+ current_dir = ENCODE_FILE (current_dir);
+
#ifndef WINDOWSNT
pid = vfork ();
if (pid == 0)
{
/* 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
+ Qraw_text, 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;
}
proc_encode_coding_system[outch]);
XPROCESS (proc)->decoding_buf = make_uninit_string (0);
+ XPROCESS (proc)->decoding_carryover = make_number (0);
XPROCESS (proc)->encoding_buf = make_uninit_string (0);
+ XPROCESS (proc)->encoding_carryover = make_number (0);
UNGCPRO;
return proc;
}
#endif /* HAVE_SOCKETS */
+void
deactivate_process (proc)
Lisp_Object proc;
{
with subprocess. This is used in a newly-forked subprocess
to get rid of irrelevant descriptors. */
+void
close_process_descs ()
{
#ifndef WINDOWSNT
static int waiting_for_user_input_p;
/* This is here so breakpoints can be put on it. */
-static
+static void
wait_reading_process_input_1 ()
{
}
before the timeout elapsed.
Otherwise, return true iff we received input from any process. */
+int
wait_reading_process_input (time_limit, microsecs, read_kbd, do_display)
int time_limit, microsecs;
Lisp_Object read_kbd;
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;
{
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))
{
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;
}
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;
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);
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. */
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
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;
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.
The characters read are decoded according to PROC's coding-system
for decoding. */
+int
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. */
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 carryover = XINT (p->decoding_carryover);
#ifdef VMS
VMS_PROC_STUFF *vs, *get_vms_process_pointer();
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 */
}
- if (coding->carryover_size)
+ if (carryover > 0)
{
- /* 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);
-
- bcopy (coding->carryover, buf, coding->carryover_size);
- bcopy (chars, buf + coding->carryover_size, nchars);
+ /* The data carried over in the previous decoding (which are at
+ the tail of decoding buffer) should be prepended to the new
+ data read to decode all together. */
+ char *buf = (char *) xmalloc (nbytes + carryover);
+
+ bcopy (XSTRING (p->decoding_buf)->data
+ + STRING_BYTES (XSTRING (p->decoding_buf)) - carryover,
+ buf, carryover);
+ bcopy (chars, buf + carryover, nbytes);
chars = buf;
chars_allocated = 1;
}
#else /* not VMS */
- if (coding->carryover_size)
- /* The data carried over in the previous decoding should be
- prepended to the new data read to decode all together. */
- bcopy (coding->carryover, buf, coding->carryover_size);
+ if (carryover)
+ /* See the comment above. */
+ bcopy (XSTRING (p->decoding_buf)->data
+ + STRING_BYTES (XSTRING (p->decoding_buf)) - carryover,
+ buf, carryover);
if (proc_buffered_char[channel] < 0)
- nchars = READ_CHILD_OUTPUT (channel, buf + coding->carryover_size,
- (sizeof buf) - coding->carryover_size);
+ nbytes = read (channel, buf + carryover, (sizeof buf) - carryover);
else
{
- buf[coding->carryover_size] = proc_buffered_char[channel];
+ buf[carryover] = 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 + carryover + 1,
+ (sizeof buf) - carryover - 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 += carryover;
+ nchars = nbytes;
- if (CODING_REQUIRE_CONVERSION (coding))
+ if (CODING_MAY_REQUIRE_DECODING (coding))
{
- int require = decoding_buffer_size (coding, nchars);
- int consumed, produced;
+ int require = decoding_buffer_size (coding, nbytes);
+ int result;
- if (XSTRING (p->decoding_buf)->size < require)
+ if (STRING_BYTES (XSTRING (p->decoding_buf)) < require)
p->decoding_buf = make_uninit_string (require);
- produced = decode_coding (coding, chars, XSTRING (p->decoding_buf)->data,
- nchars, XSTRING (p->decoding_buf)->size,
- &consumed);
+ result = decode_coding (coding, chars, XSTRING (p->decoding_buf)->data,
+ nbytes, STRING_BYTES (XSTRING (p->decoding_buf)));
+ carryover = nbytes - coding->consumed;
- /* New coding-system might be found by `decode_coding'. */
+ /* A 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 a 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)
free (chars);
#endif
- if (produced == 0)
+ if (coding->produced == 0)
return 0;
- chars = XSTRING (p->decoding_buf)->data;
- nchars = produced;
+ chars = (char *) XSTRING (p->decoding_buf)->data;
+ nbytes = coding->produced;
+ nchars = (coding->fake_multibyte
+ ? multibyte_chars_in_text (chars, nbytes)
+ : coding->produced_char);
chars_in_decoding_buf = 1;
}
#ifdef VMS
/* 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);
+ || STRING_BYTES (XSTRING (p->decoding_buf)) < nbytes)
+ p->decoding_buf = make_uninit_string (nbytes);
+ bcopy (chars, XSTRING (p->decoding_buf)->data, nbytes);
free (chars);
chars = XSTRING (p->decoding_buf)->data;
+ nchars = multibyte_chars_in_text (chars, nbytes);
chars_in_decoding_buf = 1;
+ carryover = 0;
}
#endif
+ XSETINT (p->decoding_carryover, carryover);
+ Vlast_coding_system_used = coding->symbol;
+
+ /* Read and dispose of the process output. */
outstream = p->filter;
if (!NILP (outstream))
{
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
/* Don't clobber the CURRENT match data, either! */
tem = Fmatch_data (Qnil, Qnil);
restore_match_data ();
- record_unwind_protect (Fstore_match_data, Fmatch_data (Qnil, Qnil));
- Fstore_match_data (tem);
+ record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
+ Fset_match_data (tem);
}
/* For speed, if a search happens within this code,
save the match data in a special nonrecursive fashion. */
running_asynch_code = 1;
- /* Read and dispose of the process output. */
+ text = make_string_from_bytes (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);
{
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;
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. */
/* 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);
+ {
+ /* Since multibyteness of p->docoding_buf is corrupted, we
+ can't use insert_from_string_before_markers. */
+ char *temp_buf;
+
+ temp_buf = (char *) alloca (nbytes);
+ bcopy (XSTRING (p->decoding_buf)->data, temp_buf, nbytes);
+ insert_before_markers (temp_buf, nbytes);
+ }
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)
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,
being encoded. Should we store them in a buffer to prepend them to
the data send later? */
+void
send_process (proc, buf, len, object)
volatile Lisp_Object proc;
- char *buf;
+ unsigned char *buf;
int len;
Lisp_Object object;
{
volatile unsigned char *procname = XSTRING (XPROCESS (proc)->name)->data;
struct coding_system *coding;
struct gcpro gcpro1;
+ int carryover = XINT (XPROCESS (proc)->encoding_carryover);
GCPRO1 (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)
+ if (carryover > 0)
{
- temp_buf = (char *) xmalloc (len + coding->carryover_size);
+ temp_buf = (unsigned char *) xmalloc (len + carryover);
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;
}
- bcopy (coding->carryover, temp_buf, coding->carryover_size);
- bcopy (buf, temp_buf + coding->carryover_size, len);
+ bcopy ((XSTRING (XPROCESS (proc)->encoding_buf)->data
+ + STRING_BYTES (XSTRING (XPROCESS (proc)->encoding_buf))
+ - carryover),
+ temp_buf,
+ carryover);
+ bcopy (buf, temp_buf + carryover, len);
buf = temp_buf;
}
- if (XSTRING (XPROCESS (proc)->encoding_buf)->size < require)
+ if (STRING_BYTES (XSTRING (XPROCESS (proc)->encoding_buf)) < 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);
+ encode_coding (coding, buf, XSTRING (object)->data,
+ len, STRING_BYTES (XSTRING (object)));
+ len = coding->produced;
buf = XSTRING (object)->data;
if (temp_buf)
xfree (temp_buf);
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)
/* 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
#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;
}
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;
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,
+ STRING_BYTES (XSTRING (string)), string);
return Qnil;
}
\f
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 */
/* Kill all processes associated with `buffer'.
If `buffer' is nil, kill all processes */
+void
kill_buffer_processes (buffer)
Lisp_Object buffer;
{
Lisp_Object tem;
tem = Fmatch_data (Qnil, Qnil);
restore_match_data ();
- record_unwind_protect (Fstore_match_data, Fmatch_data (Qnil, Qnil));
- Fstore_match_data (tem);
+ record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
+ Fset_match_data (tem);
}
/* For speed, if a search happens within this code,
(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;
{
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;
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;
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);
}
\f
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;
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;
{
return 0;
}
\f
+void
init_process ()
{
register int i;
bzero (proc_encode_coding_system, sizeof proc_encode_coding_system);
}
+void
syms_of_process ()
{
Qprocessp = intern ("processp");
If `buffer' is nil, kill all processes.
Since we have no subprocesses, this does nothing. */
+void
kill_buffer_processes (buffer)
Lisp_Object buffer;
{