#include <config.h>
#include <signal.h>
-
-/* This file is split into two parts by the following preprocessor
- conditional. The 'then' clause contains all of the support for
- asynchronous subprocesses. The 'else' clause contains stub
- versions of some of the asynchronous subprocess routines that are
- often called elsewhere in Emacs, so we don't have to #ifdef the
- sections that call them. */
-
-\f
-#ifdef subprocesses
-
#include <stdio.h>
#include <errno.h>
#include <setjmp.h>
#endif
#include <fcntl.h>
-#ifdef HAVE_SOCKETS /* TCP connection support, if kernel can do it */
+/* Only MS-DOS does not define `subprocesses'. */
+#ifdef subprocesses
+
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <sys/un.h>
#endif
#endif
-#endif /* HAVE_SOCKETS */
#if defined(HAVE_SYS_IOCTL_H)
#include <sys/ioctl.h>
#if !defined (O_NDELAY) && defined (HAVE_PTYS) && !defined(USG5)
#include <fcntl.h>
#endif /* HAVE_PTYS and no O_NDELAY */
+#if defined(HAVE_NET_IF_H)
+#include <net/if.h>
+#endif /* HAVE_NET_IF_H */
#endif /* HAVE_SYS_IOCTL_H */
#ifdef NEED_BSDTTY
#include <bsdtty.h>
#endif
-/* Can we use SIOCGIFCONF and/or SIOCGIFADDR */
-#ifdef HAVE_SOCKETS
-#if defined(HAVE_SYS_IOCTL_H) && defined(HAVE_NET_IF_H)
-/* sys/ioctl.h may have been included already */
-#ifndef SIOCGIFADDR
-#include <sys/ioctl.h>
-#endif
-#include <net/if.h>
-#endif
-#endif
-
#ifdef HAVE_SYS_WAIT
#include <sys/wait.h>
#endif
#include <resolv.h>
#endif
+#ifdef HAVE_UTIL_H
+#include <util.h>
+#endif
+
+#endif /* subprocesses */
+
#include "lisp.h"
#include "systime.h"
#include "systty.h"
#include "dispextern.h"
#include "composite.h"
#include "atimer.h"
+#include "sysselect.h"
+#include "syssignal.h"
+#include "syswait.h"
#if defined (USE_GTK) || defined (HAVE_GCONF)
#include "xgselect.h"
#endif /* defined (USE_GTK) || defined (HAVE_GCONF) */
+#ifdef HAVE_NS
+#include "nsterm.h"
+#endif
+extern int timers_run;
+
+Lisp_Object Qeuid, Qegid, Qcomm, Qstate, Qppid, Qpgrp, Qsess, Qttname, Qtpgid;
+Lisp_Object Qminflt, Qmajflt, Qcminflt, Qcmajflt, Qutime, Qstime, Qcstime;
+Lisp_Object Qcutime, Qpri, Qnice, Qthcount, Qstart, Qvsize, Qrss, Qargs;
+Lisp_Object Quser, Qgroup, Qetime, Qpcpu, Qpmem, Qtime, Qctime;
+Lisp_Object QCname, QCtype;
+\f
+/* Non-zero if keyboard input is on hold, zero otherwise. */
+
+static int kbd_is_on_hold;
+
+/* Nonzero means delete a process right away if it exits. */
+static int delete_exited_processes;
+
+/* Nonzero means don't run process sentinels. This is used
+ when exiting. */
+int inhibit_sentinels;
+
+#ifdef subprocesses
Lisp_Object Qprocessp;
Lisp_Object Qrun, Qstop, Qsignal;
Lisp_Object QCport, QCspeed, QCprocess;
Lisp_Object QCbytesize, QCstopbits, QCparity, Qodd, Qeven;
Lisp_Object QCflowcontrol, Qhw, Qsw, QCsummary;
-Lisp_Object QCname, QCbuffer, QChost, QCservice, QCtype;
+Lisp_Object QCbuffer, QChost, QCservice;
Lisp_Object QClocal, QCremote, QCcoding;
Lisp_Object QCserver, QCnowait, QCnoquery, QCstop;
Lisp_Object QCsentinel, QClog, QCoptions, QCplist;
/* QCfilter is defined in keyboard.c. */
extern Lisp_Object QCfilter;
-Lisp_Object Qeuid, Qegid, Qcomm, Qstate, Qppid, Qpgrp, Qsess, Qttname, Qtpgid;
-Lisp_Object Qminflt, Qmajflt, Qcminflt, Qcmajflt, Qutime, Qstime, Qcstime;
-Lisp_Object Qcutime, Qpri, Qnice, Qthcount, Qstart, Qvsize, Qrss, Qargs;
-Lisp_Object Quser, Qgroup, Qetime, Qpcpu, Qpmem, Qtime, Qctime;
-
-#ifdef HAVE_SOCKETS
#define NETCONN_P(p) (EQ (XPROCESS (p)->type, Qnetwork))
#define NETCONN1_P(p) (EQ ((p)->type, Qnetwork))
#define SERIALCONN_P(p) (EQ (XPROCESS (p)->type, Qserial))
#define SERIALCONN1_P(p) (EQ ((p)->type, Qserial))
-#else
-#define NETCONN_P(p) 0
-#define NETCONN1_P(p) 0
-#define SERIALCONN_P(p) 0
-#define SERIALCONN1_P(p) 0
-#endif /* HAVE_SOCKETS */
/* Define first descriptor number available for subprocesses. */
#define FIRST_PROC_DESC 3
#define SIGCHLD SIGCLD
#endif /* SIGCLD */
-#include "syssignal.h"
-
-#include "syswait.h"
-
-extern char *get_operating_system_release (void);
+extern const char *get_operating_system_release (void);
/* Serial processes require termios or Windows. */
#if defined (HAVE_TERMIOS) || defined (WINDOWSNT)
#undef NON_BLOCKING_CONNECT
#else
#ifndef NON_BLOCKING_CONNECT
-#ifdef HAVE_SOCKETS
#ifdef HAVE_SELECT
#if defined (HAVE_GETPEERNAME) || defined (GNU_LINUX)
#if defined (O_NONBLOCK) || defined (O_NDELAY)
#endif /* O_NONBLOCK || O_NDELAY */
#endif /* HAVE_GETPEERNAME || GNU_LINUX */
#endif /* HAVE_SELECT */
-#endif /* HAVE_SOCKETS */
#endif /* NON_BLOCKING_CONNECT */
#endif /* BROKEN_NON_BLOCKING_CONNECT */
#undef DATAGRAM_SOCKETS
#else
#ifndef DATAGRAM_SOCKETS
-#ifdef HAVE_SOCKETS
#if defined (HAVE_SELECT) || defined (FIONREAD)
#if defined (HAVE_SENDTO) && defined (HAVE_RECVFROM) && defined (EMSGSIZE)
#define DATAGRAM_SOCKETS
#endif /* HAVE_SENDTO && HAVE_RECVFROM && EMSGSIZE */
#endif /* HAVE_SELECT || FIONREAD */
-#endif /* HAVE_SOCKETS */
#endif /* DATAGRAM_SOCKETS */
#endif /* BROKEN_DATAGRAM_SOCKETS */
#define process_output_delay_count 0
#endif
-
-#include "sysselect.h"
-
static int keyboard_bit_set (SELECT_TYPE *);
static void deactivate_process (Lisp_Object);
static void status_notify (struct Lisp_Process *);
static Lisp_Object get_process (register Lisp_Object name);
static void exec_sentinel (Lisp_Object proc, Lisp_Object reason);
-extern int timers_run;
-\f
/* Mask of bits indicating the descriptors that we wait for input on. */
static SELECT_TYPE input_wait_mask;
-/* Non-zero if keyboard input is on hold, zero otherwise. */
-
-static int kbd_is_on_hold;
-
/* Mask that excludes keyboard input descriptor(s). */
static SELECT_TYPE non_keyboard_wait_mask;
static int num_pending_connects;
#define IF_NON_BLOCKING_CONNECT(s) s
-#else
+#else /* NON_BLOCKING_CONNECT */
#define IF_NON_BLOCKING_CONNECT(s)
-#endif
+#endif /* NON_BLOCKING_CONNECT */
/* The largest descriptor currently in use for a process object. */
static int max_process_desc;
/* The largest descriptor currently in use for gpm mouse input. */
static int max_gpm_desc;
-/* Nonzero means delete a process right away if it exits. */
-static int delete_exited_processes;
-
/* Indexed by descriptor, gives the process (if any) for that descriptor */
Lisp_Object chan_process[MAXDESC];
/* Maximum number of bytes to send to a pty without an eof. */
static int pty_max_bytes;
-/* Nonzero means don't run process sentinels. This is used
- when exiting. */
-int inhibit_sentinels;
-
#ifdef HAVE_PTYS
#ifdef HAVE_PTY_H
#include <pty.h>
deactivate_process (proc);
}
-/* Setup coding systems of PROCESS. */
-
-void
-setup_process_coding_systems (Lisp_Object process)
-{
- struct Lisp_Process *p = XPROCESS (process);
- int inch = p->infd;
- int outch = p->outfd;
- Lisp_Object coding_system;
-
- if (inch < 0 || outch < 0)
- return;
-
- if (!proc_decode_coding_system[inch])
- proc_decode_coding_system[inch]
- = (struct coding_system *) xmalloc (sizeof (struct coding_system));
- coding_system = p->decode_coding_system;
- if (! NILP (p->filter))
- ;
- else if (BUFFERP (p->buffer))
- {
- if (NILP (XBUFFER (p->buffer)->enable_multibyte_characters))
- coding_system = raw_text_coding_system (coding_system);
- }
- setup_coding_system (coding_system, proc_decode_coding_system[inch]);
-
- if (!proc_encode_coding_system[outch])
- proc_encode_coding_system[outch]
- = (struct coding_system *) xmalloc (sizeof (struct coding_system));
- setup_coding_system (p->encode_coding_system,
- proc_encode_coding_system[outch]);
-}
\f
DEFUN ("processp", Fprocessp, Sprocessp, 1, 1, 0,
doc: /* Return t if OBJECT is a process. */)
return Fcdr (Fassoc (name, Vprocess_alist));
}
-DEFUN ("get-buffer-process", Fget_buffer_process, Sget_buffer_process, 1, 1, 0,
- doc: /* Return the (or a) process associated with BUFFER.
-BUFFER may be a buffer or the name of one. */)
- (register Lisp_Object buffer)
-{
- register Lisp_Object buf, tail, proc;
-
- if (NILP (buffer)) return Qnil;
- buf = Fget_buffer (buffer);
- if (NILP (buf)) return Qnil;
-
- for (tail = Vprocess_alist; CONSP (tail); tail = XCDR (tail))
- {
- proc = Fcdr (XCAR (tail));
- if (PROCESSP (proc) && EQ (XPROCESS (proc)->buffer, buf))
- return proc;
- }
- return Qnil;
-}
-
/* This is how commands for the user decode process arguments. It
accepts a process, a process name, a buffer, a buffer name, or nil.
Buffers denote the first process in the buffer, and nil denotes the
return flag;
}
-DEFUN ("process-inherit-coding-system-flag",
- Fprocess_inherit_coding_system_flag, Sprocess_inherit_coding_system_flag,
- 1, 1, 0,
- doc: /* Return the value of inherit-coding-system flag for PROCESS.
-If this flag is t, `buffer-file-coding-system' of the buffer
-associated with PROCESS will inherit the coding system used to decode
-the process output. */)
- (register Lisp_Object process)
-{
- CHECK_PROCESS (process);
- return XPROCESS (process)->inherit_coding_system_flag ? Qt : Qnil;
-}
-
DEFUN ("set-process-query-on-exit-flag",
Fset_process_query_on_exit_flag, Sset_process_query_on_exit_flag,
2, 2, 0,
return XPROCESS (proc)->type;
}
-#ifdef HAVE_SOCKETS
DEFUN ("format-network-address", Fformat_network_address, Sformat_network_address,
1, 2, 0,
doc: /* Convert network ADDRESS from internal format to a string.
return Qnil;
}
-#endif
\f
static Lisp_Object
list_processes_1 (Lisp_Object query_only)
}
-#if 0 /* This doesn't work; see the note before sigchld_handler. */
-#ifdef USG
-#ifdef SIGCHLD
-/* Mimic blocking of signals on system V, which doesn't really have it. */
-
-/* Nonzero means we got a SIGCHLD when it was supposed to be blocked. */
-int sigchld_deferred;
-
-SIGTYPE
-create_process_sigchld ()
-{
- signal (SIGCHLD, create_process_sigchld);
-
- sigchld_deferred = 1;
-}
-#endif
-#endif
-#endif
-
void
create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
{
}
\f
-#ifdef HAVE_SOCKETS
-
/* Convert an internal struct sockaddr to a lisp object (vector or string).
The address family of sa is not included in the result. */
/* Workaround for a bug in getsockname on BSD: Names bound to
sockets in the UNIX domain are inaccessible; getsockname returns
a zero length name. */
- if (len < OFFSETOF (struct sockaddr, sa_family) + sizeof (sa->sa_family))
+ if (len < offsetof (struct sockaddr, sa_family) + sizeof (sa->sa_family))
return empty_unibyte_string;
switch (sa->sa_family)
}
#endif
default:
- len -= OFFSETOF (struct sockaddr, sa_family) + sizeof (sa->sa_family);
+ len -= offsetof (struct sockaddr, sa_family) + sizeof (sa->sa_family);
address = Fcons (make_number (sa->sa_family),
Fmake_vector (make_number (len), Qnil));
p = XVECTOR (XCDR (address));
static const struct socket_options {
/* The name of this option. Should be lowercase version of option
name without SO_ prefix. */
- char *name;
+ const char *name;
/* Option level SOL_... */
int optlevel;
/* Option number SO_... */
#ifdef HAVE_GETADDRINFO
struct addrinfo ai, *res, *lres;
struct addrinfo hints;
- char *portstring, portbuf[128];
+ const char *portstring;
+ char portbuf[128];
#else /* HAVE_GETADDRINFO */
struct _emacs_addrinfo
{
UNGCPRO;
return proc;
}
-#endif /* HAVE_SOCKETS */
\f
-#if defined(HAVE_SOCKETS) && defined(HAVE_NET_IF_H) && defined(HAVE_SYS_IOCTL_H)
+#if defined(HAVE_NET_IF_H) && defined(HAVE_SYS_IOCTL_H)
#ifdef SIOCGIFCONF
DEFUN ("network-interface-list", Fnetwork_interface_list, Snetwork_interface_list, 0, 0, 0,
return any ? res : Qnil;
}
#endif
-#endif /* HAVE_SOCKETS */
+#endif /* defined(HAVE_NET_IF_H) && defined(HAVE_SYS_IOCTL_H) */
/* Turn off input and output for process PROC. */
}
}
-/* Close all descriptors currently in use for communication
- with subprocess. This is used in a newly-forked subprocess
- to get rid of irrelevant descriptors. */
-
-void
-close_process_descs (void)
-{
-#ifndef WINDOWSNT
- int i;
- for (i = 0; i < MAXDESC; i++)
- {
- Lisp_Object process;
- process = chan_process[i];
- if (!NILP (process))
- {
- int in = XPROCESS (process)->infd;
- int out = XPROCESS (process)->outfd;
- if (in >= 0)
- emacs_close (in);
- if (out >= 0 && in != out)
- emacs_close (out);
- }
- }
-#endif
-}
\f
DEFUN ("accept-process-output", Faccept_process_output, Saccept_process_output,
0, 4, 0,
Otherwise, return true if we received input from any process. */
int
-wait_reading_process_output (time_limit, microsecs, read_kbd, do_display,
- wait_for_cell, wait_proc, just_wait_proc)
- int time_limit, microsecs, read_kbd, do_display;
- Lisp_Object wait_for_cell;
- struct Lisp_Process *wait_proc;
- int just_wait_proc;
+wait_reading_process_output (int time_limit, int microsecs, int read_kbd,
+ int do_display,
+ Lisp_Object wait_for_cell,
+ struct Lisp_Process *wait_proc, int just_wait_proc)
{
register int channel, nfds;
SELECT_TYPE Available;
unbind_to (count, Qnil);
return nbytes;
}
-
-DEFUN ("waiting-for-user-input-p", Fwaiting_for_user_input_p, Swaiting_for_user_input_p,
- 0, 0, 0,
- doc: /* Returns non-nil if Emacs is waiting for input from the user.
-This is intended for use by asynchronous process output filters and sentinels. */)
- (void)
-{
- return (waiting_for_user_input_p ? Qt : Qnil);
-}
\f
/* Sending data to subprocess */
This function can evaluate Lisp code and can garbage collect. */
static void
-send_process (volatile Lisp_Object proc, unsigned char *volatile buf,
+send_process (volatile Lisp_Object proc, const unsigned char *volatile buf,
volatile int len, volatile Lisp_Object object)
{
/* Use volatile to protect variables from being clobbered by longjmp. */
traffic. */)
(Lisp_Object process, Lisp_Object current_group)
{
-#ifdef HAVE_SOCKETS
if (PROCESSP (process) && (NETCONN_P (process) || SERIALCONN_P (process)))
{
struct Lisp_Process *p;
p->command = Qt;
return process;
}
-#endif
#ifndef SIGTSTP
error ("No SIGTSTP support");
#else
traffic. */)
(Lisp_Object process, Lisp_Object current_group)
{
-#ifdef HAVE_SOCKETS
if (PROCESSP (process) && (NETCONN_P (process) || SERIALCONN_P (process)))
{
struct Lisp_Process *p;
p->command = Qnil;
return process;
}
-#endif
#ifdef SIGCONT
process_send_signal (process, SIGCONT, current_group, 0);
#else
}
return process;
}
-
-/* Kill all processes associated with `buffer'.
- If `buffer' is nil, kill all processes */
-
-void
-kill_buffer_processes (Lisp_Object buffer)
-{
- Lisp_Object tail, proc;
-
- for (tail = Vprocess_alist; CONSP (tail); tail = XCDR (tail))
- {
- proc = XCDR (XCAR (tail));
- if (PROCESSP (proc)
- && (NILP (buffer) || EQ (XPROCESS (proc)->buffer, buffer)))
- {
- if (NETCONN_P (proc) || SERIALCONN_P (proc))
- Fdelete_process (proc);
- else if (XPROCESS (proc)->infd >= 0)
- process_send_signal (proc, SIGHUP, Qnil, 1);
- }
- }
-}
\f
/* On receipt of a signal that a child status has changed, loop asking
about children with changed statuses until the system says there
{
int old_errno = errno;
Lisp_Object proc;
- register struct Lisp_Process *p;
- extern EMACS_TIME *input_available_clear_time;
+ struct Lisp_Process *p;
SIGNAL_THREAD_CHECK (signo);
\f
-/* Stop reading input from keyboard sources. */
-
-void
-hold_keyboard_input (void)
-{
- kbd_is_on_hold = 1;
-}
-
-/* Resume reading input from keyboard sources. */
-
-void
-unhold_keyboard_input (void)
-{
- kbd_is_on_hold = 0;
-}
-
-/* Return non-zero if keyboard input is on hold, zero otherwise. */
-
-int
-kbd_on_hold_p (void)
-{
- return kbd_is_on_hold;
-}
-
-/* Add DESC to the set of keyboard input descriptors. */
-
-void
-add_keyboard_wait_descriptor (int desc)
-{
- FD_SET (desc, &input_wait_mask);
- FD_SET (desc, &non_process_wait_mask);
- if (desc > max_keyboard_desc)
- max_keyboard_desc = desc;
-}
static int add_gpm_wait_descriptor_called_flag;
max_gpm_desc = desc;
}
-/* From now on, do not expect DESC to give keyboard input. */
-
void
-delete_keyboard_wait_descriptor (int desc)
+delete_gpm_wait_descriptor (int desc)
{
int fd;
- int lim = max_keyboard_desc;
+ int lim = max_gpm_desc;
FD_CLR (desc, &input_wait_mask);
FD_CLR (desc, &non_process_wait_mask);
- if (desc == max_keyboard_desc)
+ if (desc == max_gpm_desc)
for (fd = 0; fd < lim; fd++)
if (FD_ISSET (fd, &input_wait_mask)
&& !FD_ISSET (fd, &non_keyboard_wait_mask)
- && !FD_ISSET (fd, &gpm_wait_mask))
- max_keyboard_desc = fd;
+ && !FD_ISSET (fd, &non_process_wait_mask))
+ max_gpm_desc = fd;
}
-void
-delete_gpm_wait_descriptor (int desc)
-{
- int fd;
- int lim = max_gpm_desc;
-
- FD_CLR (desc, &input_wait_mask);
- FD_CLR (desc, &non_process_wait_mask);
-
- if (desc == max_gpm_desc)
- for (fd = 0; fd < lim; fd++)
- if (FD_ISSET (fd, &input_wait_mask)
- && !FD_ISSET (fd, &non_keyboard_wait_mask)
- && !FD_ISSET (fd, &non_process_wait_mask))
- max_gpm_desc = fd;
-}
-
-/* Return nonzero if *MASK has a bit set
- that corresponds to one of the keyboard input descriptors. */
-
-static int
-keyboard_bit_set (fd_set *mask)
-{
- int fd;
-
- for (fd = 0; fd <= max_keyboard_desc; fd++)
- if (FD_ISSET (fd, mask) && FD_ISSET (fd, &input_wait_mask)
- && !FD_ISSET (fd, &non_keyboard_wait_mask))
- return 1;
-
- return 0;
-}
-\f
-/* Enumeration of and access to system processes a-la ps(1). */
-
-DEFUN ("list-system-processes", Flist_system_processes, Slist_system_processes,
- 0, 0, 0,
- doc: /* Return a list of numerical process IDs of all running processes.
-If this functionality is unsupported, return nil.
-
-See `process-attributes' for getting attributes of a process given its ID. */)
- (void)
-{
- return list_system_processes ();
-}
-
-DEFUN ("process-attributes", Fprocess_attributes,
- Sprocess_attributes, 1, 1, 0,
- doc: /* Return attributes of the process given by its PID, a number.
-
-Value is an alist where each element is a cons cell of the form
-
- \(KEY . VALUE)
-
-If this functionality is unsupported, the value is nil.
-
-See `list-system-processes' for getting a list of all process IDs.
-
-The KEYs of the attributes that this function may return are listed
-below, together with the type of the associated VALUE (in parentheses).
-Not all platforms support all of these attributes; unsupported
-attributes will not appear in the returned alist.
-Unless explicitly indicated otherwise, numbers can have either
-integer or floating point values.
-
- euid -- Effective user User ID of the process (number)
- user -- User name corresponding to euid (string)
- egid -- Effective user Group ID of the process (number)
- group -- Group name corresponding to egid (string)
- comm -- Command name (executable name only) (string)
- state -- Process state code, such as "S", "R", or "T" (string)
- ppid -- Parent process ID (number)
- pgrp -- Process group ID (number)
- sess -- Session ID, i.e. process ID of session leader (number)
- ttname -- Controlling tty name (string)
- tpgid -- ID of foreground process group on the process's tty (number)
- minflt -- number of minor page faults (number)
- majflt -- number of major page faults (number)
- cminflt -- cumulative number of minor page faults (number)
- cmajflt -- cumulative number of major page faults (number)
- utime -- user time used by the process, in the (HIGH LOW USEC) format
- stime -- system time used by the process, in the (HIGH LOW USEC) format
- time -- sum of utime and stime, in the (HIGH LOW USEC) format
- cutime -- user time used by the process and its children, (HIGH LOW USEC)
- cstime -- system time used by the process and its children, (HIGH LOW USEC)
- ctime -- sum of cutime and cstime, in the (HIGH LOW USEC) format
- pri -- priority of the process (number)
- nice -- nice value of the process (number)
- thcount -- process thread count (number)
- start -- time the process started, in the (HIGH LOW USEC) format
- vsize -- virtual memory size of the process in KB's (number)
- rss -- resident set size of the process in KB's (number)
- etime -- elapsed time the process is running, in (HIGH LOW USEC) format
- pcpu -- percents of CPU time used by the process (floating-point number)
- pmem -- percents of total physical memory used by process's resident set
- (floating-point number)
- args -- command line which invoked the process (string). */)
- ( Lisp_Object pid)
-{
- return system_process_attributes (pid);
-}
-\f
-void
-init_process (void)
-{
- register int i;
-
- inhibit_sentinels = 0;
-
-#ifdef SIGCHLD
-#ifndef CANNOT_DUMP
- if (! noninteractive || initialized)
-#endif
- signal (SIGCHLD, sigchld_handler);
-#endif
-
- FD_ZERO (&input_wait_mask);
- FD_ZERO (&non_keyboard_wait_mask);
- FD_ZERO (&non_process_wait_mask);
- max_process_desc = 0;
-
-#ifdef NON_BLOCKING_CONNECT
- FD_ZERO (&connect_wait_mask);
- num_pending_connects = 0;
-#endif
-
-#ifdef ADAPTIVE_READ_BUFFERING
- process_output_delay_count = 0;
- process_output_skip = 0;
-#endif
-
- /* Don't do this, it caused infinite select loops. The display
- method should call add_keyboard_wait_descriptor on stdin if it
- needs that. */
-#if 0
- FD_SET (0, &input_wait_mask);
-#endif
-
- Vprocess_alist = Qnil;
-#ifdef SIGCHLD
- deleted_pid_list = Qnil;
-#endif
- for (i = 0; i < MAXDESC; i++)
- {
- chan_process[i] = Qnil;
- proc_buffered_char[i] = -1;
- }
- memset (proc_decode_coding_system, 0, sizeof proc_decode_coding_system);
- memset (proc_encode_coding_system, 0, sizeof proc_encode_coding_system);
-#ifdef DATAGRAM_SOCKETS
- memset (datagram_address, 0, sizeof datagram_address);
-#endif
-
-#ifdef HAVE_SOCKETS
- {
- Lisp_Object subfeatures = Qnil;
- const struct socket_options *sopt;
-
-#define ADD_SUBFEATURE(key, val) \
- subfeatures = pure_cons (pure_cons (key, pure_cons (val, Qnil)), subfeatures)
-
-#ifdef NON_BLOCKING_CONNECT
- ADD_SUBFEATURE (QCnowait, Qt);
-#endif
-#ifdef DATAGRAM_SOCKETS
- ADD_SUBFEATURE (QCtype, Qdatagram);
-#endif
-#ifdef HAVE_SEQPACKET
- ADD_SUBFEATURE (QCtype, Qseqpacket);
-#endif
-#ifdef HAVE_LOCAL_SOCKETS
- ADD_SUBFEATURE (QCfamily, Qlocal);
-#endif
- ADD_SUBFEATURE (QCfamily, Qipv4);
-#ifdef AF_INET6
- ADD_SUBFEATURE (QCfamily, Qipv6);
-#endif
-#ifdef HAVE_GETSOCKNAME
- ADD_SUBFEATURE (QCservice, Qt);
-#endif
-#if defined(O_NONBLOCK) || defined(O_NDELAY)
- ADD_SUBFEATURE (QCserver, Qt);
-#endif
-
- for (sopt = socket_options; sopt->name; sopt++)
- subfeatures = pure_cons (intern_c_string (sopt->name), subfeatures);
-
- Fprovide (intern_c_string ("make-network-process"), subfeatures);
- }
-#endif /* HAVE_SOCKETS */
-
-#if defined (DARWIN_OS)
- /* PTYs are broken on Darwin < 6, but are sometimes useful for interactive
- processes. As such, we only change the default value. */
- if (initialized)
- {
- char *release = get_operating_system_release ();
- if (!release || !release[0] || (release[0] < MIN_PTY_KERNEL_VERSION
- && release[1] == '.')) {
- Vprocess_connection_type = Qnil;
- }
- }
-#endif
-}
-
-void
-syms_of_process (void)
-{
- Qprocessp = intern_c_string ("processp");
- staticpro (&Qprocessp);
- Qrun = intern_c_string ("run");
- staticpro (&Qrun);
- Qstop = intern_c_string ("stop");
- staticpro (&Qstop);
- Qsignal = intern_c_string ("signal");
- staticpro (&Qsignal);
-
- /* Qexit is already staticpro'd by syms_of_eval; don't staticpro it
- here again.
-
- Qexit = intern_c_string ("exit");
- staticpro (&Qexit); */
-
- Qopen = intern_c_string ("open");
- staticpro (&Qopen);
- Qclosed = intern_c_string ("closed");
- staticpro (&Qclosed);
- Qconnect = intern_c_string ("connect");
- staticpro (&Qconnect);
- Qfailed = intern_c_string ("failed");
- staticpro (&Qfailed);
- Qlisten = intern_c_string ("listen");
- staticpro (&Qlisten);
- Qlocal = intern_c_string ("local");
- staticpro (&Qlocal);
- Qipv4 = intern_c_string ("ipv4");
- staticpro (&Qipv4);
-#ifdef AF_INET6
- Qipv6 = intern_c_string ("ipv6");
- staticpro (&Qipv6);
-#endif
- Qdatagram = intern_c_string ("datagram");
- staticpro (&Qdatagram);
- Qseqpacket = intern_c_string ("seqpacket");
- staticpro (&Qseqpacket);
-
- QCport = intern_c_string (":port");
- staticpro (&QCport);
- QCspeed = intern_c_string (":speed");
- staticpro (&QCspeed);
- QCprocess = intern_c_string (":process");
- staticpro (&QCprocess);
-
- QCbytesize = intern_c_string (":bytesize");
- staticpro (&QCbytesize);
- QCstopbits = intern_c_string (":stopbits");
- staticpro (&QCstopbits);
- QCparity = intern_c_string (":parity");
- staticpro (&QCparity);
- Qodd = intern_c_string ("odd");
- staticpro (&Qodd);
- Qeven = intern_c_string ("even");
- staticpro (&Qeven);
- QCflowcontrol = intern_c_string (":flowcontrol");
- staticpro (&QCflowcontrol);
- Qhw = intern_c_string ("hw");
- staticpro (&Qhw);
- Qsw = intern_c_string ("sw");
- staticpro (&Qsw);
- QCsummary = intern_c_string (":summary");
- staticpro (&QCsummary);
-
- Qreal = intern_c_string ("real");
- staticpro (&Qreal);
- Qnetwork = intern_c_string ("network");
- staticpro (&Qnetwork);
- Qserial = intern_c_string ("serial");
- staticpro (&Qserial);
-
- QCname = intern_c_string (":name");
- staticpro (&QCname);
- QCbuffer = intern_c_string (":buffer");
- staticpro (&QCbuffer);
- QChost = intern_c_string (":host");
- staticpro (&QChost);
- QCservice = intern_c_string (":service");
- staticpro (&QCservice);
- QCtype = intern_c_string (":type");
- staticpro (&QCtype);
- QClocal = intern_c_string (":local");
- staticpro (&QClocal);
- QCremote = intern_c_string (":remote");
- staticpro (&QCremote);
- QCcoding = intern_c_string (":coding");
- staticpro (&QCcoding);
- QCserver = intern_c_string (":server");
- staticpro (&QCserver);
- QCnowait = intern_c_string (":nowait");
- staticpro (&QCnowait);
- QCsentinel = intern_c_string (":sentinel");
- staticpro (&QCsentinel);
- QClog = intern_c_string (":log");
- staticpro (&QClog);
- QCnoquery = intern_c_string (":noquery");
- staticpro (&QCnoquery);
- QCstop = intern_c_string (":stop");
- staticpro (&QCstop);
- QCoptions = intern_c_string (":options");
- staticpro (&QCoptions);
- QCplist = intern_c_string (":plist");
- staticpro (&QCplist);
-
- Qlast_nonmenu_event = intern_c_string ("last-nonmenu-event");
- staticpro (&Qlast_nonmenu_event);
-
- staticpro (&Vprocess_alist);
-#ifdef SIGCHLD
- staticpro (&deleted_pid_list);
-#endif
-
- Qeuid = intern_c_string ("euid");
- staticpro (&Qeuid);
- Qegid = intern_c_string ("egid");
- staticpro (&Qegid);
- Quser = intern_c_string ("user");
- staticpro (&Quser);
- Qgroup = intern_c_string ("group");
- staticpro (&Qgroup);
- Qcomm = intern_c_string ("comm");
- staticpro (&Qcomm);
- Qstate = intern_c_string ("state");
- staticpro (&Qstate);
- Qppid = intern_c_string ("ppid");
- staticpro (&Qppid);
- Qpgrp = intern_c_string ("pgrp");
- staticpro (&Qpgrp);
- Qsess = intern_c_string ("sess");
- staticpro (&Qsess);
- Qttname = intern_c_string ("ttname");
- staticpro (&Qttname);
- Qtpgid = intern_c_string ("tpgid");
- staticpro (&Qtpgid);
- Qminflt = intern_c_string ("minflt");
- staticpro (&Qminflt);
- Qmajflt = intern_c_string ("majflt");
- staticpro (&Qmajflt);
- Qcminflt = intern_c_string ("cminflt");
- staticpro (&Qcminflt);
- Qcmajflt = intern_c_string ("cmajflt");
- staticpro (&Qcmajflt);
- Qutime = intern_c_string ("utime");
- staticpro (&Qutime);
- Qstime = intern_c_string ("stime");
- staticpro (&Qstime);
- Qtime = intern_c_string ("time");
- staticpro (&Qtime);
- Qcutime = intern_c_string ("cutime");
- staticpro (&Qcutime);
- Qcstime = intern_c_string ("cstime");
- staticpro (&Qcstime);
- Qctime = intern_c_string ("ctime");
- staticpro (&Qctime);
- Qpri = intern_c_string ("pri");
- staticpro (&Qpri);
- Qnice = intern_c_string ("nice");
- staticpro (&Qnice);
- Qthcount = intern_c_string ("thcount");
- staticpro (&Qthcount);
- Qstart = intern_c_string ("start");
- staticpro (&Qstart);
- Qvsize = intern_c_string ("vsize");
- staticpro (&Qvsize);
- Qrss = intern_c_string ("rss");
- staticpro (&Qrss);
- Qetime = intern_c_string ("etime");
- staticpro (&Qetime);
- Qpcpu = intern_c_string ("pcpu");
- staticpro (&Qpcpu);
- Qpmem = intern_c_string ("pmem");
- staticpro (&Qpmem);
- Qargs = intern_c_string ("args");
- staticpro (&Qargs);
-
- DEFVAR_BOOL ("delete-exited-processes", &delete_exited_processes,
- doc: /* *Non-nil means delete processes immediately when they exit.
-A value of nil means don't delete them until `list-processes' is run. */);
-
- delete_exited_processes = 1;
+/* Return nonzero if *MASK has a bit set
+ that corresponds to one of the keyboard input descriptors. */
- DEFVAR_LISP ("process-connection-type", &Vprocess_connection_type,
- doc: /* Control type of device used to communicate with subprocesses.
-Values are nil to use a pipe, or t or `pty' to use a pty.
-The value has no effect if the system has no ptys or if all ptys are busy:
-then a pipe is used in any case.
-The value takes effect when `start-process' is called. */);
- Vprocess_connection_type = Qt;
+static int
+keyboard_bit_set (fd_set *mask)
+{
+ int fd;
-#ifdef ADAPTIVE_READ_BUFFERING
- DEFVAR_LISP ("process-adaptive-read-buffering", &Vprocess_adaptive_read_buffering,
- doc: /* If non-nil, improve receive buffering by delaying after short reads.
-On some systems, when Emacs reads the output from a subprocess, the output data
-is read in very small blocks, potentially resulting in very poor performance.
-This behavior can be remedied to some extent by setting this variable to a
-non-nil value, as it will automatically delay reading from such processes, to
-allow them to produce more output before Emacs tries to read it.
-If the value is t, the delay is reset after each write to the process; any other
-non-nil value means that the delay is not reset on write.
-The variable takes effect when `start-process' is called. */);
- Vprocess_adaptive_read_buffering = Qt;
-#endif
+ for (fd = 0; fd <= max_keyboard_desc; fd++)
+ if (FD_ISSET (fd, mask) && FD_ISSET (fd, &input_wait_mask)
+ && !FD_ISSET (fd, &non_keyboard_wait_mask))
+ return 1;
- defsubr (&Sprocessp);
- defsubr (&Sget_process);
- defsubr (&Sget_buffer_process);
- defsubr (&Sdelete_process);
- defsubr (&Sprocess_status);
- defsubr (&Sprocess_exit_status);
- defsubr (&Sprocess_id);
- defsubr (&Sprocess_name);
- defsubr (&Sprocess_tty_name);
- defsubr (&Sprocess_command);
- defsubr (&Sset_process_buffer);
- defsubr (&Sprocess_buffer);
- defsubr (&Sprocess_mark);
- defsubr (&Sset_process_filter);
- defsubr (&Sprocess_filter);
- defsubr (&Sset_process_sentinel);
- defsubr (&Sprocess_sentinel);
- defsubr (&Sset_process_window_size);
- defsubr (&Sset_process_inherit_coding_system_flag);
- defsubr (&Sprocess_inherit_coding_system_flag);
- defsubr (&Sset_process_query_on_exit_flag);
- defsubr (&Sprocess_query_on_exit_flag);
- defsubr (&Sprocess_contact);
- defsubr (&Sprocess_plist);
- defsubr (&Sset_process_plist);
- defsubr (&Slist_processes);
- defsubr (&Sprocess_list);
- defsubr (&Sstart_process);
-#ifdef HAVE_SERIAL
- defsubr (&Sserial_process_configure);
- defsubr (&Smake_serial_process);
-#endif /* HAVE_SERIAL */
-#ifdef HAVE_SOCKETS
- defsubr (&Sset_network_process_option);
- defsubr (&Smake_network_process);
- defsubr (&Sformat_network_address);
-#endif /* HAVE_SOCKETS */
-#if defined(HAVE_SOCKETS) && defined(HAVE_NET_IF_H) && defined(HAVE_SYS_IOCTL_H)
-#ifdef SIOCGIFCONF
- defsubr (&Snetwork_interface_list);
-#endif
-#if defined(SIOCGIFADDR) || defined(SIOCGIFHWADDR) || defined(SIOCGIFFLAGS)
- defsubr (&Snetwork_interface_info);
-#endif
-#endif /* HAVE_SOCKETS ... */
-#ifdef DATAGRAM_SOCKETS
- defsubr (&Sprocess_datagram_address);
- defsubr (&Sset_process_datagram_address);
-#endif
- defsubr (&Saccept_process_output);
- defsubr (&Sprocess_send_region);
- defsubr (&Sprocess_send_string);
- defsubr (&Sinterrupt_process);
- defsubr (&Skill_process);
- 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);
- defsubr (&Sprocess_type);
- defsubr (&Sset_process_coding_system);
- defsubr (&Sprocess_coding_system);
- defsubr (&Sset_process_filter_multibyte);
- defsubr (&Sprocess_filter_multibyte_p);
- defsubr (&Slist_system_processes);
- defsubr (&Sprocess_attributes);
+ return 0;
}
-\f
-#else /* not subprocesses */
-
-#include <sys/types.h>
-#include <errno.h>
-#include <sys/stat.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <setjmp.h>
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
-#include "lisp.h"
-#include "systime.h"
-#include "character.h"
-#include "coding.h"
-#include "termopts.h"
-#include "sysselect.h"
-
-extern int frame_garbaged;
-
-extern EMACS_TIME timer_check ();
-extern int timers_run;
-
-Lisp_Object QCtype, QCname;
-
-Lisp_Object Qeuid, Qegid, Qcomm, Qstate, Qppid, Qpgrp, Qsess, Qttname, Qtpgid;
-Lisp_Object Qminflt, Qmajflt, Qcminflt, Qcmajflt, Qutime, Qstime, Qcstime;
-Lisp_Object Qcutime, Qpri, Qnice, Qthcount, Qstart, Qvsize, Qrss, Qargs;
-Lisp_Object Quser, Qgroup, Qetime, Qpcpu, Qpmem, Qtime, Qctime;
+#else /* not subprocesses */
-/* Non-zero if keyboard input is on hold, zero otherwise. */
-static int kbd_is_on_hold;
+/* Defined on msdos.c. */
+extern int sys_select (int, SELECT_TYPE *, SELECT_TYPE *, SELECT_TYPE *,
+ EMACS_TIME *);
-/* As described above, except assuming that there are no subprocesses:
+/* Implementation of wait_reading_process_output, assuming that there
+ are no subprocesses. Used only by the MS-DOS build.
Wait for timeout to elapse and/or keyboard input to be available.
Return true if we received input from any process. */
int
-wait_reading_process_output (time_limit, microsecs, read_kbd, do_display,
- wait_for_cell, wait_proc, just_wait_proc)
- int time_limit, microsecs, read_kbd, do_display;
- Lisp_Object wait_for_cell;
- struct Lisp_Process *wait_proc;
- int just_wait_proc;
+wait_reading_process_output (int time_limit, int microsecs, int read_kbd,
+ int do_display,
+ Lisp_Object wait_for_cell,
+ struct Lisp_Process *wait_proc, int just_wait_proc)
{
register int nfds;
EMACS_TIME end_time, timeout;
else
error ("select error: %s", emacs_strerror (xerrno));
}
-#ifdef SOLARIS2
- else if (nfds > 0 && (waitchannels & 1) && interrupt_input)
- /* System sometimes fails to deliver SIGIO. */
- kill (getpid (), SIGIO);
-#endif
-#ifdef SIGIO
- if (read_kbd && interrupt_input && (waitchannels & 1))
- kill (getpid (), SIGIO);
-#endif
/* Check for keyboard input */
if (! NILP (wait_for_cell)
&& detect_input_pending ())
{
- swallow_events (do_display);
- if (detect_input_pending ())
- break;
+ swallow_events (do_display);
+ if (detect_input_pending ())
+ break;
+ }
+
+ /* Exit now if the cell we're waiting for became non-nil. */
+ if (! NILP (wait_for_cell) && ! NILP (XCAR (wait_for_cell)))
+ break;
+ }
+
+ start_polling ();
+
+ return 0;
+}
+
+#endif /* not subprocesses */
+
+/* The following functions are needed even if async subprocesses are
+ not supported. Some of them are no-op stubs in that case. */
+
+/* Add DESC to the set of keyboard input descriptors. */
+
+void
+add_keyboard_wait_descriptor (int desc)
+{
+#ifdef subprocesses
+ FD_SET (desc, &input_wait_mask);
+ FD_SET (desc, &non_process_wait_mask);
+ if (desc > max_keyboard_desc)
+ max_keyboard_desc = desc;
+#endif
+}
+
+/* From now on, do not expect DESC to give keyboard input. */
+
+void
+delete_keyboard_wait_descriptor (int desc)
+{
+#ifdef subprocesses
+ int fd;
+ int lim = max_keyboard_desc;
+
+ FD_CLR (desc, &input_wait_mask);
+ FD_CLR (desc, &non_process_wait_mask);
+
+ if (desc == max_keyboard_desc)
+ for (fd = 0; fd < lim; fd++)
+ if (FD_ISSET (fd, &input_wait_mask)
+ && !FD_ISSET (fd, &non_keyboard_wait_mask)
+ && !FD_ISSET (fd, &gpm_wait_mask))
+ max_keyboard_desc = fd;
+#endif /* subprocesses */
+}
+
+/* Setup coding systems of PROCESS. */
+
+void
+setup_process_coding_systems (Lisp_Object process)
+{
+#ifdef subprocesses
+ struct Lisp_Process *p = XPROCESS (process);
+ int inch = p->infd;
+ int outch = p->outfd;
+ Lisp_Object coding_system;
+
+ if (inch < 0 || outch < 0)
+ return;
+
+ if (!proc_decode_coding_system[inch])
+ proc_decode_coding_system[inch]
+ = (struct coding_system *) xmalloc (sizeof (struct coding_system));
+ coding_system = p->decode_coding_system;
+ if (! NILP (p->filter))
+ ;
+ else if (BUFFERP (p->buffer))
+ {
+ if (NILP (XBUFFER (p->buffer)->enable_multibyte_characters))
+ coding_system = raw_text_coding_system (coding_system);
+ }
+ setup_coding_system (coding_system, proc_decode_coding_system[inch]);
+
+ if (!proc_encode_coding_system[outch])
+ proc_encode_coding_system[outch]
+ = (struct coding_system *) xmalloc (sizeof (struct coding_system));
+ setup_coding_system (p->encode_coding_system,
+ proc_encode_coding_system[outch]);
+#endif
+}
+
+/* Close all descriptors currently in use for communication
+ with subprocess. This is used in a newly-forked subprocess
+ to get rid of irrelevant descriptors. */
+
+void
+close_process_descs (void)
+{
+#ifndef DOS_NT
+ int i;
+ for (i = 0; i < MAXDESC; i++)
+ {
+ Lisp_Object process;
+ process = chan_process[i];
+ if (!NILP (process))
+ {
+ int in = XPROCESS (process)->infd;
+ int out = XPROCESS (process)->outfd;
+ if (in >= 0)
+ emacs_close (in);
+ if (out >= 0 && in != out)
+ emacs_close (out);
}
-
- /* Exit now if the cell we're waiting for became non-nil. */
- if (! NILP (wait_for_cell) && ! NILP (XCAR (wait_for_cell)))
- break;
}
-
- start_polling ();
-
- return 0;
+#endif
}
-
-/* Don't confuse make-docfile by having two doc strings for this function.
- make-docfile does not pay attention to #if, for good reason! */
DEFUN ("get-buffer-process", Fget_buffer_process, Sget_buffer_process, 1, 1, 0,
- 0)
- (register Lisp_Object name)
+ doc: /* Return the (or a) process associated with BUFFER.
+BUFFER may be a buffer or the name of one. */)
+ (register Lisp_Object buffer)
{
+#ifdef subprocesses
+ register Lisp_Object buf, tail, proc;
+
+ if (NILP (buffer)) return Qnil;
+ buf = Fget_buffer (buffer);
+ if (NILP (buf)) return Qnil;
+
+ for (tail = Vprocess_alist; CONSP (tail); tail = XCDR (tail))
+ {
+ proc = Fcdr (XCAR (tail));
+ if (PROCESSP (proc) && EQ (XPROCESS (proc)->buffer, buf))
+ return proc;
+ }
+#endif /* subprocesses */
return Qnil;
}
- /* Don't confuse make-docfile by having two doc strings for this function.
- make-docfile does not pay attention to #if, for good reason! */
DEFUN ("process-inherit-coding-system-flag",
Fprocess_inherit_coding_system_flag, Sprocess_inherit_coding_system_flag,
1, 1, 0,
- 0)
+ doc: /* Return the value of inherit-coding-system flag for PROCESS.
+If this flag is t, `buffer-file-coding-system' of the buffer
+associated with PROCESS will inherit the coding system used to decode
+the process output. */)
(register Lisp_Object process)
{
+#ifdef subprocesses
+ CHECK_PROCESS (process);
+ return XPROCESS (process)->inherit_coding_system_flag ? Qt : Qnil;
+#else
/* Ignore the argument and return the value of
inherit-process-coding-system. */
return inherit_process_coding_system ? Qt : Qnil;
+#endif
}
/* Kill all processes associated with `buffer'.
- If `buffer' is nil, kill all processes.
- Since we have no subprocesses, this does nothing. */
+ If `buffer' is nil, kill all processes */
void
-kill_buffer_processes (buffer)
- Lisp_Object buffer;
+kill_buffer_processes (Lisp_Object buffer)
+{
+#ifdef subprocesses
+ Lisp_Object tail, proc;
+
+ for (tail = Vprocess_alist; CONSP (tail); tail = XCDR (tail))
+ {
+ proc = XCDR (XCAR (tail));
+ if (PROCESSP (proc)
+ && (NILP (buffer) || EQ (XPROCESS (proc)->buffer, buffer)))
+ {
+ if (NETCONN_P (proc) || SERIALCONN_P (proc))
+ Fdelete_process (proc);
+ else if (XPROCESS (proc)->infd >= 0)
+ process_send_signal (proc, SIGHUP, Qnil, 1);
+ }
+ }
+#else /* subprocesses */
+ /* Since we have no subprocesses, this does nothing. */
+#endif /* subprocesses */
+}
+
+DEFUN ("waiting-for-user-input-p", Fwaiting_for_user_input_p, Swaiting_for_user_input_p,
+ 0, 0, 0,
+ doc: /* Returns non-nil if Emacs is waiting for input from the user.
+This is intended for use by asynchronous process output filters and sentinels. */)
+ (void)
{
+#ifdef subprocesses
+ return (waiting_for_user_input_p ? Qt : Qnil);
+#else
+ return Qnil;
+#endif
}
-\f
/* Stop reading input from keyboard sources. */
void
return kbd_is_on_hold;
}
+\f
+/* Enumeration of and access to system processes a-la ps(1). */
+
DEFUN ("list-system-processes", Flist_system_processes, Slist_system_processes,
0, 0, 0,
doc: /* Return a list of numerical process IDs of all running processes.
See `process-attributes' for getting attributes of a process given its ID. */)
(void)
{
- return list_system_processes ();
-}
+ return list_system_processes ();
+}
+
+DEFUN ("process-attributes", Fprocess_attributes,
+ Sprocess_attributes, 1, 1, 0,
+ doc: /* Return attributes of the process given by its PID, a number.
+
+Value is an alist where each element is a cons cell of the form
+
+ \(KEY . VALUE)
+
+If this functionality is unsupported, the value is nil.
+
+See `list-system-processes' for getting a list of all process IDs.
+
+The KEYs of the attributes that this function may return are listed
+below, together with the type of the associated VALUE (in parentheses).
+Not all platforms support all of these attributes; unsupported
+attributes will not appear in the returned alist.
+Unless explicitly indicated otherwise, numbers can have either
+integer or floating point values.
+
+ euid -- Effective user User ID of the process (number)
+ user -- User name corresponding to euid (string)
+ egid -- Effective user Group ID of the process (number)
+ group -- Group name corresponding to egid (string)
+ comm -- Command name (executable name only) (string)
+ state -- Process state code, such as "S", "R", or "T" (string)
+ ppid -- Parent process ID (number)
+ pgrp -- Process group ID (number)
+ sess -- Session ID, i.e. process ID of session leader (number)
+ ttname -- Controlling tty name (string)
+ tpgid -- ID of foreground process group on the process's tty (number)
+ minflt -- number of minor page faults (number)
+ majflt -- number of major page faults (number)
+ cminflt -- cumulative number of minor page faults (number)
+ cmajflt -- cumulative number of major page faults (number)
+ utime -- user time used by the process, in the (HIGH LOW USEC) format
+ stime -- system time used by the process, in the (HIGH LOW USEC) format
+ time -- sum of utime and stime, in the (HIGH LOW USEC) format
+ cutime -- user time used by the process and its children, (HIGH LOW USEC)
+ cstime -- system time used by the process and its children, (HIGH LOW USEC)
+ ctime -- sum of cutime and cstime, in the (HIGH LOW USEC) format
+ pri -- priority of the process (number)
+ nice -- nice value of the process (number)
+ thcount -- process thread count (number)
+ start -- time the process started, in the (HIGH LOW USEC) format
+ vsize -- virtual memory size of the process in KB's (number)
+ rss -- resident set size of the process in KB's (number)
+ etime -- elapsed time the process is running, in (HIGH LOW USEC) format
+ pcpu -- percents of CPU time used by the process (floating-point number)
+ pmem -- percents of total physical memory used by process's resident set
+ (floating-point number)
+ args -- command line which invoked the process (string). */)
+ ( Lisp_Object pid)
+{
+ return system_process_attributes (pid);
+}
+
+\f
+void
+init_process (void)
+{
+#ifdef subprocesses
+ register int i;
+
+ inhibit_sentinels = 0;
+
+#ifdef SIGCHLD
+#ifndef CANNOT_DUMP
+ if (! noninteractive || initialized)
+#endif
+ signal (SIGCHLD, sigchld_handler);
+#endif
+
+ FD_ZERO (&input_wait_mask);
+ FD_ZERO (&non_keyboard_wait_mask);
+ FD_ZERO (&non_process_wait_mask);
+ max_process_desc = 0;
+
+#ifdef NON_BLOCKING_CONNECT
+ FD_ZERO (&connect_wait_mask);
+ num_pending_connects = 0;
+#endif
+
+#ifdef ADAPTIVE_READ_BUFFERING
+ process_output_delay_count = 0;
+ process_output_skip = 0;
+#endif
+
+ /* Don't do this, it caused infinite select loops. The display
+ method should call add_keyboard_wait_descriptor on stdin if it
+ needs that. */
+#if 0
+ FD_SET (0, &input_wait_mask);
+#endif
+
+ Vprocess_alist = Qnil;
+#ifdef SIGCHLD
+ deleted_pid_list = Qnil;
+#endif
+ for (i = 0; i < MAXDESC; i++)
+ {
+ chan_process[i] = Qnil;
+ proc_buffered_char[i] = -1;
+ }
+ memset (proc_decode_coding_system, 0, sizeof proc_decode_coding_system);
+ memset (proc_encode_coding_system, 0, sizeof proc_encode_coding_system);
+#ifdef DATAGRAM_SOCKETS
+ memset (datagram_address, 0, sizeof datagram_address);
+#endif
+
+ {
+ Lisp_Object subfeatures = Qnil;
+ const struct socket_options *sopt;
+
+#define ADD_SUBFEATURE(key, val) \
+ subfeatures = pure_cons (pure_cons (key, pure_cons (val, Qnil)), subfeatures)
+
+#ifdef NON_BLOCKING_CONNECT
+ ADD_SUBFEATURE (QCnowait, Qt);
+#endif
+#ifdef DATAGRAM_SOCKETS
+ ADD_SUBFEATURE (QCtype, Qdatagram);
+#endif
+#ifdef HAVE_SEQPACKET
+ ADD_SUBFEATURE (QCtype, Qseqpacket);
+#endif
+#ifdef HAVE_LOCAL_SOCKETS
+ ADD_SUBFEATURE (QCfamily, Qlocal);
+#endif
+ ADD_SUBFEATURE (QCfamily, Qipv4);
+#ifdef AF_INET6
+ ADD_SUBFEATURE (QCfamily, Qipv6);
+#endif
+#ifdef HAVE_GETSOCKNAME
+ ADD_SUBFEATURE (QCservice, Qt);
+#endif
+#if defined(O_NONBLOCK) || defined(O_NDELAY)
+ ADD_SUBFEATURE (QCserver, Qt);
+#endif
+
+ for (sopt = socket_options; sopt->name; sopt++)
+ subfeatures = pure_cons (intern_c_string (sopt->name), subfeatures);
+
+ Fprovide (intern_c_string ("make-network-process"), subfeatures);
+ }
+
+#if defined (DARWIN_OS)
+ /* PTYs are broken on Darwin < 6, but are sometimes useful for interactive
+ processes. As such, we only change the default value. */
+ if (initialized)
+ {
+ const char *release = get_operating_system_release ();
+ if (!release || !release[0] || (release[0] < MIN_PTY_KERNEL_VERSION
+ && release[1] == '.')) {
+ Vprocess_connection_type = Qnil;
+ }
+ }
+#endif
+#endif /* subprocesses */
+ kbd_is_on_hold = 0;
+}
+
+void
+syms_of_process (void)
+{
+#ifdef subprocesses
-DEFUN ("process-attributes", Fprocess_attributes,
- Sprocess_attributes, 1, 1, 0,
- doc: /* Return attributes of the process given by its PID, a number.
+ Qprocessp = intern_c_string ("processp");
+ staticpro (&Qprocessp);
+ Qrun = intern_c_string ("run");
+ staticpro (&Qrun);
+ Qstop = intern_c_string ("stop");
+ staticpro (&Qstop);
+ Qsignal = intern_c_string ("signal");
+ staticpro (&Qsignal);
-Value is an alist where each element is a cons cell of the form
+ /* Qexit is already staticpro'd by syms_of_eval; don't staticpro it
+ here again.
- \(KEY . VALUE)
+ Qexit = intern_c_string ("exit");
+ staticpro (&Qexit); */
-If this functionality is unsupported, the value is nil.
+ Qopen = intern_c_string ("open");
+ staticpro (&Qopen);
+ Qclosed = intern_c_string ("closed");
+ staticpro (&Qclosed);
+ Qconnect = intern_c_string ("connect");
+ staticpro (&Qconnect);
+ Qfailed = intern_c_string ("failed");
+ staticpro (&Qfailed);
+ Qlisten = intern_c_string ("listen");
+ staticpro (&Qlisten);
+ Qlocal = intern_c_string ("local");
+ staticpro (&Qlocal);
+ Qipv4 = intern_c_string ("ipv4");
+ staticpro (&Qipv4);
+#ifdef AF_INET6
+ Qipv6 = intern_c_string ("ipv6");
+ staticpro (&Qipv6);
+#endif
+ Qdatagram = intern_c_string ("datagram");
+ staticpro (&Qdatagram);
+ Qseqpacket = intern_c_string ("seqpacket");
+ staticpro (&Qseqpacket);
-See `list-system-processes' for getting a list of all process IDs.
+ QCport = intern_c_string (":port");
+ staticpro (&QCport);
+ QCspeed = intern_c_string (":speed");
+ staticpro (&QCspeed);
+ QCprocess = intern_c_string (":process");
+ staticpro (&QCprocess);
-The KEYs of the attributes that this function may return are listed
-below, together with the type of the associated VALUE (in parentheses).
-Not all platforms support all of these attributes; unsupported
-attributes will not appear in the returned alist.
-Unless explicitly indicated otherwise, numbers can have either
-integer or floating point values.
+ QCbytesize = intern_c_string (":bytesize");
+ staticpro (&QCbytesize);
+ QCstopbits = intern_c_string (":stopbits");
+ staticpro (&QCstopbits);
+ QCparity = intern_c_string (":parity");
+ staticpro (&QCparity);
+ Qodd = intern_c_string ("odd");
+ staticpro (&Qodd);
+ Qeven = intern_c_string ("even");
+ staticpro (&Qeven);
+ QCflowcontrol = intern_c_string (":flowcontrol");
+ staticpro (&QCflowcontrol);
+ Qhw = intern_c_string ("hw");
+ staticpro (&Qhw);
+ Qsw = intern_c_string ("sw");
+ staticpro (&Qsw);
+ QCsummary = intern_c_string (":summary");
+ staticpro (&QCsummary);
- euid -- Effective user User ID of the process (number)
- user -- User name corresponding to euid (string)
- egid -- Effective user Group ID of the process (number)
- group -- Group name corresponding to egid (string)
- comm -- Command name (executable name only) (string)
- state -- Process state code, such as "S", "R", or "T" (string)
- ppid -- Parent process ID (number)
- pgrp -- Process group ID (number)
- sess -- Session ID, i.e. process ID of session leader (number)
- ttname -- Controlling tty name (string)
- tpgid -- ID of foreground process group on the process's tty (number)
- minflt -- number of minor page faults (number)
- majflt -- number of major page faults (number)
- cminflt -- cumulative number of minor page faults (number)
- cmajflt -- cumulative number of major page faults (number)
- utime -- user time used by the process, in the (HIGH LOW USEC) format
- stime -- system time used by the process, in the (HIGH LOW USEC) format
- time -- sum of utime and stime, in the (HIGH LOW USEC) format
- cutime -- user time used by the process and its children, (HIGH LOW USEC)
- cstime -- system time used by the process and its children, (HIGH LOW USEC)
- ctime -- sum of cutime and cstime, in the (HIGH LOW USEC) format
- pri -- priority of the process (number)
- nice -- nice value of the process (number)
- thcount -- process thread count (number)
- start -- time the process started, in the (HIGH LOW USEC) format
- vsize -- virtual memory size of the process in KB's (number)
- rss -- resident set size of the process in KB's (number)
- etime -- elapsed time the process is running, in (HIGH LOW USEC) format
- pcpu -- percents of CPU time used by the process (floating-point number)
- pmem -- percents of total physical memory used by process's resident set
- (floating-point number)
- args -- command line which invoked the process (string). */)
- ( Lisp_Object pid)
-{
- return system_process_attributes (pid);
-}
+ Qreal = intern_c_string ("real");
+ staticpro (&Qreal);
+ Qnetwork = intern_c_string ("network");
+ staticpro (&Qnetwork);
+ Qserial = intern_c_string ("serial");
+ staticpro (&Qserial);
+ QCbuffer = intern_c_string (":buffer");
+ staticpro (&QCbuffer);
+ QChost = intern_c_string (":host");
+ staticpro (&QChost);
+ QCservice = intern_c_string (":service");
+ staticpro (&QCservice);
+ QClocal = intern_c_string (":local");
+ staticpro (&QClocal);
+ QCremote = intern_c_string (":remote");
+ staticpro (&QCremote);
+ QCcoding = intern_c_string (":coding");
+ staticpro (&QCcoding);
+ QCserver = intern_c_string (":server");
+ staticpro (&QCserver);
+ QCnowait = intern_c_string (":nowait");
+ staticpro (&QCnowait);
+ QCsentinel = intern_c_string (":sentinel");
+ staticpro (&QCsentinel);
+ QClog = intern_c_string (":log");
+ staticpro (&QClog);
+ QCnoquery = intern_c_string (":noquery");
+ staticpro (&QCnoquery);
+ QCstop = intern_c_string (":stop");
+ staticpro (&QCstop);
+ QCoptions = intern_c_string (":options");
+ staticpro (&QCoptions);
+ QCplist = intern_c_string (":plist");
+ staticpro (&QCplist);
-void
-init_process ()
-{
- kbd_is_on_hold = 0;
-}
+ Qlast_nonmenu_event = intern_c_string ("last-nonmenu-event");
+ staticpro (&Qlast_nonmenu_event);
+
+ staticpro (&Vprocess_alist);
+#ifdef SIGCHLD
+ staticpro (&deleted_pid_list);
+#endif
+
+#endif /* subprocesses */
-void
-syms_of_process ()
-{
- QCtype = intern_c_string (":type");
- staticpro (&QCtype);
QCname = intern_c_string (":name");
staticpro (&QCname);
QCtype = intern_c_string (":type");
staticpro (&QCtype);
- QCname = intern_c_string (":name");
- staticpro (&QCname);
+
Qeuid = intern_c_string ("euid");
staticpro (&Qeuid);
Qegid = intern_c_string ("egid");
Qargs = intern_c_string ("args");
staticpro (&Qargs);
+ DEFVAR_BOOL ("delete-exited-processes", &delete_exited_processes,
+ doc: /* *Non-nil means delete processes immediately when they exit.
+A value of nil means don't delete them until `list-processes' is run. */);
+
+ delete_exited_processes = 1;
+
+#ifdef subprocesses
+ DEFVAR_LISP ("process-connection-type", &Vprocess_connection_type,
+ doc: /* Control type of device used to communicate with subprocesses.
+Values are nil to use a pipe, or t or `pty' to use a pty.
+The value has no effect if the system has no ptys or if all ptys are busy:
+then a pipe is used in any case.
+The value takes effect when `start-process' is called. */);
+ Vprocess_connection_type = Qt;
+
+#ifdef ADAPTIVE_READ_BUFFERING
+ DEFVAR_LISP ("process-adaptive-read-buffering", &Vprocess_adaptive_read_buffering,
+ doc: /* If non-nil, improve receive buffering by delaying after short reads.
+On some systems, when Emacs reads the output from a subprocess, the output data
+is read in very small blocks, potentially resulting in very poor performance.
+This behavior can be remedied to some extent by setting this variable to a
+non-nil value, as it will automatically delay reading from such processes, to
+allow them to produce more output before Emacs tries to read it.
+If the value is t, the delay is reset after each write to the process; any other
+non-nil value means that the delay is not reset on write.
+The variable takes effect when `start-process' is called. */);
+ Vprocess_adaptive_read_buffering = Qt;
+#endif
+
+ defsubr (&Sprocessp);
+ defsubr (&Sget_process);
+ defsubr (&Sdelete_process);
+ defsubr (&Sprocess_status);
+ defsubr (&Sprocess_exit_status);
+ defsubr (&Sprocess_id);
+ defsubr (&Sprocess_name);
+ defsubr (&Sprocess_tty_name);
+ defsubr (&Sprocess_command);
+ defsubr (&Sset_process_buffer);
+ defsubr (&Sprocess_buffer);
+ defsubr (&Sprocess_mark);
+ defsubr (&Sset_process_filter);
+ defsubr (&Sprocess_filter);
+ defsubr (&Sset_process_sentinel);
+ defsubr (&Sprocess_sentinel);
+ defsubr (&Sset_process_window_size);
+ defsubr (&Sset_process_inherit_coding_system_flag);
+ defsubr (&Sset_process_query_on_exit_flag);
+ defsubr (&Sprocess_query_on_exit_flag);
+ defsubr (&Sprocess_contact);
+ defsubr (&Sprocess_plist);
+ defsubr (&Sset_process_plist);
+ defsubr (&Slist_processes);
+ defsubr (&Sprocess_list);
+ defsubr (&Sstart_process);
+#ifdef HAVE_SERIAL
+ defsubr (&Sserial_process_configure);
+ defsubr (&Smake_serial_process);
+#endif /* HAVE_SERIAL */
+ defsubr (&Sset_network_process_option);
+ defsubr (&Smake_network_process);
+ defsubr (&Sformat_network_address);
+#if defined(HAVE_NET_IF_H) && defined(HAVE_SYS_IOCTL_H)
+#ifdef SIOCGIFCONF
+ defsubr (&Snetwork_interface_list);
+#endif
+#if defined(SIOCGIFADDR) || defined(SIOCGIFHWADDR) || defined(SIOCGIFFLAGS)
+ defsubr (&Snetwork_interface_info);
+#endif
+#endif /* defined(HAVE_NET_IF_H) && defined(HAVE_SYS_IOCTL_H) */
+#ifdef DATAGRAM_SOCKETS
+ defsubr (&Sprocess_datagram_address);
+ defsubr (&Sset_process_datagram_address);
+#endif
+ defsubr (&Saccept_process_output);
+ defsubr (&Sprocess_send_region);
+ defsubr (&Sprocess_send_string);
+ defsubr (&Sinterrupt_process);
+ defsubr (&Skill_process);
+ 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);
+ defsubr (&Sprocess_type);
+ defsubr (&Sset_process_coding_system);
+ defsubr (&Sprocess_coding_system);
+ defsubr (&Sset_process_filter_multibyte);
+ defsubr (&Sprocess_filter_multibyte_p);
+
+#endif /* subprocesses */
+
defsubr (&Sget_buffer_process);
defsubr (&Sprocess_inherit_coding_system_flag);
defsubr (&Slist_system_processes);
defsubr (&Sprocess_attributes);
}
-\f
-#endif /* not subprocesses */
-
/* arch-tag: 3706c011-7b9a-4117-bd4f-59e7f701a4c4
(do not change this comment) */