elisp: Asynchronous Processes

 
 36.4 Creating an Asynchronous Process
 =====================================
 
 In this section, we describe how to create an “asynchronous process”.
 After an asynchronous process is created, it runs in parallel with
 Emacs, and Emacs can communicate with it using the functions described
DONTPRINTYET  in the following sections (SeeInput to Processes, and *noteOutput
DONTPRINTYET  in the following sections (SeeInput to Processes, and SeeOutput

 from Processes).  Note that process communication is only partially
 asynchronous: Emacs sends data to the process only when certain
 functions are called, and Emacs accepts data from the process only while
 waiting for input or for a time delay.
 
    An asynchronous process is controlled either via a “pty”
 (pseudo-terminal) or a “pipe”.  The choice of pty or pipe is made when
 creating the process, by default based on the value of the variable
 ‘process-connection-type’ (see below).  If available, ptys are usually
 preferable for processes visible to the user, as in Shell mode, because
 they allow for job control (‘C-c’, ‘C-z’, etc.) between the process and
 its children, and because interactive programs treat ptys as terminal
 devices, whereas pipes don’t support these features.  However, for
 subprocesses used by Lisp programs for internal purposes, it is often
 better to use a pipe, because pipes are more efficient, and because they
 are immune to stray character injections that ptys introduce for large
 (around 500 byte) messages.  Also, the total number of ptys is limited
 on many systems and it is good not to waste them.
 
  -- Function: make-process &rest args
      This function is the basic low-level primitive for starting
      asynchronous subprocesses.  It returns a process object
      representing the subprocess.  Compared to the more high-level
      ‘start-process’, described below, it takes keyword arguments, is
      more flexible, and allows to specify process filters and sentinels
      in a single call.
 
      The arguments ARGS are a list of keyword/argument pairs.  Omitting
      a keyword is always equivalent to specifying it with value ‘nil’.
      Here are the meaningful keywords:
 
      :name NAME
           Use the string NAME as the process name; if a process with
           this name already exists, then NAME is modified (by appending
           ‘<1>’, etc.) to be unique.
 
      :buffer BUFFER
           Use BUFFER as the process buffer.  If the value is ‘nil’, the
           subprocess is not associated with any buffer.
 
      :command COMMAND
           Use COMMAND as the command line of the process.  The value
           should be a list starting with the program’s executable file
           name, followed by strings to give to the program as its
           arguments.  If the first element of the list is ‘nil’, Emacs
           opens a new pseudoterminal (pty) and associates its input and
           output with BUFFER, without actually running any program; the
           rest of the list elements are ignored in that case.
 
      :coding CODING
           If CODING is a symbol, it specifies the coding system to be
           used for both reading and writing of data from and to the
           connection.  If CODING is a cons cell ‘(DECODING . ENCODING)’,
           then DECODING will be used for reading and ENCODING for
           writing.  The coding system used for encoding the data written
           to the program is also used for encoding the command-line
           arguments (but not the program itself, whose file name is
           encoded as any other file name; Seefile-name-coding-system
           Encoding and I/O.).
 
           If CODING is ‘nil’, the default rules for finding the coding
           system will apply.  SeeDefault Coding Systems.
 
      :connection-type TYPE
           Initialize the type of device used to communicate with the
           subprocess.  Possible values are ‘pty’ to use a pty, ‘pipe’ to
           use a pipe, or ‘nil’ to use the default derived from the value
           of the ‘process-connection-type’ variable.  This parameter and
           the value of ‘process-connection-type’ are ignored if a
           non-‘nil’ value is specified for the ‘:stderr’ parameter; in
           that case, the type will always be ‘pipe’.
 
      :noquery QUERY-FLAG
           Initialize the process query flag to QUERY-FLAG.  SeeQuery
           Before Exit.
 
      :stop STOPPED
           If STOPPED is non-‘nil’, start the process in the stopped
           state.
 
      :filter FILTER
           Initialize the process filter to FILTER.  If not specified, a
           default filter will be provided, which can be overridden
           later.  SeeFilter Functions.
 
      :sentinel SENTINEL
           Initialize the process sentinel to SENTINEL.  If not
           specified, a default sentinel will be used, which can be
           overridden later.  SeeSentinels.
 
      :stderr STDERR
           Associate STDERR with the standard error of the process.  A
           non-‘nil’ value should be either a buffer or a pipe process
           created with ‘make-pipe-process’, described below.
 
      The original argument list, modified with the actual connection
      information, is available via the ‘process-contact’ function.
 
      The current working directory of the subprocess is set to the
      current buffer’s value of ‘default-directory’ if that is local (as
      determined by ‘unhandled-file-name-directory’), or "~" otherwise.
      If you want to run a process in a remote direcotry use
      ‘start-file-process’.
 
  -- Function: make-pipe-process &rest args
      This function creates a bidirectional pipe which can be attached to
      a child process.  This is useful with the ‘:stderr’ keyword of
      ‘make-process’.  The function returns a process object.
 
      The arguments ARGS are a list of keyword/argument pairs.  Omitting
      a keyword is always equivalent to specifying it with value ‘nil’.
 
      Here are the meaningful keywords:
 
      :name NAME
           Use the string NAME as the process name.  As with
           ‘make-process’, it is modified if necessary to make it unique.
 
      :buffer BUFFER
           Use BUFFER as the process buffer.
 
      :coding CODING
           If CODING is a symbol, it specifies the coding system to be
           used for both reading and writing of data from and to the
           connection.  If CODING is a cons cell ‘(DECODING . ENCODING)’,
           then DECODING will be used for reading and ENCODING for
           writing.
 
           If CODING is ‘nil’, the default rules for finding the coding
           system will apply.  SeeDefault Coding Systems.
 
      :noquery QUERY-FLAG
           Initialize the process query flag to QUERY-FLAG.  SeeQuery
           Before Exit.
 
      :stop STOPPED
           If STOPPED is non-‘nil’, start the process in the stopped
           state.
 
      :filter FILTER
           Initialize the process filter to FILTER.  If not specified, a
           default filter will be provided, which can be changed later.
           SeeFilter Functions.
 
      :sentinel SENTINEL
           Initialize the process sentinel to SENTINEL.  If not
           specified, a default sentinel will be used, which can be
           changed later.  SeeSentinels.
 
      The original argument list, modified with the actual connection
      information, is available via the ‘process-contact’ function.
 
  -- Function: start-process name buffer-or-name program &rest args
      This function is a higher-level wrapper around ‘make-process’,
      exposing an interface that is similar to ‘call-process’.  It
      creates a new asynchronous subprocess and starts the specified
      PROGRAM running in it.  It returns a process object that stands for
      the new subprocess in Lisp.  The argument NAME specifies the name
      for the process object; as with ‘make-process’, it is modified if
      necessary to make it unique.  The buffer BUFFER-OR-NAME is the
      buffer to associate with the process.
 
      If PROGRAM is ‘nil’, Emacs opens a new pseudoterminal (pty) and
      associates its input and output with BUFFER-OR-NAME, without
      creating a subprocess.  In that case, the remaining arguments ARGS
      are ignored.
 
      The rest of ARGS are strings that specify command line arguments
      for the subprocess.
 
      In the example below, the first process is started and runs
      (rather, sleeps) for 100 seconds (the output buffer ‘foo’ is
      created immediately).  Meanwhile, the second process is started,
      and given the name ‘my-process<1>’ for the sake of uniqueness.  It
      inserts the directory listing at the end of the buffer ‘foo’,
      before the first process finishes.  Then it finishes, and a message
      to that effect is inserted in the buffer.  Much later, the first
      process finishes, and another message is inserted in the buffer for
      it.
 
           (start-process "my-process" "foo" "sleep" "100")
                ⇒ #<process my-process>
 
           (start-process "my-process" "foo" "ls" "-l" "/bin")
                ⇒ #<process my-process<1>>
 
           ---------- Buffer: foo ----------
           total 8336
           -rwxr-xr-x 1 root root 971384 Mar 30 10:14 bash
           -rwxr-xr-x 1 root root 146920 Jul  5  2011 bsd-csh
           ...
           -rwxr-xr-x 1 root root 696880 Feb 28 15:55 zsh4
 
           Process my-process<1> finished
 
           Process my-process finished
           ---------- Buffer: foo ----------
 
  -- Function: start-file-process name buffer-or-name program &rest args
      Like ‘start-process’, this function starts a new asynchronous
      subprocess running PROGRAM in it, and returns its process object.
 
      The difference from ‘start-process’ is that this function may
      invoke a file handler based on the value of ‘default-directory’.
      This handler ought to run PROGRAM, perhaps on the local host,
      perhaps on a remote host that corresponds to ‘default-directory’.
      In the latter case, the local part of ‘default-directory’ becomes
      the working directory of the process.
 
      This function does not try to invoke file name handlers for PROGRAM
      or for the rest of ARGS.
 
      Depending on the implementation of the file handler, it might not
      be possible to apply ‘process-filter’ or ‘process-sentinel’ to the
DONTPRINTYET       resulting process object.  SeeFilter Functions, and *noteDONTPRINTYET       resulting process object.  SeeFilter Functions, and See
      Sentinels.
 
      Some file handlers may not support ‘start-file-process’ (for
      example the function ‘ange-ftp-hook-function’).  In such cases,
      this function does nothing and returns ‘nil’.
 
  -- Function: start-process-shell-command name buffer-or-name command
      This function is like ‘start-process’, except that it uses a shell
      to execute the specified COMMAND.  The argument COMMAND is a shell
      command string.  The variable ‘shell-file-name’ specifies which
      shell to use.
 
      The point of running a program through the shell, rather than
      directly with ‘make-process’ or ‘start-process’, is so that you can
      employ shell features such as wildcards in the arguments.  It
      follows that if you include any arbitrary user-specified arguments
      in the command, you should quote them with ‘shell-quote-argument’
      first, so that any special shell characters do _not_ have their
      special shell meanings.  SeeShell Arguments.  Of course, when
      executing commands based on user input you should also consider the
      security implications.
 
  -- Function: start-file-process-shell-command name buffer-or-name
           command
      This function is like ‘start-process-shell-command’, but uses
      ‘start-file-process’ internally.  Because of this, COMMAND can also
      be executed on remote hosts, depending on ‘default-directory’.
 
  -- Variable: process-connection-type
      This variable controls the type of device used to communicate with
      asynchronous subprocesses.  If it is non-‘nil’, then ptys are used,
      when available.  Otherwise, pipes are used.
 
      The value of ‘process-connection-type’ takes effect when
      ‘make-process’ or ‘start-process’ is called.  So you can specify
      how to communicate with one subprocess by binding the variable
      around the call to these functions.
 
      Note that the value of this variable is ignored when ‘make-process’
      is called with a non-‘nil’ value of the ‘:stderr’ parameter; in
      that case, Emacs will communicate with the process using pipes.
 
           (let ((process-connection-type nil))  ; use a pipe
             (start-process ...))
 
      To determine whether a given subprocess actually got a pipe or a
      pty, use the function ‘process-tty-name’ (SeeProcess
      Information).