aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/event/process.c
Commit message (Collapse)AuthorAge
* fix(pty): Always use $TERM from the job's env dictJames McCoy2021-02-06
| | | | | | | | | | | | | | | | | | | | | | Before #12937, the only way to specify the `$TERM` for a pty job was through the `TERM` key in the job's opts dict. This was shuttled to the child process throug a special field on the PtyProcess object and injected into the environment after forking. Now that we have a proper way to specify the environment for a job, we can simply ensure that the env dict has a proper `TERM` set and avoid the extra shuttling of data around. This deprecates the use of the `TERM` option, but will still honor it if present, although at a lower priority than a `TERM` present in the env dict. This also fixes #13874 because we're no longer trying to overwrite `TERM` in the env dict with the special pty `term_name`. Doing so raises an internal error because of the existing key which, under certain circumstances, would cause the "hit enter" prompt. However, since the child process had already forked, there was no way for the user to acknowledge the prompt and we would just hang there.
* f_jobwait: cleanupJustin M. Keyes2019-09-03
|
* channels: reflect exit due to signals in exit status code (#10573)Daniel Hahler2019-08-09
| | | | | Uses `128 + term_signal` in case of exit due to a signal. Fixes https://github.com/neovim/neovim/issues/10571.
* process_stop: uv: do not close stdin first/explicitly #10584Daniel Hahler2019-08-01
| | | | | | | | | | - process_stop: do not close stdin explicitly. The "close stdin" step was from aa9cb48, before we fixed/reworked the SIGTERM timing logic. So it's probably outdated / no longer needed. - win: jobstop: exit_code 15 GetExitCodeProcess appears to return the used signal. https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-getexitcodeprocess ref #10573
* CI: improve gcov handling #10404Daniel Hahler2019-07-07
| | | | | | | | | - Move __gcov_flush to process_spawn, for more reliable coverage tracking of subprocesses - Travis: use GCOV_ERROR_FILE - codecov: use "-X fix" to skip "fixing" uploaded coverage data; it should be handled by codecov's backend instead. - AppVeyor: no $PATH mangling, which breaks with the improved coverage tracking due to missing .dll in PATH.
* gcov: use __gcov_flush instead of __gcov_dump (#10260)Daniel Hahler2019-06-18
| | | | | | This restores missing coverage again. Move it to process_spawn in os/pty_process_unix.c, since it seems to break printargs-test on Windows/AppVeyor otherwise (#10248).
* Dump gcov coverage in process_spawn (#10230)Daniel Hahler2019-06-15
| | | Fixes https://github.com/neovim/neovim/pull/3926#issuecomment-502343527.
* Merge #8218 'Fix errors reported by PVS'Justin M. Keyes2018-04-27
|\ | | | | closes #4983
| * event/process: Silence PVS/V547: assuming stream->num_bytes changesZyX2018-04-17
| | | | | | | | Not familiar with the code, but I assume that loop_poll_events can actually change stream->num_bytes, so condition is not always false.
* | IO: shada should respect 'fsync' optionJustin M. Keyes2018-04-21
| | | | | | | | | | | | | | shada_write_file() is called on exit (:quit and friends), this can be very slow. Note: AFAICT Vim (do_viminfo()) does not appear to fsync() viminfo.
* | job-control: children_kill_cb(): do not check elapsed timeJustin M. Keyes2018-04-15
| | | | | | | | | | | | | | | | | | 1. Don't check elapsed time in children_kill_cb(), it's already implied by the start-time of the timer itself. 2. Restart timer from children_kill_cb() for PTY jobs, to send SIGKILL after SIGTERM. There is an edge case where SIGKILL might follow SIGTERM too quickly, if jobstop() is called near the 2-second timer window. But this edge case is not worth code complication.
* | job-control: one-shot timer instead of repeatingJustin M. Keyes2018-04-15
| | | | | | | | | | | | | | | | | | | | | | | | Before f31c26f1afb5 the timer was used to try SIGTERM *and* SIGKILL, so a repeating timer was needed. After f31c26f1afb5 process_stop() sends SIGTERM immediately, and the timer only sends SIGKILL. So we don't need a repeating timer. - Simplifies the logic: don't need to call uv_timer_stop() explicitly. - Avoids a problem: if process_stop() is called more than once in the 2-second window, the first on_process_exit() would call uv_timer_stop() which stops the timer for all stopped processes.
* | job-control: mitigate process-kill raceJustin M. Keyes2018-04-15
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | children_kill_cb() is racey. One obvious problem is that process_close_handles() is *queued* by on_process_exit(), so when children_kill_cb() is invoked, the dead process might still be in the `loop->children` list. If the OS already reclaimed the dead PID, Nvim may try to SIGKILL it. Avoid that by checking `proc->status`. Vim doesn't have this problem because it doesn't attempt to kill processes that ignored SIGTERM after a timeout. closes #8269
* | loop: remove `children_stop_requests`Justin M. Keyes2018-04-15
|/ | | | | It serves no purpose because process_stop() is already guarded by `proc->stopped_time`.
* win: os_proc_tree_kill()Justin M. Keyes2018-03-16
| | | | | | | | XXX: comment at https://stackoverflow.com/q/1173342 : > Windows recycles PIDs quite fast, you have to be extra careful not > to kill unrelated processes. These APIs will report PPIDs for long > dead processes whose PIDs may have been recycled. Check the parent > start date to make sure it is related to the processes you spawned.
* jobs: child proc must have a separate process-groupJustin M. Keyes2018-03-16
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | UV_PROCESS_DETACHED compels libuv:uv__process_child_init() to call setsid() in the child just after fork(). That ensures the process and its descendants are grouped in a separate session (and process group). The following jobstart() call correctly groups `sh` and `sleep` in a new session (and process-group), where `sh` is the "session leader" (and process-group leader): :call jobstart(['sh','-c','sleep 60']) SESN PGRP PID PPID Command 30383 30383 30383 3620 │ ├─ -bash 30383 31432 31432 30383 │ │ └─ nvim -u NORC 30383 31432 31433 30383 │ │ ├─ nvim -u NORC 8105 8105 8105 31432 │ │ └─ sh -c sleep 60 8105 8105 8106 8105 │ │ └─ sleep 60 closes #6530 ref: https://stackoverflow.com/q/1046933 ref: https://unix.stackexchange.com/a/404065 Helped-by: Marco Hinz <mh.codebro+github@gmail.com> Discussion ------------------------------------------------------------------------ On my linux box before this patch, the termclose_spec.lua:'kills job trapping SIGTERM' test indirectly causes cmake/busted to wait for 60s. That's because the test spawns a `sleep 60` descendant process which hangs around even after nvim exits: nvim killed the parent PID, but not PGID (process-group), so the grandchild "reparented" to init (PID 1). Session contains processes (and process-groups) which are logically part of the same "login session". Process-group is a set of logically/informally-related processes within a session; for example, shells assign a process group to each "job". Session IDs and PGIDs both have type pid_t (like PIDs). These OS-level mechanisms are, as usual, legacy accidents whose purpose is upheld by convention and folklore. We can use session-level grouping (setsid), or we could use process-group-level grouping (setpgid). Vim uses setsid() if available, otherwise setpgid(0,0). Windows ------------------------------------------------------------------------ UV_PROCESS_DETACHED on win32 sets CREATE_NEW_PROCESS_GROUP flag. But uv_kill() does not kill the process-group: https://github.com/nodejs/node/issues/3617 Ideas: - Set UV_PROCESS_DETACHED (CREATE_NEW_PROCESS_GROUP), then call GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT, pid) - Maybe won't work because MSDN says "Only processes that share the same console as the calling process receive the signal." https://docs.microsoft.com/en-us/windows/console/generateconsolectrlevent But CREATE_NEW_PROCESS_GROUP creates a new console ... ref https://stackoverflow.com/q/1453520 - Group processes within a "job". libuv does that *globally* for non-detached processes: uv__init_global_job_handle. - Iterate through CreateToolhelp32Snapshot(). - https://stackoverflow.com/q/1173342 - Vim does this, see terminate_all()
* jobwait: return -2 on interrupt also with timeoutBjörn Linse2018-02-20
|
* channels: refactor jobwaitBjörn Linse2017-11-25
|
* channels: generalize jobclose()Björn Linse2017-11-25
|
* channels: allow bytes sockets and stdio, and buffered bytes outputBjörn Linse2017-11-24
|
* channels: refactorBjörn Linse2017-11-24
|
* process_close(): uv_unref() detached processes (#7539)Justin M. Keyes2017-11-12
| | | | | | | Doc for UV_PROCESS_DETACHED in uv.h mentions: > child process will still keep the parent's event loop alive unless > the parent process calls uv_unref() on the child's process handle. ref #3944
* log: some DEBUG-level stream loggingJustin M. Keyes2017-08-21
|
* jobstop/process_stop: send SIGTERM directlyDaniel Hahler2017-07-07
| | | | | This reverts the revert of #6644 (7c1a5d1d4), and handles it properly now (with tests).
* *: Fix all V641 errorsZyX2017-05-20
|
* Revert "event/process.c: send SIGTERM directly (#6644)"Justin M. Keyes2017-05-08
| | | | This reverts commit 34c3f03013375817d3d089e685793290eded553a.
* event/process.c: send SIGTERM directly (#6644)Daniel Hahler2017-05-04
| | | | | | | Send SIGTERM to processes directly, instead of waiting for ~1s. - removes TERM_TIMEOUT - changes KILL_TIMEOUT to milliseconds - removes Process.term_sent
* *: Add comment to all C filesZyX2017-04-19
|
* process_spawn: Return status code (#6075)Justin M. Keyes2017-02-09
|
* process_wait(): Avoid dereference after LOOP_PROCESS_EVENTS. (#5917)Justin M. Keyes2017-01-09
|
* event/multiqueue.c: Rename "queue" to "multiqueue".Justin M. Keyes2016-10-02
| | | | | | | | | | | | | | `lib/queue.h` implements a basic queue. `event/queue.c` implements a specialized data structure on top of lib/queue.h; it is not a "normal" queue. Rename the specialized multi-level queue implemented in event/queue.c to "multiqueue", to avoid confusion when reading the code. Before this change one can eventually notice that "macros (uppercase symbols) are for the normal queue, lowercase operations are for the multi-level queue", but that is unnecessary friction for new developers (or existing developers just visiting this part of the codebase).
* signal_init: Always unblock SIGCHLD. (#5243)Justin M. Keyes2016-08-29
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Inherited signal mask may block SIGCHLD, which causes libuv to hang at epoll_wait. Closes #5230 Helped-by: Nicolas Hillegeer <nicolas@hillegeer.com> Helped-by: John Szakmeister <john@szakmeister.net> Note: the #pragma gymnastics are a workaround for broken system headers on macOS. signal.h: int sigaddset(sigset_t *, int); #define sigaddset(set, signo) (*(set) |= __sigbits(signo), 0) sys/_types/_sigset.h: typedef __darwin_sigset_t sigset_t; sys/_types.h: typedef __uint32_t __darwin_sigset_t; /* [???] signal set */ sigset_t is defined as unsigned int, but the sigaddset() ORs it with an int, mixing the types. So GCC generates a sign-conversion warning: sig.c:9:13: warning: implicit conversion changes signedness: 'int' to 'unsigned int' [-Wsign-conversion] (*(&s) |= __sigbits((sigset_t) 20), 0); ~~ ^~~~~~~~~~~~~~~~~~~~~~~~ 1 warning generated. System headers are normally ignored when the compiler generates warnings: https://gcc.gnu.org/onlinedocs/cpp/System-Headers.html > GCC gives code found in system headers special treatment. All warnings, > other than those generated by ‘#warning’ (see Diagnostics), are suppressed > while GCC is processing a system header. Macros defined in a system header > are immune to a few warnings wherever they are expanded. This immunity is > granted on an ad-hoc basis, when we find that a warning generates lots of > false positives because of code in macros defined in system headers. Instead of the #pragma workaround, we could cast the sigset_t pointer: # if defined(__APPLE__) sigaddset((int *)&mask, SIGCHLD); # else sigaddset(&mask, SIGCHLD); # endif but that could break if the headers are later fixed.
* stream: set data together with callbackBjörn Linse2016-08-20
|
* Merge #4798 'process.c: Fix block in teardown'Justin M. Keyes2016-07-16
|\
| * process.c: Close events are processed too lateoni-link2016-05-28
| | | | | | | | | | | | Compiling with macro -DEXITFREE opens a code path on which the event loop is used after it was teared down, because not all close events were processed yet.
| * process.c: Fix a block when in teardown modeoni-link2016-05-28
| | | | | | | | | | | | | | nvim blocking can be tested with "nvim +te +'!xclip' +qa" By closing all handles for a pty process, we unblock the event loop if the process has not terminated yet.
* | Merge #4646 from oni-link/fix.issue.4569.3Justin M. Keyes2016-06-26
|\ \ | | | | | | Fix for missing output (#4569, ...)
| * | fixup2: process.c: Prevent data loss for process output streamsoni-link2016-05-15
| | | | | | | | | | | | | | | | | | | | | | | | The only data loss should be, if a process forked a child that keeps sending data after the parent terminated. While not in teardown mode we could keep reading child data, but then `:!cmd` would block after `cmd` exited. In teardown mode we want to exit nvim so we cannot keep reading child data.
| * | fixup: process.c: Prevent data loss for process output streamsoni-link2016-05-15
| | | | | | | | | | | | | | | | | | * Get system buffer size for upper data limit. Otherwise data loss if this buffer is too big. * Test whether teardown needs special handling.
| * | process.c: Prevent data loss for process output streamsoni-link2016-05-15
| |/ | | | | | | | | For a terminating process, it's output streams could be closed, before all data is read.
* | *: Fix errors from new linter checksZyX2016-06-11
| |
* | pty_process: split into plat-specific files (#3976)Rui Abreu Ferreira2016-06-04
|/
* *: Fix new linter errorsZyX2016-05-01
| | | | Originally there were 128 new errors, so I thought this is a good idea to fix all of them. Of course, this commit also fixes many suppressed errors.
* job control: don't kill PTY processes on exitBjörn Linse2016-01-20
| | | | These will automatically recieve SIGHUP on closing PTY master.
* job control: add 'detach' option to jobstartBjörn Linse2016-01-20
|
* Windows: avoid "uv_" naming conflicts. #3225Seth Jackson2015-08-27
|
* eval: Protect job callbacks from being redefinedThiago de Arruda2015-08-21
| | | | ref: #3188
* eval: Fix jobwait() to process multiple jobs concurrentlyThiago de Arruda2015-08-13
| | | | | | | | | | | | | The new event processing architecture changed `jobwait()` semantics: Only one job is processed at time since process_wait only focuses on one queue. This fixes the problem with a few changes: - Allow the event queue polled by `process_wait` to be overriden by a new argument. - Allow the parent queue to be overriden with `queue_replace_parent` - Create a temporary queue that serves as the parent for all jobs passed to `jobwait()`
* event: Refactor async event processingThiago de Arruda2015-08-13
| | | | | | | | | | - Improve the implementation of deferred/immediate events. - Use the new queue module to change how/when events are queued/processed by giving a private queue to each emitter. - Immediate events(which only exist to break uv_run recursion) are now represented in the `loop->fast_events` queue. - Events pushed to child queues are propagated to the event loop main queue and processed as K_EVENT keys.
* process: Pass loop reference during initializationThiago de Arruda2015-08-13
| | | | | Change the API so that it is passed to {uv,pty}_process_init instead of `process_spawn`.