#include "opaque.h"
#include "process.h"
#include "procimpl.h"
-#include "sysdep.h"
#include "window.h"
#ifdef FILE_CODING
#include "file-coding.h"
/* Qrun => Qopen, Qexit => Qclosed for "network connection" processes */
Lisp_Object Qopen, Qclosed;
/* Protocol families */
-Lisp_Object Qtcpip;
+Lisp_Object Qtcp, Qudp;
#ifdef HAVE_MULTICAST
Lisp_Object Qmulticast; /* Will be used for occasional warnings */
/* Nonzero means delete a process right away if it exits. */
int delete_exited_processes;
-/* Hashtable which maps USIDs as returned by create_stream_pair_cb to
+/* Hash table which maps USIDs as returned by create_stream_pair_cb to
process objects. Processes are not GC-protected through this! */
-c_hashtable usid_to_process;
+struct hash_table *usid_to_process;
/* List of process objects. */
Lisp_Object Vprocess_list;
+extern Lisp_Object Vlisp_EXEC_SUFFIXES;
+
\f
static Lisp_Object
-mark_process (Lisp_Object obj, void (*markobj) (Lisp_Object))
+mark_process (Lisp_Object obj)
{
struct Lisp_Process *proc = XPROCESS (obj);
- MAYBE_PROCMETH (mark_process_data, (proc, markobj));
- ((markobj) (proc->name));
- ((markobj) (proc->command));
- ((markobj) (proc->filter));
- ((markobj) (proc->sentinel));
- ((markobj) (proc->buffer));
- ((markobj) (proc->mark));
- ((markobj) (proc->pid));
- ((markobj) (proc->pipe_instream));
- ((markobj) (proc->pipe_outstream));
+ MAYBE_PROCMETH (mark_process_data, (proc));
+ mark_object (proc->name);
+ mark_object (proc->command);
+ mark_object (proc->filter);
+ mark_object (proc->sentinel);
+ mark_object (proc->buffer);
+ mark_object (proc->mark);
+ mark_object (proc->pid);
+ mark_object (proc->pipe_instream);
+ mark_object (proc->pipe_outstream);
#ifdef FILE_CODING
- ((markobj) (proc->coding_instream));
- ((markobj) (proc->coding_outstream));
+ mark_object (proc->coding_instream);
+ mark_object (proc->coding_outstream);
#endif
return proc->status_symbol;
}
else
{
int netp = network_connection_p (obj);
- write_c_string (((netp) ? GETTEXT ("#<network connection ") :
+ write_c_string ((netp ? GETTEXT ("#<network connection ") :
GETTEXT ("#<process ")), printcharfun);
print_internal (proc->name, printcharfun, 1);
- write_c_string (((netp) ? " " : " pid "), printcharfun);
+ write_c_string ((netp ? " " : " pid "), printcharfun);
print_internal (proc->pid, printcharfun, 1);
write_c_string (" state:", printcharfun);
print_internal (proc->status_symbol, printcharfun, 1);
DEFINE_LRECORD_IMPLEMENTATION ("process", process,
mark_process, print_process, finalize_process,
- 0, 0, struct Lisp_Process);
+ 0, 0, 0, struct Lisp_Process);
\f
/************************************************************************/
/* basic process accessors */
/************************************************************************/
/* Under FILE_CODING, this function returns low-level streams, connected
- directrly to the child process, rather than en/decoding FILE_CODING
+ directly to the child process, rather than en/decoding FILE_CODING
streams */
void
get_process_streams (struct Lisp_Process *p,
int
network_connection_p (Lisp_Object process)
{
- return GC_CONSP (XPROCESS (process)->pid);
+ return CONSP (XPROCESS (process)->pid);
}
#endif
{
Lisp_Object tail;
- if (GC_PROCESSP (name))
+ if (PROCESSP (name))
return name;
if (!gc_in_progress)
of a signal or crash. */
CHECK_STRING (name);
- for (tail = Vprocess_list; GC_CONSP (tail); tail = XCDR (tail))
+ for (tail = Vprocess_list; CONSP (tail); tail = XCDR (tail))
{
Lisp_Object proc = XCAR (tail);
QUIT;
{
Lisp_Object buf, tail, proc;
- if (GC_NILP (name)) return Qnil;
+ if (NILP (name)) return Qnil;
buf = Fget_buffer (name);
- if (GC_NILP (buf)) return Qnil;
+ if (NILP (buf)) return Qnil;
- for (tail = Vprocess_list; GC_CONSP (tail); tail = XCDR (tail))
+ for (tail = Vprocess_list; CONSP (tail); tail = XCDR (tail))
{
/* jwz: do not quit here - it isn't necessary, as there is no way for
Vprocess_list to get circular or overwhelmingly long, and this
function is called from layout_mode_element under redisplay. */
/* QUIT; */
proc = XCAR (tail);
- if (GC_PROCESSP (proc) && EQ (XPROCESS (proc)->buffer, buf))
+ if (PROCESSP (proc) && EQ (XPROCESS (proc)->buffer, buf))
return proc;
}
return Qnil;
/* This may be called during a GC from process_send_signal() from
kill_buffer_processes() if emacs decides to abort(). */
- if (GC_PROCESSP (name))
+ if (PROCESSP (name))
return name;
- if (GC_STRINGP (name))
+ if (STRINGP (name))
{
obj = Fget_process (name);
- if (GC_NILP (obj))
+ if (NILP (obj))
obj = Fget_buffer (name);
- if (GC_NILP (obj))
+ if (NILP (obj))
error ("Process %s does not exist", XSTRING_DATA (name));
}
- else if (GC_NILP (name))
+ else if (NILP (name))
obj = Fcurrent_buffer ();
else
obj = name;
/* Now obj should be either a buffer object or a process object.
*/
- if (GC_BUFFERP (obj))
+ if (BUFFERP (obj))
{
proc = Fget_buffer_process (obj);
- if (GC_NILP (proc))
+ if (NILP (proc))
error ("Buffer %s has no process", XSTRING_DATA (XBUFFER(obj)->name));
}
else
{
/* #### This was commented out. Although, simple
- (kill-process 7 "qqq") resulted in a falat error. - kkm */
+ (kill-process 7 "qqq") resulted in a fatal error. - kkm */
CHECK_PROCESS (obj);
proc = obj;
}
Lisp_Object val, name1;
int i;
struct Lisp_Process *p =
- alloc_lcrecord_type (struct Lisp_Process, lrecord_process);
+ alloc_lcrecord_type (struct Lisp_Process, &lrecord_process);
/* If name is already in use, modify it until it is unused. */
name1 = name;
tem = Qnil;
NGCPRO1 (tem);
- locate_file (Vexec_path, program, EXEC_SUFFIXES, &tem,
- X_OK);
+ locate_file (Vexec_path, program, Vlisp_EXEC_SUFFIXES, &tem, X_OK);
if (NILP (tem))
report_file_error ("Searching for program", list1 (program));
program = Fexpand_file_name (tem, Qnil);
functions must then go to lisp and provide a suitable list for the
generalized connection function.
- Both UNIX ans Win32 support BSD sockets, and there are many extensions
- availalble (Sockets 2 spec).
+ Both UNIX and Win32 support BSD sockets, and there are many extensions
+ available (Sockets 2 spec).
A todo is define a consistent set of properties abstracting a
network connection. -kkm
DEFUN ("open-network-stream-internal", Fopen_network_stream_internal, 4, 5, 0, /*
Open a TCP connection for a service to a host.
-Returns a subprocess-object to represent the connection.
+Return a subprocess-object to represent the connection.
Input and output work as for subprocesses; `delete-process' closes it.
NAME is name for process. It is modified if necessary to make it unique.
Third arg is name of the host to connect to, or its IP address.
Fourth arg SERVICE is name of the service desired, or an integer
specifying a port number to connect to.
-Fifth argument FAMILY is a protocol family. When omitted, 'tcp/ip
-\(Internet protocol family TCP/IP) is assumed.
+Fifth argument PROTOCOL is a network protocol. Currently 'tcp
+ (Transmission Control Protocol) and 'udp (User Datagram Protocol) are
+ supported. When omitted, 'tcp is assumed.
+
+Ouput via `process-send-string' and input via buffer or filter (see
+`set-process-filter') are stream-oriented. That means UDP datagrams are
+not guaranteed to be sent and received in discrete packets. (But small
+datagrams around 500 bytes that are not truncated by `process-send-string'
+are usually fine.) Note further that UDP protocol does not guard against
+lost packets.
*/
- (name, buffer, host, service, family))
+ (name, buffer, host, service, protocol))
{
/* !!#### This function has not been Mule-ized */
/* This function can GC */
struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, ngcpro1;
void *inch, *outch;
- GCPRO5 (name, buffer, host, service, family);
+ GCPRO5 (name, buffer, host, service, protocol);
CHECK_STRING (name);
- if (NILP(family))
- family = Qtcpip;
+ if (NILP(protocol))
+ protocol = Qtcp;
else
- CHECK_SYMBOL (family);
+ CHECK_SYMBOL (protocol);
/* Since this code is inside HAVE_SOCKETS, existence of
open_network_stream is mandatory */
- PROCMETH (open_network_stream, (name, host, service, family,
+ PROCMETH (open_network_stream, (name, host, service, protocol,
&inch, &outch));
if (!NILP (buffer))
DEFUN ("open-multicast-group-internal", Fopen_multicast_group_internal, 5, 5, 0, /*
Open a multicast connection on the specified dest/port/ttl.
-Returns a subprocess-object to represent the connection.
+Return a subprocess-object to represent the connection.
Input and output work as for subprocesses; `delete-process' closes it.
NAME is name for process. It is modified if necessary to make it unique.
old_zv += nchars;
#if 0
- /* This screws up intial display of the window. jla */
+ /* This screws up initial display of the window. jla */
/* Insert before markers in case we are inserting where
the buffer's mark is, and the user's next command is Meta-y. */
if (nonrelocatable)
lstream =
make_fixed_buffer_input_stream (nonrelocatable + start, len);
- else if (GC_BUFFERP (relocatable))
+ else if (BUFFERP (relocatable))
lstream = make_lisp_buffer_input_stream (XBUFFER (relocatable),
start, start + len, 0);
else
handle_signal (SIGUNUSED);
#endif
#ifdef SIGDANGER
- handle_signal (SIGDANGER);
+ handle_signal (SIGDANGER); /* AIX */
#endif
#ifdef SIGMSG
handle_signal (SIGMSG);
{
Lisp_Object tail;
- for (tail = Vprocess_list; GC_CONSP (tail);
+ for (tail = Vprocess_list; CONSP (tail);
tail = XCDR (tail))
{
Lisp_Object proc = XCAR (tail);
- if (GC_PROCESSP (proc)
- && (GC_NILP (buffer) || GC_EQ (XPROCESS (proc)->buffer, buffer)))
+ if (PROCESSP (proc)
+ && (NILP (buffer) || EQ (XPROCESS (proc)->buffer, buffer)))
{
if (network_connection_p (proc))
Fdelete_process (proc);
MAYBE_PROCMETH (init_process, ());
Vprocess_list = Qnil;
- usid_to_process = make_hashtable (32);
+
+ if (usid_to_process)
+ clrhash (usid_to_process);
+ else
+ usid_to_process = make_hash_table (32);
}
#if 0
defsymbol (&Qopen, "open");
defsymbol (&Qclosed, "closed");
- defsymbol (&Qtcpip, "tcp/ip");
+ defsymbol (&Qtcp, "tcp");
+ defsymbol (&Qudp, "udp");
#ifdef HAVE_MULTICAST
defsymbol(&Qmulticast, "multicast"); /* Used for occasional warnings */
Vprocess_connection_type = Qt;
DEFVAR_BOOL ("windowed-process-io", &windowed_process_io /*
-Enables input/ouptut on standard handles of a windowed process.
+Enables input/output on standard handles of a windowed process.
When this variable is nil (the default), XEmacs does not attempt to read
standard output handle of a windowed process. Instead, the process is
immediately marked as exited immediately upon successful launching. This is
-done because normal windowed processes do not use stadnard I/O, as they are
+done because normal windowed processes do not use standard I/O, as they are
not connected to any console.
When launching a specially crafted windowed process, which expects to be