#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;
/* 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. */
/* 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 = 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))
{
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)->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);
}
#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->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
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)
{
/* 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;
}
}
#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
{
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;
+ int nread, total_nread = 0;
clear_waiting_for_input ();
XSETPROCESS (proc, wait_proc);
while (XINT (wait_proc->infd) >= 0
&& (nread
= read_process_output (proc, XINT (wait_proc->infd))))
- total_nread += nread;
+ {
+ 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 ();
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);
&& requeued_events_pending_p ())
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 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.
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);
+ nchars = 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);
+ nchars = read (channel, buf + coding->carryover_size + 1,
+ (sizeof buf) - coding->carryover_size - 1);
if (nchars < 0)
nchars = 1;
else
/* Now set NCHARS how many bytes we must decode. */
nchars += 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 consumed, produced;
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
#endif
if (produced == 0)
return 0;
- chars = XSTRING (p->decoding_buf)->data;
+ chars = (char *) XSTRING (p->decoding_buf)->data;
nchars = produced;
chars_in_decoding_buf = 1;
}
}
#endif
+ Vlast_coding_system_used = coding->symbol;
+
outstream = p->filter;
if (!NILP (outstream))
{
{
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_from_string_before_markers (p->decoding_buf, 0, nchars, 0);
else
insert_before_markers (chars, nchars);
- Fset_marker (p->mark, make_number (PT), p->buffer);
+ 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
send_process (proc, buf, len, object)
volatile Lisp_Object proc;
- char *buf;
+ unsigned char *buf;
int len;
Lisp_Object 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;
}
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;
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;
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.
/* 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;
{
(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;
{