Function: make-pipe-process
make-pipe-process is a function defined in process.c.
Signature
(make-pipe-process &rest ARGS)
Documentation
Create and return a bidirectional pipe process.
In Emacs, pipes are represented by process objects, so input and
output work as for subprocesses, and delete-process closes a pipe.
However, a pipe process has no process id, it cannot be signaled,
and the status codes are different from normal processes.
Arguments are specified as keyword/argument pairs. The following arguments are defined:
:name NAME -- NAME is the name of the process. It is modified if necessary to make it unique.
:buffer BUFFER -- BUFFER is the buffer (or buffer-name) to associate
with the process. Process output goes at the end of that buffer,
unless you specify a filter function to handle the output. If BUFFER
is not given, the value of NAME is used.
:coding CODING -- If CODING is a symbol, it specifies the coding
system used for both reading and writing for this process. If CODING
is a cons (DECODING . ENCODING), DECODING is used for reading, and
ENCODING is used for writing.
:noquery BOOL -- When exiting Emacs, query the user if BOOL is nil and
the process is running. If BOOL is not given, query before exiting.
:stop BOOL -- Start process in the stopped state if BOOL non-nil.
In the stopped state, a pipe process does not accept incoming data,
but you can send outgoing data. The stopped state is cleared by
continue-process and set by stop-process.
:filter FILTER -- Install FILTER as the process filter.
:sentinel SENTINEL -- Install SENTINEL as the process sentinel.
Probably introduced at or before Emacs version 28.1.
Source Code
// Defined in /usr/src/emacs/src/process.c
{
Lisp_Object proc, contact;
struct Lisp_Process *p;
Lisp_Object name, buffer;
Lisp_Object tem;
int inchannel, outchannel;
if (nargs == 0)
return Qnil;
contact = Flist (nargs, args);
name = plist_get (contact, QCname);
CHECK_STRING (name);
proc = make_process (name);
specpdl_ref specpdl_count = SPECPDL_INDEX ();
record_unwind_protect (remove_process, proc);
p = XPROCESS (proc);
if (emacs_pipe (p->open_fd + SUBPROCESS_STDIN) != 0
|| emacs_pipe (p->open_fd + READ_FROM_SUBPROCESS) != 0)
report_file_error ("Creating pipe", Qnil);
outchannel = p->open_fd[WRITE_TO_SUBPROCESS];
inchannel = p->open_fd[READ_FROM_SUBPROCESS];
if (FD_SETSIZE <= inchannel || FD_SETSIZE <= outchannel)
report_file_errno ("Creating pipe", Qnil, EMFILE);
fcntl (inchannel, F_SETFL, O_NONBLOCK);
fcntl (outchannel, F_SETFL, O_NONBLOCK);
#ifdef WINDOWSNT
register_aux_fd (inchannel);
#endif
/* Record this as an active process, with its channels. */
eassert (0 <= inchannel && inchannel < FD_SETSIZE);
chan_process[inchannel] = proc;
p->infd = inchannel;
p->outfd = outchannel;
if (inchannel > max_desc)
max_desc = inchannel;
buffer = plist_get (contact, QCbuffer);
if (NILP (buffer))
buffer = name;
buffer = Fget_buffer_create (buffer, Qnil);
pset_buffer (p, buffer);
pset_childp (p, contact);
pset_plist (p, Fcopy_sequence (plist_get (contact, QCplist)));
pset_type (p, Qpipe);
pset_sentinel (p, plist_get (contact, QCsentinel));
pset_filter (p, plist_get (contact, QCfilter));
eassert (NILP (p->log));
if (tem = plist_get (contact, QCnoquery), !NILP (tem))
p->kill_without_query = 1;
if (tem = plist_get (contact, QCstop), !NILP (tem))
pset_command (p, Qt);
eassert (! p->pty_in && ! p->pty_out);
if (!EQ (p->command, Qt)
&& !EQ (p->filter, Qt))
add_process_read_fd (inchannel);
p->adaptive_read_buffering
= (NILP (Vprocess_adaptive_read_buffering) ? 0
: EQ (Vprocess_adaptive_read_buffering, Qt) ? 1 : 2);
/* Make the process marker point into the process buffer (if any). */
update_process_mark (p);
{
/* Setup coding systems for communicating with the network stream. */
/* Qt denotes we have not yet called Ffind_operation_coding_system. */
Lisp_Object coding_systems = Qt;
Lisp_Object val;
tem = plist_get (contact, QCcoding);
val = Qnil;
if (!NILP (tem))
{
val = tem;
if (CONSP (val))
val = XCAR (val);
}
else if (!NILP (Vcoding_system_for_read))
val = Vcoding_system_for_read;
else if ((!NILP (buffer) && NILP (BVAR (XBUFFER (buffer), enable_multibyte_characters)))
|| (NILP (buffer) && NILP (BVAR (&buffer_defaults, enable_multibyte_characters))))
/* We dare not decode end-of-line format by setting VAL to
Qraw_text, because the existing Emacs Lisp libraries
assume that they receive bare code including a sequence of
CR LF. */
val = Qnil;
else
{
if (CONSP (coding_systems))
val = XCAR (coding_systems);
else if (CONSP (Vdefault_process_coding_system))
val = XCAR (Vdefault_process_coding_system);
else
val = Qnil;
}
pset_decode_coding_system (p, val);
if (!NILP (tem))
{
val = tem;
if (CONSP (val))
val = XCDR (val);
}
else if (!NILP (Vcoding_system_for_write))
val = Vcoding_system_for_write;
else if (NILP (BVAR (current_buffer, enable_multibyte_characters)))
val = Qnil;
else
{
if (CONSP (coding_systems))
val = XCDR (coding_systems);
else if (CONSP (Vdefault_process_coding_system))
val = XCDR (Vdefault_process_coding_system);
else
val = Qnil;
}
pset_encode_coding_system (p, val);
}
/* This may signal an error. */
setup_process_coding_systems (proc);
pset_decoding_buf (p, empty_unibyte_string);
eassert (p->decoding_carryover == 0);
pset_encoding_buf (p, empty_unibyte_string);
specpdl_ptr = specpdl_ref_to_ptr (specpdl_count);
return proc;
}