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. BUFFER may be also nil, meaning
that this process is not associated with any buffer.
: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 buffer;
Lisp_Object tem;
int inchannel, outchannel;
if (nargs == 0)
return Qnil;
CHECK_KEYWORD_ARGS (nargs);
contact = Flist (nargs, args);
Lisp_Object name = get_required_string_keyword_param (contact, QCname);
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;
{
Lisp_Object buffer_member = plist_member (contact, QCbuffer);
if (NILP (buffer_member))
buffer = name;
else
buffer = XCAR (XCDR (buffer_member));
}
if (!NILP (buffer))
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;
}