diff options
| author | Jim Porter | 2022-07-17 20:25:00 -0700 |
|---|---|---|
| committer | Jim Porter | 2022-08-05 17:58:54 -0700 |
| commit | d7b89ea4077d4fe677ba0577245328819ee79cdc (patch) | |
| tree | d4e499042bdf2f301be7f2d7ec05f0d1bfd8d44b /lisp/eshell | |
| parent | b70369c557efed3dcd86dc64a2e73e3480dea6af (diff) | |
| download | emacs-d7b89ea4077d4fe677ba0577245328819ee79cdc.tar.gz emacs-d7b89ea4077d4fe677ba0577245328819ee79cdc.zip | |
Allow creating processes where only one of stdin or stdout is a PTY
* src/lisp.h (emacs_spawn):
* src/callproc.c (emacs_spawn): Add PTY_IN and PTY_OUT arguments to
specify which streams should be set up as a PTY.
(call_process): Adjust call to 'emacs_spawn'.
* src/process.h (Lisp_Process): Replace 'pty_flag' with 'pty_in' and
'pty_out'.
* src/process.c (is_pty_from_symbol): New function.
(make-process): Allow :connection-type to be a cons cell, and allow
using a stderr process with a PTY for stdin/stdout.
(create_process): Handle creating a process where only one of stdin or
stdout is a PTY.
* lisp/eshell/esh-proc.el (eshell-needs-pipe, eshell-needs-pipe-p):
Remove.
(eshell-gather-process-output): Use 'make-process' and set
':connection-type' as needed by the value of 'eshell-in-pipeline-p'.
* lisp/net/tramp.el (tramp-handle-make-process):
* lisp/net/tramp-adb.el (tramp-adb-handle-make-process):
* lisp/net/tramp-sh.el (tramp-sh-handle-make-process): Don't signal an
error when ':connection-type' is a cons cell.
* test/src/process-tests.el
(process-test-sentinel-wait-function-working-p): Allow passing PROC
in, and rework into...
(process-test-wait-for-sentinel): ... this.
(process-test-sentinel-accept-process-output)
(process-test-sentinel-sit-for, process-test-quoted-batfile)
(process-test-stderr-filter): Use 'process-test-wait-for-sentinel'.
(make/process/test-connection-type): New function.
(make-process/connection-type/pty, make-process/connection-type/pty-2)
(make-process/connection-type/pipe)
(make-process/connection-type/pipe-2)
(make-process/connection-type/in-pty)
(make-process/connection-type/out-pty)
(make-process/connection-type/pty-with-stderr-buffer)
(make-process/connection-type/out-pty-with-stderr-buffer): New tests.
* test/lisp/eshell/esh-proc-tests.el (esh-proc-test--detect-pty-cmd):
New variable.
(esh-proc-test/pipeline-connection-type/no-pipeline)
(esh-proc-test/pipeline-connection-type/first)
(esh-proc-test/pipeline-connection-type/middle)
(esh-proc-test/pipeline-connection-type/last): New tests.
* doc/lispref/processes.texi (Asynchronous Processes): Document new
':connection-type' behavior.
(Output from Processes): Remove caveat about ':stderr' forcing
'make-process' to use pipes.
* etc/NEWS: Announce this change (bug#56025).
Diffstat (limited to 'lisp/eshell')
| -rw-r--r-- | lisp/eshell/esh-proc.el | 55 |
1 files changed, 18 insertions, 37 deletions
diff --git a/lisp/eshell/esh-proc.el b/lisp/eshell/esh-proc.el index 70426ccaf2a..99b43661f2c 100644 --- a/lisp/eshell/esh-proc.el +++ b/lisp/eshell/esh-proc.el | |||
| @@ -250,30 +250,6 @@ The prompt will be set to PROMPT." | |||
| 250 | "A marker that tracks the beginning of output of the last subprocess. | 250 | "A marker that tracks the beginning of output of the last subprocess. |
| 251 | Used only on systems which do not support async subprocesses.") | 251 | Used only on systems which do not support async subprocesses.") |
| 252 | 252 | ||
| 253 | (defvar eshell-needs-pipe | ||
| 254 | '("bc" | ||
| 255 | ;; xclip.el (in GNU ELPA) calls all of these with | ||
| 256 | ;; `process-connection-type' set to nil. | ||
| 257 | "pbpaste" "putclip" "xclip" "xsel" "wl-copy") | ||
| 258 | "List of commands which need `process-connection-type' to be nil. | ||
| 259 | Currently only affects commands in pipelines, and not those at | ||
| 260 | the front. If an element contains a directory part it must match | ||
| 261 | the full name of a command, otherwise just the nondirectory part must match.") | ||
| 262 | |||
| 263 | (defun eshell-needs-pipe-p (command) | ||
| 264 | "Return non-nil if COMMAND needs `process-connection-type' to be nil. | ||
| 265 | See `eshell-needs-pipe'." | ||
| 266 | (and (bound-and-true-p eshell-in-pipeline-p) | ||
| 267 | (not (eq eshell-in-pipeline-p 'first)) | ||
| 268 | ;; FIXME should this return non-nil for anything that is | ||
| 269 | ;; neither 'first nor 'last? See bug#1388 discussion. | ||
| 270 | (catch 'found | ||
| 271 | (dolist (exe eshell-needs-pipe) | ||
| 272 | (if (string-equal exe (if (string-search "/" exe) | ||
| 273 | command | ||
| 274 | (file-name-nondirectory command))) | ||
| 275 | (throw 'found t)))))) | ||
| 276 | |||
| 277 | (defun eshell-gather-process-output (command args) | 253 | (defun eshell-gather-process-output (command args) |
| 278 | "Gather the output from COMMAND + ARGS." | 254 | "Gather the output from COMMAND + ARGS." |
| 279 | (require 'esh-var) | 255 | (require 'esh-var) |
| @@ -290,31 +266,36 @@ See `eshell-needs-pipe'." | |||
| 290 | (cond | 266 | (cond |
| 291 | ((fboundp 'make-process) | 267 | ((fboundp 'make-process) |
| 292 | (setq proc | 268 | (setq proc |
| 293 | (let ((process-connection-type | 269 | (let ((command (file-local-name (expand-file-name command))) |
| 294 | (unless (eshell-needs-pipe-p command) | 270 | (conn-type (pcase (bound-and-true-p eshell-in-pipeline-p) |
| 295 | process-connection-type)) | 271 | ('first '(nil . pipe)) |
| 296 | (command (file-local-name (expand-file-name command)))) | 272 | ('last '(pipe . nil)) |
| 297 | (apply #'start-file-process | 273 | ('t 'pipe) |
| 298 | (file-name-nondirectory command) nil command args))) | 274 | ('nil nil)))) |
| 275 | (make-process | ||
| 276 | :name (file-name-nondirectory command) | ||
| 277 | :buffer (current-buffer) | ||
| 278 | :command (cons command args) | ||
| 279 | :filter (if (eshell-interactive-output-p) | ||
| 280 | #'eshell-output-filter | ||
| 281 | #'eshell-insertion-filter) | ||
| 282 | :sentinel #'eshell-sentinel | ||
| 283 | :connection-type conn-type | ||
| 284 | :file-handler t))) | ||
| 299 | (eshell-record-process-object proc) | 285 | (eshell-record-process-object proc) |
| 300 | (set-process-buffer proc (current-buffer)) | ||
| 301 | (set-process-filter proc (if (eshell-interactive-output-p) | ||
| 302 | #'eshell-output-filter | ||
| 303 | #'eshell-insertion-filter)) | ||
| 304 | (set-process-sentinel proc #'eshell-sentinel) | ||
| 305 | (run-hook-with-args 'eshell-exec-hook proc) | 286 | (run-hook-with-args 'eshell-exec-hook proc) |
| 306 | (when (fboundp 'process-coding-system) | 287 | (when (fboundp 'process-coding-system) |
| 307 | (let ((coding-systems (process-coding-system proc))) | 288 | (let ((coding-systems (process-coding-system proc))) |
| 308 | (setq decoding (car coding-systems) | 289 | (setq decoding (car coding-systems) |
| 309 | encoding (cdr coding-systems))) | 290 | encoding (cdr coding-systems))) |
| 310 | ;; If start-process decided to use some coding system for | 291 | ;; If `make-process' decided to use some coding system for |
| 311 | ;; decoding data sent from the process and the coding system | 292 | ;; decoding data sent from the process and the coding system |
| 312 | ;; doesn't specify EOL conversion, we had better convert CRLF | 293 | ;; doesn't specify EOL conversion, we had better convert CRLF |
| 313 | ;; to LF. | 294 | ;; to LF. |
| 314 | (if (vectorp (coding-system-eol-type decoding)) | 295 | (if (vectorp (coding-system-eol-type decoding)) |
| 315 | (setq decoding (coding-system-change-eol-conversion decoding 'dos) | 296 | (setq decoding (coding-system-change-eol-conversion decoding 'dos) |
| 316 | changed t)) | 297 | changed t)) |
| 317 | ;; Even if start-process left the coding system for encoding | 298 | ;; Even if `make-process' left the coding system for encoding |
| 318 | ;; data sent from the process undecided, we had better use the | 299 | ;; data sent from the process undecided, we had better use the |
| 319 | ;; same one as what we use for decoding. But, we should | 300 | ;; same one as what we use for decoding. But, we should |
| 320 | ;; suppress EOL conversion. | 301 | ;; suppress EOL conversion. |