diff options
| author | Philipp Stephani | 2020-03-26 17:22:25 +0100 |
|---|---|---|
| committer | Philipp Stephani | 2020-03-26 21:47:25 +0100 |
| commit | d28b00476890f791a89b65007e5f20682b3eaa0d (patch) | |
| tree | 3bb04c984ed5b74e661291b71579fe8d04070f69 /src/process.c | |
| parent | 934b3c9ecc2b91723b9e5826080424ec1a90f264 (diff) | |
| download | emacs-d28b00476890f791a89b65007e5f20682b3eaa0d.tar.gz emacs-d28b00476890f791a89b65007e5f20682b3eaa0d.zip | |
Add a module function to open a file descriptor connected to a pipe.
A common complaint about the module API is that modules can't
communicate asynchronously with Emacs. While it isn't possible to
call arbitrary Emacs functions asynchronously, writing to a pipe
should always be fine and is a pretty low-hanging fruit.
This patch implements a function that adapts an existing pipe
process. That way, users can use familiar tools like process filters
or 'accept-process-output'.
* src/module-env-28.h: Add 'open_channel' module function.
* src/emacs-module.c (module_open_channel): Provide definition for
'open_channel'.
(initialize_environment): Use it.
* src/process.c (open_channel_for_module): New helper function.
(syms_of_process): Define necessary symbol.
* test/src/emacs-module-tests.el (module/async-pipe): New unit test.
* test/data/emacs-module/mod-test.c (signal_system_error): New helper
function.
(signal_errno): Use it.
(write_to_pipe): New function running in the background.
(Fmod_test_async_pipe): New test module function.
(emacs_module_init): Export it.
* doc/lispref/internals.texi (Module Misc): Document new module
function.
* doc/lispref/processes.texi (Asynchronous Processes): New anchor
for pipe processes.
* etc/NEWS: Document 'open_channel' function.
Diffstat (limited to 'src/process.c')
| -rw-r--r-- | src/process.c | 12 |
1 files changed, 12 insertions, 0 deletions
diff --git a/src/process.c b/src/process.c index e4e5e57aeee..07881d6c5d3 100644 --- a/src/process.c +++ b/src/process.c | |||
| @@ -8200,6 +8200,17 @@ restore_nofile_limit (void) | |||
| 8200 | #endif | 8200 | #endif |
| 8201 | } | 8201 | } |
| 8202 | 8202 | ||
| 8203 | int | ||
| 8204 | open_channel_for_module (Lisp_Object process) | ||
| 8205 | { | ||
| 8206 | CHECK_PROCESS (process); | ||
| 8207 | CHECK_TYPE (PIPECONN_P (process), Qpipe_process_p, process); | ||
| 8208 | int fd = dup (XPROCESS (process)->open_fd[SUBPROCESS_STDOUT]); | ||
| 8209 | if (fd == -1) | ||
| 8210 | report_file_error ("Cannot duplicate file descriptor", Qnil); | ||
| 8211 | return fd; | ||
| 8212 | } | ||
| 8213 | |||
| 8203 | 8214 | ||
| 8204 | /* This is not called "init_process" because that is the name of a | 8215 | /* This is not called "init_process" because that is the name of a |
| 8205 | Mach system call, so it would cause problems on Darwin systems. */ | 8216 | Mach system call, so it would cause problems on Darwin systems. */ |
| @@ -8446,6 +8457,7 @@ amounts of data in one go. */); | |||
| 8446 | DEFSYM (Qinterrupt_process_functions, "interrupt-process-functions"); | 8457 | DEFSYM (Qinterrupt_process_functions, "interrupt-process-functions"); |
| 8447 | 8458 | ||
| 8448 | DEFSYM (Qnull, "null"); | 8459 | DEFSYM (Qnull, "null"); |
| 8460 | DEFSYM (Qpipe_process_p, "pipe-process-p"); | ||
| 8449 | 8461 | ||
| 8450 | defsubr (&Sprocessp); | 8462 | defsubr (&Sprocessp); |
| 8451 | defsubr (&Sget_process); | 8463 | defsubr (&Sget_process); |