}
else
{
- *symbol = XCONS (l)->car;
- tem = XCONS (l)->cdr;
- *code = XFASTINT (XCONS (tem)->car);
- tem = XCONS (tem)->cdr;
+ *symbol = XCAR (l);
+ tem = XCDR (l);
+ *code = XFASTINT (XCAR (tem));
+ tem = XCDR (tem);
*coredump = !NILP (tem);
}
}
open -- for a network stream connection that is open.\n\
closed -- for a network stream connection that is closed.\n\
nil -- if arg is a process name and no such process exists.\n\
-PROCESS may be a process, a buffer, the name of a process or buffer, or\n\
+PROCESS may be a process, a buffer, the name of a process, or\n\
nil, indicating the current buffer's process.")
(process)
register Lisp_Object process;
update_status (p);
status = p->status;
if (CONSP (status))
- status = XCONS (status)->car;
+ status = XCAR (status);
if (NETCONN_P (process))
{
if (EQ (status, Qrun))
if (!NILP (XPROCESS (process)->raw_status_low))
update_status (XPROCESS (process));
if (CONSP (XPROCESS (process)->status))
- return XCONS (XCONS (XPROCESS (process)->status)->cdr)->car;
+ return XCAR (XCDR (XPROCESS (process)->status));
return make_number (0);
}
CHECK_NATNUM (height, 0);
CHECK_NATNUM (width, 0);
if (set_window_size (XINT (XPROCESS (process)->infd),
- XINT (height), XINT(width)) <= 0)
+ XINT (height), XINT (width)) <= 0)
return Qnil;
else
return Qt;
update_status (p);
symbol = p->status;
if (CONSP (p->status))
- symbol = XCONS (p->status)->car;
+ symbol = XCAR (p->status);
if (EQ (symbol, Qsignal))
if (NETCONN_P (proc))
{
sprintf (tembuf, "(network stream connection to %s)\n",
- XSTRING (XCONS (p->childp)->car)->data);
+ XSTRING (XCAR (p->childp))->data);
insert_string (tembuf);
}
else
coding_systems = Ffind_operation_coding_system (nargs + 1, args2);
UNGCPRO;
if (CONSP (coding_systems))
- val = XCONS (coding_systems)->car;
+ val = XCAR (coding_systems);
else if (CONSP (Vdefault_process_coding_system))
- val = XCONS (Vdefault_process_coding_system)->car;
+ val = XCAR (Vdefault_process_coding_system);
}
XPROCESS (proc)->decode_coding_system = val;
UNGCPRO;
}
if (CONSP (coding_systems))
- val = XCONS (coding_systems)->cdr;
+ val = XCDR (coding_systems);
else if (CONSP (Vdefault_process_coding_system))
- val = XCONS (Vdefault_process_coding_system)->cdr;
+ val = XCDR (Vdefault_process_coding_system);
}
XPROCESS (proc)->encode_coding_system = val;
}
}
#else /* not SKTPAIR */
{
- pipe (sv);
+ int tem;
+ tem = pipe (sv);
+ if (tem < 0)
+ report_file_error ("Creating pipe", Qnil);
inchannel = sv[0];
forkout = sv[1];
- pipe (sv);
+ tem = pipe (sv);
+ if (tem < 0)
+ {
+ close (inchannel);
+ close (forkout);
+ report_file_error ("Creating pipe", Qnil);
+ }
outchannel = sv[1];
forkin = sv[0];
}
/* In unibyte mode, character code conversion should not take
place but EOL conversion should. So, setup raw-text or one
of the subsidiary according to the information just setup. */
- if (NILP (Vcoding_system_for_read)
- && !NILP (XPROCESS (process)->decode_coding_system))
+ if (!NILP (XPROCESS (process)->decode_coding_system))
setup_raw_text_coding_system (proc_decode_coding_system[inchannel]);
- if (NILP (Vcoding_system_for_write)
- && !NILP (XPROCESS (process)->encode_coding_system))
+ if (!NILP (XPROCESS (process)->encode_coding_system))
setup_raw_text_coding_system (proc_encode_coding_system[outchannel]);
}
{
Lisp_Object proc;
register int i;
+
+#ifndef HAVE_GETADDRINFO
struct sockaddr_in address;
struct servent *svc_info;
struct hostent *host_info_ptr, host_info;
char *(addr_list[2]);
IN_ADDR numeric_addr;
- int s, outch, inch;
- char errstring[80];
- int port;
struct hostent host_info_fixed;
+ int port;
+#else /* HAVE_GETADDRINFO */
+ struct addrinfo hints, *res, *lres;
+ int ret = 0;
+ int xerrno = 0;
+ char *portstring, portbuf[128];
+#endif /* HAVE_GETADDRINFO */
+ int s = -1, outch, inch;
struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
int retry = 0;
int count = specpdl_ptr - specpdl;
GCPRO4 (name, buffer, host, service);
CHECK_STRING (name, 0);
CHECK_STRING (host, 0);
+
+#ifdef HAVE_GETADDRINFO
+ /*
+ * SERVICE can either be a string or int.
+ * Convert to a C string for later use by getaddrinfo.
+ */
+ if (INTEGERP (service))
+ {
+ sprintf (portbuf, "%d", XINT (service));
+ portstring = portbuf;
+ }
+ else
+ {
+ CHECK_STRING (service, 0);
+ portstring = XSTRING (service)->data;
+ }
+#else /* ! HAVE_GETADDRINFO */
if (INTEGERP (service))
port = htons ((unsigned short) XINT (service));
else
error ("Unknown service \"%s\"", XSTRING (service)->data);
port = svc_info->s_port;
}
+#endif /* ! HAVE_GETADDRINFO */
+
/* Slow down polling to every ten seconds.
Some kernels have a bug which causes retrying connect to fail
#endif
#ifndef TERM
+#ifdef HAVE_GETADDRINFO
+ {
+ immediate_quit = 1;
+ QUIT;
+ memset (&hints, 0, sizeof (hints));
+ hints.ai_flags = 0;
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_protocol = 0;
+ ret = getaddrinfo (XSTRING (host)->data, portstring, &hints, &res);
+ if (ret)
+ {
+ error ("%s/%s %s", XSTRING (host)->data, portstring,
+ gai_strerror (ret));
+ }
+ immediate_quit = 0;
+ }
+
+ for (lres = res; lres; lres = lres->ai_next)
+ {
+ s = socket (lres->ai_family, lres->ai_socktype, lres->ai_protocol);
+ if (s < 0)
+ continue;
+
+ /* Kernel bugs (on Ultrix at least) cause lossage (not just EINTR)
+ when connect is interrupted. So let's not let it get interrupted.
+ Note we do not turn off polling, because polling is only used
+ when not interrupt_input, and thus not normally used on the systems
+ which have this bug. On systems which use polling, there's no way
+ to quit if polling is turned off. */
+ if (interrupt_input)
+ unrequest_sigio ();
+
+ immediate_quit = 1;
+ QUIT;
+
+ ret = connect (s, lres->ai_addr, lres->ai_addrlen);
+ if (ret == 0)
+ break;
+ close (s);
+ s = -1;
+ }
+
+ freeaddrinfo (res);
+ if (s < 0)
+ {
+ if (interrupt_input)
+ request_sigio ();
+
+ errno = xerrno;
+ report_file_error ("connection failed",
+ Fcons (host, Fcons (name, Qnil)));
+ }
+#else /* ! HAVE_GETADDRINFO */
+
while (1)
{
#ifdef TRY_AGAIN
report_file_error ("connection failed",
Fcons (host, Fcons (name, Qnil)));
}
+#endif /* ! HAVE_GETADDRINFO */
immediate_quit = 0;
coding_systems = Ffind_operation_coding_system (5, args);
UNGCPRO;
if (CONSP (coding_systems))
- val = XCONS (coding_systems)->car;
+ val = XCAR (coding_systems);
else if (CONSP (Vdefault_process_coding_system))
- val = XCONS (Vdefault_process_coding_system)->car;
+ val = XCAR (Vdefault_process_coding_system);
else
val = Qnil;
}
UNGCPRO;
}
if (CONSP (coding_systems))
- val = XCONS (coding_systems)->cdr;
+ val = XCDR (coding_systems);
else if (CONSP (Vdefault_process_coding_system))
- val = XCONS (Vdefault_process_coding_system)->cdr;
+ val = XCDR (Vdefault_process_coding_system);
else
val = Qnil;
}
int seconds;
int useconds;
+ if (! NILP (process))
+ CHECK_PROCESS (process, 0);
+
if (! NILP (timeout_msecs))
{
CHECK_NUMBER (timeout_msecs, 2);
/* If waiting for non-nil in a cell, record where. */
if (CONSP (read_kbd))
{
- wait_for_cell = &XCONS (read_kbd)->car;
+ wait_for_cell = &XCAR (read_kbd);
XSETFASTINT (read_kbd, 0);
}
{
int timeout_reduced_for_timers = 0;
+#ifdef HAVE_X_WINDOWS
+ if (display_busy_cursor_p)
+ Fx_hide_busy_cursor (Qnil);
+#endif
+
/* If calling from keyboard input, do not quit
since we want to return C-g as an input character.
Otherwise, do pending quit if requested. */
clear_waiting_for_input ();
/* If we woke up due to SIGWINCH, actually change size now. */
- do_pending_window_change ();
+ do_pending_window_change (0);
if (time_limit && nfds == 0 && ! timeout_reduced_for_timers)
/* We wanted the full specified time, so return now. */
/* If checking input just got us a size-change event from X,
obey it now if we should. */
if (XINT (read_kbd) || wait_for_cell)
- do_pending_window_change ();
+ do_pending_window_change (0);
/* Check for data from a process. */
/* Really FIRST_PROC_DESC should be 0 on Unix,
Turn periodic alarms back on */
start_polling ();
#endif
+
+#ifdef HAVE_X_WINDOWS
+ if (display_busy_cursor_p)
+ if (!inhibit_busy_cursor)
+ Fx_show_busy_cursor ();
+#endif
return got_some_input;
}
read_process_output_call (fun_and_args)
Lisp_Object fun_and_args;
{
- return apply1 (XCONS (fun_and_args)->car, XCONS (fun_and_args)->cdr);
+ return apply1 (XCAR (fun_and_args), XCDR (fun_and_args));
}
static Lisp_Object
if (vs)
{
if (!vs->iosb[0])
- return(0); /* Really weird if it does this */
+ return (0); /* Really weird if it does this */
if (!(vs->iosb[0] & 1))
return -1; /* I/O error */
}
/* At this point, NBYTES holds number of characters just received
(including the one in proc_buffered_char[channel]). */
- if (nbytes <= 0) return nbytes;
+ if (nbytes <= 0)
+ {
+ if (nbytes < 0 || coding->mode & CODING_MODE_LAST_BLOCK)
+ return nbytes;
+ coding->mode |= CODING_MODE_LAST_BLOCK;
+ }
/* Now set NBYTES how many bytes we must decode. */
nbytes += carryover;
Lisp_Object obuffer, okeymap;
Lisp_Object text;
int outer_running_asynch_code = running_asynch_code;
+ int waiting = waiting_for_user_input_p;
/* No need to gcpro these, because all we do with them later
is test them for EQness, and none of them should be a string. */
save the match data in a special nonrecursive fashion. */
running_asynch_code = 1;
- text = make_string_from_bytes (chars, nchars, nbytes);
+ /* The multibyteness of a string given to the filter is decided
+ by which coding system we used for decoding. */
+ if (coding->type == coding_type_no_conversion
+ || coding->type == coding_type_raw_text)
+ text = make_unibyte_string (chars, nbytes);
+ else
+ text = make_multibyte_string (chars, nchars, nbytes);
+
internal_condition_case_1 (read_process_output_call,
Fcons (outstream,
Fcons (proc, Fcons (text, Qnil))),
/* Handling the process output should not deactivate the mark. */
Vdeactivate_mark = odeactivate;
+ /* Restore waiting_for_user_input_p as it was
+ when we were called, in case the filter clobbered it. */
+ waiting_for_user_input_p = waiting;
+
#if 0 /* Call record_asynch_buffer_change unconditionally,
because we might have changed minor modes or other things
that affect key bindings. */
insert_before_markers (temp_buf, nbytes);
}
else
- insert_1_both (chars, nchars, nbytes, 0, 1, 1);
+ {
+ insert_1_both (chars, nchars, nbytes, 0, 1, 1);
+ signal_after_change (opoint, 0, PT - opoint);
+ }
set_marker_both (p->mark, p->buffer, PT, PT_BYTE);
update_mode_lines++;
/* 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. */
+ care about relocation. */
offset = (BUFFERP (object)
? BUF_PTR_BYTE_POS (XBUFFER (object), buf)
: (STRINGP (object)
- ? offset = buf - XSTRING (object)->data
+ ? buf - XSTRING (object)->data
: -1));
if (carryover > 0)
buf = BUF_BYTE_ADDRESS (XBUFFER (object), offset);
else if (STRINGP (object))
buf = offset + XSTRING (object)->data;
- /* Now we don't have to care relocation. */
+ /* Now we don't have to care about relocation. */
offset = -1;
}
bcopy ((XSTRING (XPROCESS (proc)->encoding_buf)->data
return Qnil;
}
\f
+DEFUN ("process-running-child-p", Fprocess_running_child_p,
+ Sprocess_running_child_p, 0, 1, 0,
+ "Return t if PROCESS has given the terminal to a child.\n\
+If the operating system does not make it possible to find out,\n\
+return t unconditionally.")
+ (process)
+ Lisp_Object process;
+{
+ /* Initialize in case ioctl doesn't exist or gives an error,
+ in a way that will cause returning t. */
+ int gid = 0;
+ Lisp_Object proc;
+ struct Lisp_Process *p;
+
+ proc = get_process (process);
+ p = XPROCESS (proc);
+
+ if (!EQ (p->childp, Qt))
+ error ("Process %s is not a subprocess",
+ XSTRING (p->name)->data);
+ if (XINT (p->infd) < 0)
+ error ("Process %s is not active",
+ XSTRING (p->name)->data);
+
+#ifdef TIOCGPGRP
+ if (!NILP (p->subtty))
+ ioctl (XFASTINT (p->subtty), TIOCGPGRP, &gid);
+ else
+ ioctl (XINT (p->infd), TIOCGPGRP, &gid);
+#endif /* defined (TIOCGPGRP ) */
+
+ if (gid == XFASTINT (p->pid))
+ return Qnil;
+ return Qt;
+}
+\f
/* send a signal number SIGNO to PROCESS.
- CURRENT_GROUP means send to the process group that currently owns
- the terminal being used to communicate with PROCESS.
+ If CURRENT_GROUP is t, that means send to the process group
+ that currently owns the terminal being used to communicate with PROCESS.
This is used for various commands in shell mode.
+ If CURRENT_GROUP is lambda, that means send to the process group
+ that currently owns the terminal, but only if it is NOT the shell itself.
+
If NOMSG is zero, insert signal-announcements into process's buffers
right away.
the child itself heads the pgrp. */
gid = - XFASTINT (p->pid);
#endif /* ! defined (TIOCGPGRP ) */
+
+ /* If current_group is lambda, and the shell owns the terminal,
+ don't send any signal. */
+ if (EQ (current_group, Qlambda) && gid == - XFASTINT (p->pid))
+ return;
}
else
gid = - XFASTINT (p->pid);
the current process-group of the process's controlling terminal\n\
rather than to the process's own process group.\n\
If the process is a shell, this means interrupt current subjob\n\
-rather than the shell.")
+rather than the shell.\n\
+\n\
+If CURRENT-GROUP is `lambda', and if the shell owns the terminal,\n\
+don't send the signal.")
(process, current_group)
Lisp_Object process, current_group;
{
Lisp_Object process;
{
Lisp_Object proc;
+ struct coding_system *coding;
proc = get_process (process);
+ coding = proc_encode_coding_system[XINT (XPROCESS (proc)->outfd)];
/* Make sure the process is really alive. */
if (! NILP (XPROCESS (proc)->raw_status_low))
if (! EQ (XPROCESS (proc)->status, Qrun))
error ("Process %s not running", XSTRING (XPROCESS (proc)->name)->data);
+ if (CODING_REQUIRE_FLUSHING (coding))
+ {
+ coding->mode |= CODING_MODE_LAST_BLOCK;
+ send_process (proc, "", 0, Qnil);
+ }
+
#ifdef VMS
send_process (proc, "\032", 1, Qnil); /* ^z */
#else
{
Lisp_Object tail, proc;
- for (tail = Vprocess_alist; GC_CONSP (tail); tail = XCONS (tail)->cdr)
+ for (tail = Vprocess_alist; GC_CONSP (tail); tail = XCDR (tail))
{
- proc = XCONS (XCONS (tail)->car)->cdr;
+ proc = XCDR (XCAR (tail));
if (GC_PROCESSP (proc)
&& (NILP (buffer) || EQ (XPROCESS (proc)->buffer, buffer)))
{
/* Find the process that signaled us, and record its status. */
p = 0;
- for (tail = Vprocess_alist; CONSP (tail); tail = XCONS (tail)->cdr)
+ for (tail = Vprocess_alist; CONSP (tail); tail = XCDR (tail))
{
- proc = XCONS (XCONS (tail)->car)->cdr;
+ proc = XCDR (XCAR (tail));
p = XPROCESS (proc);
if (EQ (p->childp, Qt) && XFASTINT (p->pid) == pid)
break;
/* Look for an asynchronous process whose pid hasn't been filled
in yet. */
if (p == 0)
- for (tail = Vprocess_alist; CONSP (tail); tail = XCONS (tail)->cdr)
+ for (tail = Vprocess_alist; CONSP (tail); tail = XCDR (tail))
{
- proc = XCONS (XCONS (tail)->car)->cdr;
+ proc = XCDR (XCAR (tail));
p = XPROCESS (proc);
if (INTEGERP (p->pid) && XINT (p->pid) == -1)
break;
exec_sentinel_unwind (data)
Lisp_Object data;
{
- XPROCESS (XCONS (data)->car)->sentinel = XCONS (data)->cdr;
+ XPROCESS (XCAR (data))->sentinel = XCDR (data);
return Qnil;
}
register struct Lisp_Process *p = XPROCESS (proc);
int count = specpdl_ptr - specpdl;
int outer_running_asynch_code = running_asynch_code;
+ int waiting = waiting_for_user_input_p;
/* No need to gcpro these, because all we do with them later
is test them for EQness, and none of them should be a string. */
running_asynch_code = outer_running_asynch_code;
Vdeactivate_mark = odeactivate;
+
+ /* Restore waiting_for_user_input_p as it was
+ when we were called, in case the filter clobbered it. */
+ waiting_for_user_input_p = waiting;
+
#if 0
if (! EQ (Fcurrent_buffer (), obuffer)
|| ! EQ (current_buffer->keymap, okeymap))
/* If process is terminated, deactivate it or delete it. */
symbol = p->status;
if (CONSP (p->status))
- symbol = XCONS (p->status)->car;
+ symbol = XCAR (p->status);
if (EQ (symbol, Qsignal) || EQ (symbol, Qexit)
|| EQ (symbol, Qclosed))
defsubr (&Squit_process);
defsubr (&Sstop_process);
defsubr (&Scontinue_process);
+ defsubr (&Sprocess_running_child_p);
defsubr (&Sprocess_send_eof);
defsubr (&Ssignal_process);
defsubr (&Swaiting_for_user_input_p);
/* If waiting for non-nil in a cell, record where. */
if (CONSP (read_kbd))
{
- wait_for_cell = &XCONS (read_kbd)->car;
+ wait_for_cell = &XCAR (read_kbd);
XSETFASTINT (read_kbd, 0);
}
clear_waiting_for_input ();
/* If we woke up due to SIGWINCH, actually change size now. */
- do_pending_window_change ();
+ do_pending_window_change (0);
if (time_limit && nfds == 0 && ! timeout_reduced_for_timers)
/* We waited the full specified time, so return now. */