summaryrefslogtreecommitdiff
path: root/devdocs/elisp/accepting-output.html
blob: 40e7938f37c7bfd40a6bd0be00027e0a44b93c2c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
 <h4 class="subsection">Accepting Output from Processes</h4>  <p>Output from asynchronous subprocesses normally arrives only while Emacs is waiting for some sort of external event, such as elapsed time or terminal input. Occasionally it is useful in a Lisp program to explicitly permit output to arrive at a specific point, or even to wait until output arrives from a process. </p> <dl> <dt id="accept-process-output">Function: <strong>accept-process-output</strong> <em>&amp;optional process seconds millisec just-this-one</em>
</dt> <dd>
<p>This function allows Emacs to read pending output from processes. The output is given to their filter functions. If <var>process</var> is non-<code>nil</code> then this function does not return until some output has been received from <var>process</var> or <var>process</var> has closed the connection. </p> <p>The arguments <var>seconds</var> and <var>millisec</var> let you specify timeout periods. The former specifies a period measured in seconds and the latter specifies one measured in milliseconds. The two time periods thus specified are added together, and <code>accept-process-output</code> returns after that much time, even if there is no subprocess output. </p> <p>The argument <var>millisec</var> is obsolete (and should not be used), because <var>seconds</var> can be floating point to specify waiting a fractional number of seconds. If <var>seconds</var> is 0, the function accepts whatever output is pending but does not wait. </p> <p>If <var>process</var> is a process, and the argument <var>just-this-one</var> is non-<code>nil</code>, only output from that process is handled, suspending output from other processes until some output has been received from that process or the timeout expires. If <var>just-this-one</var> is an integer, also inhibit running timers. This feature is generally not recommended, but may be necessary for specific applications, such as speech synthesis. </p> <p>The function <code>accept-process-output</code> returns non-<code>nil</code> if it got output from <var>process</var>, or from any process if <var>process</var> is <code>nil</code>; this can occur even after a process has exited if the corresponding connection contains buffered data. The function returns <code>nil</code> if the timeout expired or the connection was closed before output arrived. </p>
</dd>
</dl> <p>If a connection from a process contains buffered data, <code>accept-process-output</code> can return non-<code>nil</code> even after the process has exited. Therefore, although the following loop: </p> <div class="example"> <pre class="example">;; This loop contains a bug.
(while (process-live-p process)
  (accept-process-output process))
</pre>
</div> <p>will often read all output from <var>process</var>, it has a race condition and can miss some output if <code>process-live-p</code> returns <code>nil</code> while the connection still contains data. Better is to write the loop like this: </p> <div class="example"> <pre class="example">(while (accept-process-output process))
</pre>
</div> <p>If you have passed a non-<code>nil</code> <var>stderr</var> to <code>make-process</code>, it will have a standard error process. See <a href="asynchronous-processes">Asynchronous Processes</a>. In that case, waiting for process output from the main process doesn’t wait for output from the standard error process. To make sure you have received both all of standard output and all of standard error from a process, use the following code: </p> <div class="example"> <pre class="example">(while (accept-process-output process))
(while (accept-process-output stderr-process))
</pre>
</div> <p>If you passed a buffer to the <var>stderr</var> argument of <code>make-process</code>, you still have to wait for the standard error process, like so: </p> <div class="example"> <pre class="example">(let* ((stdout (generate-new-buffer "stdout"))
       (stderr (generate-new-buffer "stderr"))
       (process (make-process :name "test"
                              :command '("my-program")
                              :buffer stdout
                              :stderr stderr))
       (stderr-process (get-buffer-process stderr)))
  (unless (and process stderr-process)
    (error "Process unexpectedly nil"))
  (while (accept-process-output process))
  (while (accept-process-output stderr-process)))
</pre>
</div> <p>Only when both <code>accept-process-output</code> forms return <code>nil</code>, you can be sure that the process has exited and Emacs has read all its output. </p> <p>Reading pending standard error from a process running on a remote host is not possible this way. </p><div class="_attribution">
  <p class="_attribution-p">
    Copyright &copy; 1990-1996, 1998-2022 Free Software Foundation, Inc. <br>Licensed under the GNU GPL license.<br>
    <a href="https://www.gnu.org/software/emacs/manual/html_node/elisp/Accepting-Output.html" class="_attribution-link">https://www.gnu.org/software/emacs/manual/html_node/elisp/Accepting-Output.html</a>
  </p>
</div>