mirror of
https://github.com/neovim/neovim.git
synced 2024-09-17 20:58:20 -04:00
refactor: rename "process" => "proc" #30387
Problem: - "process" is often used as a verb (`multiqueue_process_events`), which is ambiguous for cases where it's used as a topic. - The documented naming convention for processes is "proc". - `:help dev-name-common` - Shorter is better, when it doesn't harm readability or discoverability. Solution: Rename "process" => "proc" in all C symbols and module names.
This commit is contained in:
parent
5792546777
commit
057d27a9d6
@ -10,7 +10,7 @@
|
|||||||
Memcheck:Leak
|
Memcheck:Leak
|
||||||
fun:malloc
|
fun:malloc
|
||||||
fun:uv_spawn
|
fun:uv_spawn
|
||||||
fun:libuv_process_spawn
|
fun:libuv_proc_spawn
|
||||||
fun:process_spawn
|
fun:proc_spawn
|
||||||
fun:job_start
|
fun:job_start
|
||||||
}
|
}
|
||||||
|
@ -848,7 +848,7 @@ def CheckIncludes(filename, lines, error):
|
|||||||
or filename.endswith('.in.h')
|
or filename.endswith('.in.h')
|
||||||
or FileInfo(filename).RelativePath() in {
|
or FileInfo(filename).RelativePath() in {
|
||||||
'func_attr.h',
|
'func_attr.h',
|
||||||
'os/pty_process.h',
|
'os/pty_proc.h',
|
||||||
}):
|
}):
|
||||||
return
|
return
|
||||||
|
|
||||||
@ -869,7 +869,7 @@ def CheckIncludes(filename, lines, error):
|
|||||||
"src/nvim/msgpack_rpc/unpacker.h",
|
"src/nvim/msgpack_rpc/unpacker.h",
|
||||||
"src/nvim/option.h",
|
"src/nvim/option.h",
|
||||||
"src/nvim/os/pty_conpty_win.h",
|
"src/nvim/os/pty_conpty_win.h",
|
||||||
"src/nvim/os/pty_process_win.h",
|
"src/nvim/os/pty_proc_win.h",
|
||||||
]
|
]
|
||||||
|
|
||||||
skip_headers = [
|
skip_headers = [
|
||||||
|
@ -417,10 +417,10 @@ list(SORT NVIM_HEADERS)
|
|||||||
|
|
||||||
foreach(sfile ${NVIM_SOURCES})
|
foreach(sfile ${NVIM_SOURCES})
|
||||||
get_filename_component(f ${sfile} NAME)
|
get_filename_component(f ${sfile} NAME)
|
||||||
if(WIN32 AND ${f} MATCHES "^(pty_process_unix.c)$")
|
if(WIN32 AND ${f} MATCHES "^(pty_proc_unix.c)$")
|
||||||
list(REMOVE_ITEM NVIM_SOURCES ${sfile})
|
list(REMOVE_ITEM NVIM_SOURCES ${sfile})
|
||||||
endif()
|
endif()
|
||||||
if(NOT WIN32 AND ${f} MATCHES "^(pty_process_win.c)$")
|
if(NOT WIN32 AND ${f} MATCHES "^(pty_proc_win.c)$")
|
||||||
list(REMOVE_ITEM NVIM_SOURCES ${sfile})
|
list(REMOVE_ITEM NVIM_SOURCES ${sfile})
|
||||||
endif()
|
endif()
|
||||||
if(NOT WIN32 AND ${f} MATCHES "^(pty_conpty_win.c)$")
|
if(NOT WIN32 AND ${f} MATCHES "^(pty_conpty_win.c)$")
|
||||||
@ -436,7 +436,7 @@ foreach(hfile ${NVIM_HEADERS})
|
|||||||
if(WIN32 AND ${f} MATCHES "^(unix_defs.h)$")
|
if(WIN32 AND ${f} MATCHES "^(unix_defs.h)$")
|
||||||
list(REMOVE_ITEM NVIM_HEADERS ${hfile})
|
list(REMOVE_ITEM NVIM_HEADERS ${hfile})
|
||||||
endif()
|
endif()
|
||||||
if(WIN32 AND ${f} MATCHES "^(pty_process_unix.h)$")
|
if(WIN32 AND ${f} MATCHES "^(pty_proc_unix.h)$")
|
||||||
list(REMOVE_ITEM NVIM_HEADERS ${hfile})
|
list(REMOVE_ITEM NVIM_HEADERS ${hfile})
|
||||||
endif()
|
endif()
|
||||||
if(NOT WIN32 AND ${f} MATCHES "^(win_defs.h)$")
|
if(NOT WIN32 AND ${f} MATCHES "^(win_defs.h)$")
|
||||||
@ -832,12 +832,12 @@ find_program(CLANG_TIDY_PRG clang-tidy)
|
|||||||
set(EXCLUDE_CLANG_TIDY typval_encode.c.h ui_events.in.h)
|
set(EXCLUDE_CLANG_TIDY typval_encode.c.h ui_events.in.h)
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
list(APPEND EXCLUDE_CLANG_TIDY
|
list(APPEND EXCLUDE_CLANG_TIDY
|
||||||
os/pty_process_unix.h
|
os/pty_proc_unix.h
|
||||||
os/unix_defs.h)
|
os/unix_defs.h)
|
||||||
else()
|
else()
|
||||||
list(APPEND EXCLUDE_CLANG_TIDY
|
list(APPEND EXCLUDE_CLANG_TIDY
|
||||||
os/win_defs.h
|
os/win_defs.h
|
||||||
os/pty_process_win.h
|
os/pty_proc_win.h
|
||||||
os/pty_conpty_win.h
|
os/pty_conpty_win.h
|
||||||
os/os_win_console.h)
|
os/os_win_console.h)
|
||||||
endif()
|
endif()
|
||||||
|
@ -70,7 +70,7 @@
|
|||||||
#include "nvim/optionstr.h"
|
#include "nvim/optionstr.h"
|
||||||
#include "nvim/os/input.h"
|
#include "nvim/os/input.h"
|
||||||
#include "nvim/os/os_defs.h"
|
#include "nvim/os/os_defs.h"
|
||||||
#include "nvim/os/process.h"
|
#include "nvim/os/proc.h"
|
||||||
#include "nvim/popupmenu.h"
|
#include "nvim/popupmenu.h"
|
||||||
#include "nvim/pos_defs.h"
|
#include "nvim/pos_defs.h"
|
||||||
#include "nvim/runtime.h"
|
#include "nvim/runtime.h"
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
#include "nvim/eval/typval.h"
|
#include "nvim/eval/typval.h"
|
||||||
#include "nvim/event/loop.h"
|
#include "nvim/event/loop.h"
|
||||||
#include "nvim/event/multiqueue.h"
|
#include "nvim/event/multiqueue.h"
|
||||||
#include "nvim/event/process.h"
|
#include "nvim/event/proc.h"
|
||||||
#include "nvim/event/rstream.h"
|
#include "nvim/event/rstream.h"
|
||||||
#include "nvim/event/socket.h"
|
#include "nvim/event/socket.h"
|
||||||
#include "nvim/event/stream.h"
|
#include "nvim/event/stream.h"
|
||||||
@ -88,7 +88,7 @@ void channel_free_all_mem(void)
|
|||||||
bool channel_close(uint64_t id, ChannelPart part, const char **error)
|
bool channel_close(uint64_t id, ChannelPart part, const char **error)
|
||||||
{
|
{
|
||||||
Channel *chan;
|
Channel *chan;
|
||||||
Process *proc;
|
Proc *proc;
|
||||||
|
|
||||||
const char *dummy;
|
const char *dummy;
|
||||||
if (!error) {
|
if (!error) {
|
||||||
@ -139,8 +139,8 @@ bool channel_close(uint64_t id, ChannelPart part, const char **error)
|
|||||||
if (part == kChannelPartStderr || part == kChannelPartAll) {
|
if (part == kChannelPartStderr || part == kChannelPartAll) {
|
||||||
rstream_may_close(&proc->err);
|
rstream_may_close(&proc->err);
|
||||||
}
|
}
|
||||||
if (proc->type == kProcessTypePty && part == kChannelPartAll) {
|
if (proc->type == kProcTypePty && part == kChannelPartAll) {
|
||||||
pty_process_close_master(&chan->stream.pty);
|
pty_proc_close_master(&chan->stream.pty);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -289,7 +289,7 @@ static void channel_destroy(Channel *chan)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (chan->streamtype == kChannelStreamProc) {
|
if (chan->streamtype == kChannelStreamProc) {
|
||||||
process_free(&chan->stream.proc);
|
proc_free(&chan->stream.proc);
|
||||||
}
|
}
|
||||||
|
|
||||||
callback_reader_free(&chan->on_data);
|
callback_reader_free(&chan->on_data);
|
||||||
@ -376,7 +376,7 @@ Channel *channel_job_start(char **argv, const char *exepath, CallbackReader on_s
|
|||||||
*status_out = 0;
|
*status_out = 0;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
chan->stream.pty = pty_process_init(&main_loop, chan);
|
chan->stream.pty = pty_proc_init(&main_loop, chan);
|
||||||
if (pty_width > 0) {
|
if (pty_width > 0) {
|
||||||
chan->stream.pty.width = pty_width;
|
chan->stream.pty.width = pty_width;
|
||||||
}
|
}
|
||||||
@ -384,22 +384,22 @@ Channel *channel_job_start(char **argv, const char *exepath, CallbackReader on_s
|
|||||||
chan->stream.pty.height = pty_height;
|
chan->stream.pty.height = pty_height;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
chan->stream.uv = libuv_process_init(&main_loop, chan);
|
chan->stream.uv = libuv_proc_init(&main_loop, chan);
|
||||||
}
|
}
|
||||||
|
|
||||||
Process *proc = &chan->stream.proc;
|
Proc *proc = &chan->stream.proc;
|
||||||
proc->argv = argv;
|
proc->argv = argv;
|
||||||
proc->exepath = exepath;
|
proc->exepath = exepath;
|
||||||
proc->cb = channel_process_exit_cb;
|
proc->cb = channel_proc_exit_cb;
|
||||||
proc->events = chan->events;
|
proc->events = chan->events;
|
||||||
proc->detach = detach;
|
proc->detach = detach;
|
||||||
proc->cwd = cwd;
|
proc->cwd = cwd;
|
||||||
proc->env = env;
|
proc->env = env;
|
||||||
proc->overlapped = overlapped;
|
proc->overlapped = overlapped;
|
||||||
|
|
||||||
char *cmd = xstrdup(process_get_exepath(proc));
|
char *cmd = xstrdup(proc_get_exepath(proc));
|
||||||
bool has_out, has_err;
|
bool has_out, has_err;
|
||||||
if (proc->type == kProcessTypePty) {
|
if (proc->type == kProcTypePty) {
|
||||||
has_out = true;
|
has_out = true;
|
||||||
has_err = false;
|
has_err = false;
|
||||||
} else {
|
} else {
|
||||||
@ -410,7 +410,7 @@ Channel *channel_job_start(char **argv, const char *exepath, CallbackReader on_s
|
|||||||
|
|
||||||
bool has_in = stdin_mode == kChannelStdinPipe;
|
bool has_in = stdin_mode == kChannelStdinPipe;
|
||||||
|
|
||||||
int status = process_spawn(proc, has_in, has_out, has_err);
|
int status = proc_spawn(proc, has_in, has_out, has_err);
|
||||||
if (status) {
|
if (status) {
|
||||||
semsg(_(e_jobspawn), os_strerror(status), cmd);
|
semsg(_(e_jobspawn), os_strerror(status), cmd);
|
||||||
xfree(cmd);
|
xfree(cmd);
|
||||||
@ -760,7 +760,7 @@ void channel_reader_callbacks(Channel *chan, CallbackReader *reader)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void channel_process_exit_cb(Process *proc, int status, void *data)
|
static void channel_proc_exit_cb(Proc *proc, int status, void *data)
|
||||||
{
|
{
|
||||||
Channel *chan = data;
|
Channel *chan = data;
|
||||||
if (chan->term) {
|
if (chan->term) {
|
||||||
@ -847,7 +847,7 @@ static void term_write(const char *buf, size_t size, void *data)
|
|||||||
static void term_resize(uint16_t width, uint16_t height, void *data)
|
static void term_resize(uint16_t width, uint16_t height, void *data)
|
||||||
{
|
{
|
||||||
Channel *chan = data;
|
Channel *chan = data;
|
||||||
pty_process_resize(&chan->stream.pty, width, height);
|
pty_proc_resize(&chan->stream.pty, width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void term_delayed_free(void **argv)
|
static inline void term_delayed_free(void **argv)
|
||||||
@ -867,7 +867,7 @@ static inline void term_delayed_free(void **argv)
|
|||||||
static void term_close(void *data)
|
static void term_close(void *data)
|
||||||
{
|
{
|
||||||
Channel *chan = data;
|
Channel *chan = data;
|
||||||
process_stop(&chan->stream.proc);
|
proc_stop(&chan->stream.proc);
|
||||||
multiqueue_put(chan->events, term_delayed_free, data);
|
multiqueue_put(chan->events, term_delayed_free, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -907,7 +907,7 @@ bool channel_job_running(uint64_t id)
|
|||||||
Channel *chan = find_channel(id);
|
Channel *chan = find_channel(id);
|
||||||
return (chan
|
return (chan
|
||||||
&& chan->streamtype == kChannelStreamProc
|
&& chan->streamtype == kChannelStreamProc
|
||||||
&& !process_is_stopped(&chan->stream.proc));
|
&& !proc_is_stopped(&chan->stream.proc));
|
||||||
}
|
}
|
||||||
|
|
||||||
Dictionary channel_info(uint64_t id, Arena *arena)
|
Dictionary channel_info(uint64_t id, Arena *arena)
|
||||||
@ -924,8 +924,8 @@ Dictionary channel_info(uint64_t id, Arena *arena)
|
|||||||
switch (chan->streamtype) {
|
switch (chan->streamtype) {
|
||||||
case kChannelStreamProc: {
|
case kChannelStreamProc: {
|
||||||
stream_desc = "job";
|
stream_desc = "job";
|
||||||
if (chan->stream.proc.type == kProcessTypePty) {
|
if (chan->stream.proc.type == kProcTypePty) {
|
||||||
const char *name = pty_process_tty_name(&chan->stream.pty);
|
const char *name = pty_proc_tty_name(&chan->stream.pty);
|
||||||
PUT_C(info, "pty", CSTR_TO_ARENA_OBJ(arena, name));
|
PUT_C(info, "pty", CSTR_TO_ARENA_OBJ(arena, name));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,11 +7,11 @@
|
|||||||
#include "nvim/channel_defs.h" // IWYU pragma: keep
|
#include "nvim/channel_defs.h" // IWYU pragma: keep
|
||||||
#include "nvim/eval/typval_defs.h"
|
#include "nvim/eval/typval_defs.h"
|
||||||
#include "nvim/event/defs.h"
|
#include "nvim/event/defs.h"
|
||||||
#include "nvim/event/libuv_process.h"
|
#include "nvim/event/libuv_proc.h"
|
||||||
#include "nvim/macros_defs.h"
|
#include "nvim/macros_defs.h"
|
||||||
#include "nvim/map_defs.h"
|
#include "nvim/map_defs.h"
|
||||||
#include "nvim/msgpack_rpc/channel_defs.h"
|
#include "nvim/msgpack_rpc/channel_defs.h"
|
||||||
#include "nvim/os/pty_process.h"
|
#include "nvim/os/pty_proc.h"
|
||||||
#include "nvim/types_defs.h"
|
#include "nvim/types_defs.h"
|
||||||
|
|
||||||
struct Channel {
|
struct Channel {
|
||||||
@ -21,9 +21,9 @@ struct Channel {
|
|||||||
|
|
||||||
ChannelStreamType streamtype;
|
ChannelStreamType streamtype;
|
||||||
union {
|
union {
|
||||||
Process proc;
|
Proc proc;
|
||||||
LibuvProcess uv;
|
LibuvProc uv;
|
||||||
PtyProcess pty;
|
PtyProc pty;
|
||||||
RStream socket;
|
RStream socket;
|
||||||
StdioPair stdio;
|
StdioPair stdio;
|
||||||
StderrState err;
|
StderrState err;
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
#include "nvim/eval/vars.h"
|
#include "nvim/eval/vars.h"
|
||||||
#include "nvim/event/loop.h"
|
#include "nvim/event/loop.h"
|
||||||
#include "nvim/event/multiqueue.h"
|
#include "nvim/event/multiqueue.h"
|
||||||
#include "nvim/event/process.h"
|
#include "nvim/event/proc.h"
|
||||||
#include "nvim/event/time.h"
|
#include "nvim/event/time.h"
|
||||||
#include "nvim/ex_cmds.h"
|
#include "nvim/ex_cmds.h"
|
||||||
#include "nvim/ex_docmd.h"
|
#include "nvim/ex_docmd.h"
|
||||||
@ -8506,7 +8506,7 @@ Channel *find_job(uint64_t id, bool show_error)
|
|||||||
{
|
{
|
||||||
Channel *data = find_channel(id);
|
Channel *data = find_channel(id);
|
||||||
if (!data || data->streamtype != kChannelStreamProc
|
if (!data || data->streamtype != kChannelStreamProc
|
||||||
|| process_is_stopped(&data->stream.proc)) {
|
|| proc_is_stopped(&data->stream.proc)) {
|
||||||
if (show_error) {
|
if (show_error) {
|
||||||
if (data && data->streamtype != kChannelStreamProc) {
|
if (data && data->streamtype != kChannelStreamProc) {
|
||||||
emsg(_(e_invchanjob));
|
emsg(_(e_invchanjob));
|
||||||
|
@ -49,7 +49,7 @@
|
|||||||
#include "nvim/event/defs.h"
|
#include "nvim/event/defs.h"
|
||||||
#include "nvim/event/loop.h"
|
#include "nvim/event/loop.h"
|
||||||
#include "nvim/event/multiqueue.h"
|
#include "nvim/event/multiqueue.h"
|
||||||
#include "nvim/event/process.h"
|
#include "nvim/event/proc.h"
|
||||||
#include "nvim/event/time.h"
|
#include "nvim/event/time.h"
|
||||||
#include "nvim/ex_cmds.h"
|
#include "nvim/ex_cmds.h"
|
||||||
#include "nvim/ex_cmds_defs.h"
|
#include "nvim/ex_cmds_defs.h"
|
||||||
@ -101,7 +101,7 @@
|
|||||||
#include "nvim/os/fs.h"
|
#include "nvim/os/fs.h"
|
||||||
#include "nvim/os/os.h"
|
#include "nvim/os/os.h"
|
||||||
#include "nvim/os/os_defs.h"
|
#include "nvim/os/os_defs.h"
|
||||||
#include "nvim/os/pty_process.h"
|
#include "nvim/os/pty_proc.h"
|
||||||
#include "nvim/os/shell.h"
|
#include "nvim/os/shell.h"
|
||||||
#include "nvim/os/stdpaths_defs.h"
|
#include "nvim/os/stdpaths_defs.h"
|
||||||
#include "nvim/os/time.h"
|
#include "nvim/os/time.h"
|
||||||
@ -3770,7 +3770,7 @@ static void f_jobpid(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Process *proc = &data->stream.proc;
|
Proc *proc = &data->stream.proc;
|
||||||
rettv->vval.v_number = proc->pid;
|
rettv->vval.v_number = proc->pid;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3796,13 +3796,13 @@ static void f_jobresize(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data->stream.proc.type != kProcessTypePty) {
|
if (data->stream.proc.type != kProcTypePty) {
|
||||||
emsg(_(e_channotpty));
|
emsg(_(e_channotpty));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
pty_process_resize(&data->stream.pty, (uint16_t)argvars[1].vval.v_number,
|
pty_proc_resize(&data->stream.pty, (uint16_t)argvars[1].vval.v_number,
|
||||||
(uint16_t)argvars[2].vval.v_number);
|
(uint16_t)argvars[2].vval.v_number);
|
||||||
rettv->vval.v_number = 1;
|
rettv->vval.v_number = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4077,7 +4077,7 @@ static void f_jobstop(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
|||||||
// Ignore return code, but show error later.
|
// Ignore return code, but show error later.
|
||||||
channel_close(data->id, kChannelPartRpc, &error);
|
channel_close(data->id, kChannelPartRpc, &error);
|
||||||
}
|
}
|
||||||
process_stop(&data->stream.proc);
|
proc_stop(&data->stream.proc);
|
||||||
rettv->vval.v_number = 1;
|
rettv->vval.v_number = 1;
|
||||||
if (error) {
|
if (error) {
|
||||||
emsg(error);
|
emsg(error);
|
||||||
@ -4113,10 +4113,10 @@ static void f_jobwait(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
|||||||
|| !(chan = find_channel((uint64_t)TV_LIST_ITEM_TV(arg)->vval.v_number))
|
|| !(chan = find_channel((uint64_t)TV_LIST_ITEM_TV(arg)->vval.v_number))
|
||||||
|| chan->streamtype != kChannelStreamProc) {
|
|| chan->streamtype != kChannelStreamProc) {
|
||||||
jobs[i] = NULL; // Invalid job.
|
jobs[i] = NULL; // Invalid job.
|
||||||
} else if (process_is_stopped(&chan->stream.proc)) {
|
} else if (proc_is_stopped(&chan->stream.proc)) {
|
||||||
// Job is stopped but not fully destroyed.
|
// Job is stopped but not fully destroyed.
|
||||||
// Ensure all callbacks on its event queue are executed. #15402
|
// Ensure all callbacks on its event queue are executed. #15402
|
||||||
process_wait(&chan->stream.proc, -1, NULL);
|
proc_wait(&chan->stream.proc, -1, NULL);
|
||||||
jobs[i] = NULL; // Invalid job.
|
jobs[i] = NULL; // Invalid job.
|
||||||
} else {
|
} else {
|
||||||
jobs[i] = chan;
|
jobs[i] = chan;
|
||||||
@ -4144,8 +4144,8 @@ static void f_jobwait(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
|||||||
if (jobs[i] == NULL) {
|
if (jobs[i] == NULL) {
|
||||||
continue; // Invalid job, will assign status=-3 below.
|
continue; // Invalid job, will assign status=-3 below.
|
||||||
}
|
}
|
||||||
int status = process_wait(&jobs[i]->stream.proc, remaining,
|
int status = proc_wait(&jobs[i]->stream.proc, remaining,
|
||||||
waiting_jobs);
|
waiting_jobs);
|
||||||
if (status < 0) {
|
if (status < 0) {
|
||||||
break; // Interrupted (CTRL-C) or timeout, skip remaining jobs.
|
break; // Interrupted (CTRL-C) or timeout, skip remaining jobs.
|
||||||
}
|
}
|
||||||
@ -8207,7 +8207,7 @@ static void f_termopen(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int pid = chan->stream.pty.process.pid;
|
int pid = chan->stream.pty.proc.pid;
|
||||||
|
|
||||||
// "./…" => "/home/foo/…"
|
// "./…" => "/home/foo/…"
|
||||||
vim_FullName(cwd, NameBuff, sizeof(NameBuff), false);
|
vim_FullName(cwd, NameBuff, sizeof(NameBuff), false);
|
||||||
|
@ -142,30 +142,31 @@ struct socket_watcher {
|
|||||||
};
|
};
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
kProcessTypeUv,
|
kProcTypeUv,
|
||||||
kProcessTypePty,
|
kProcTypePty,
|
||||||
} ProcessType;
|
} ProcType;
|
||||||
|
|
||||||
typedef struct process Process;
|
/// OS process
|
||||||
typedef void (*process_exit_cb)(Process *proc, int status, void *data);
|
typedef struct proc Proc;
|
||||||
typedef void (*internal_process_cb)(Process *proc);
|
typedef void (*proc_exit_cb)(Proc *proc, int status, void *data);
|
||||||
|
typedef void (*internal_proc_cb)(Proc *proc);
|
||||||
|
|
||||||
struct process {
|
struct proc {
|
||||||
ProcessType type;
|
ProcType type;
|
||||||
Loop *loop;
|
Loop *loop;
|
||||||
void *data;
|
void *data;
|
||||||
int pid, status, refcount;
|
int pid, status, refcount;
|
||||||
uint8_t exit_signal; // Signal used when killing (on Windows).
|
uint8_t exit_signal; // Signal used when killing (on Windows).
|
||||||
uint64_t stopped_time; // process_stop() timestamp
|
uint64_t stopped_time; // proc_stop() timestamp
|
||||||
const char *cwd;
|
const char *cwd;
|
||||||
char **argv;
|
char **argv;
|
||||||
const char *exepath;
|
const char *exepath;
|
||||||
dict_T *env;
|
dict_T *env;
|
||||||
Stream in;
|
Stream in;
|
||||||
RStream out, err;
|
RStream out, err;
|
||||||
/// Exit handler. If set, user must call process_free().
|
/// Exit handler. If set, user must call proc_free().
|
||||||
process_exit_cb cb;
|
proc_exit_cb cb;
|
||||||
internal_process_cb internal_exit_cb, internal_close_cb;
|
internal_proc_cb internal_exit_cb, internal_close_cb;
|
||||||
bool closed, detach, overlapped, fwd_err;
|
bool closed, detach, overlapped, fwd_err;
|
||||||
MultiQueue *events;
|
MultiQueue *events;
|
||||||
};
|
};
|
||||||
|
@ -5,9 +5,9 @@
|
|||||||
|
|
||||||
#include "nvim/eval/typval.h"
|
#include "nvim/eval/typval.h"
|
||||||
#include "nvim/event/defs.h"
|
#include "nvim/event/defs.h"
|
||||||
#include "nvim/event/libuv_process.h"
|
#include "nvim/event/libuv_proc.h"
|
||||||
#include "nvim/event/loop.h"
|
#include "nvim/event/loop.h"
|
||||||
#include "nvim/event/process.h"
|
#include "nvim/event/proc.h"
|
||||||
#include "nvim/log.h"
|
#include "nvim/log.h"
|
||||||
#include "nvim/os/os.h"
|
#include "nvim/os/os.h"
|
||||||
#include "nvim/os/os_defs.h"
|
#include "nvim/os/os_defs.h"
|
||||||
@ -15,15 +15,15 @@
|
|||||||
#include "nvim/ui_client.h"
|
#include "nvim/ui_client.h"
|
||||||
|
|
||||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||||
# include "event/libuv_process.c.generated.h"
|
# include "event/libuv_proc.c.generated.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/// @returns zero on success, or negative error code
|
/// @returns zero on success, or negative error code
|
||||||
int libuv_process_spawn(LibuvProcess *uvproc)
|
int libuv_proc_spawn(LibuvProc *uvproc)
|
||||||
FUNC_ATTR_NONNULL_ALL
|
FUNC_ATTR_NONNULL_ALL
|
||||||
{
|
{
|
||||||
Process *proc = (Process *)uvproc;
|
Proc *proc = (Proc *)uvproc;
|
||||||
uvproc->uvopts.file = process_get_exepath(proc);
|
uvproc->uvopts.file = proc_get_exepath(proc);
|
||||||
uvproc->uvopts.args = proc->argv;
|
uvproc->uvopts.args = proc->argv;
|
||||||
uvproc->uvopts.flags = UV_PROCESS_WINDOWS_HIDE;
|
uvproc->uvopts.flags = UV_PROCESS_WINDOWS_HIDE;
|
||||||
#ifdef MSWIN
|
#ifdef MSWIN
|
||||||
@ -101,7 +101,7 @@ int libuv_process_spawn(LibuvProcess *uvproc)
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
void libuv_process_close(LibuvProcess *uvproc)
|
void libuv_proc_close(LibuvProc *uvproc)
|
||||||
FUNC_ATTR_NONNULL_ARG(1)
|
FUNC_ATTR_NONNULL_ARG(1)
|
||||||
{
|
{
|
||||||
uv_close((uv_handle_t *)&uvproc->uv, close_cb);
|
uv_close((uv_handle_t *)&uvproc->uv, close_cb);
|
||||||
@ -109,11 +109,11 @@ void libuv_process_close(LibuvProcess *uvproc)
|
|||||||
|
|
||||||
static void close_cb(uv_handle_t *handle)
|
static void close_cb(uv_handle_t *handle)
|
||||||
{
|
{
|
||||||
Process *proc = handle->data;
|
Proc *proc = handle->data;
|
||||||
if (proc->internal_close_cb) {
|
if (proc->internal_close_cb) {
|
||||||
proc->internal_close_cb(proc);
|
proc->internal_close_cb(proc);
|
||||||
}
|
}
|
||||||
LibuvProcess *uvproc = (LibuvProcess *)proc;
|
LibuvProc *uvproc = (LibuvProc *)proc;
|
||||||
if (uvproc->uvopts.env) {
|
if (uvproc->uvopts.env) {
|
||||||
os_free_fullenv(uvproc->uvopts.env);
|
os_free_fullenv(uvproc->uvopts.env);
|
||||||
}
|
}
|
||||||
@ -121,7 +121,7 @@ static void close_cb(uv_handle_t *handle)
|
|||||||
|
|
||||||
static void exit_cb(uv_process_t *handle, int64_t status, int term_signal)
|
static void exit_cb(uv_process_t *handle, int64_t status, int term_signal)
|
||||||
{
|
{
|
||||||
Process *proc = handle->data;
|
Proc *proc = handle->data;
|
||||||
#if defined(MSWIN)
|
#if defined(MSWIN)
|
||||||
// Use stored/expected signal.
|
// Use stored/expected signal.
|
||||||
term_signal = proc->exit_signal;
|
term_signal = proc->exit_signal;
|
||||||
@ -130,10 +130,10 @@ static void exit_cb(uv_process_t *handle, int64_t status, int term_signal)
|
|||||||
proc->internal_exit_cb(proc);
|
proc->internal_exit_cb(proc);
|
||||||
}
|
}
|
||||||
|
|
||||||
LibuvProcess libuv_process_init(Loop *loop, void *data)
|
LibuvProc libuv_proc_init(Loop *loop, void *data)
|
||||||
{
|
{
|
||||||
LibuvProcess rv = {
|
LibuvProc rv = {
|
||||||
.process = process_init(loop, kProcessTypeUv, data)
|
.proc = proc_init(loop, kProcTypeUv, data)
|
||||||
};
|
};
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
@ -5,12 +5,12 @@
|
|||||||
#include "nvim/event/defs.h"
|
#include "nvim/event/defs.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
Process process;
|
Proc proc;
|
||||||
uv_process_t uv;
|
uv_process_t uv;
|
||||||
uv_process_options_t uvopts;
|
uv_process_options_t uvopts;
|
||||||
uv_stdio_container_t uvstdio[4];
|
uv_stdio_container_t uvstdio[4];
|
||||||
} LibuvProcess;
|
} LibuvProc;
|
||||||
|
|
||||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||||
# include "event/libuv_process.h.generated.h"
|
# include "event/libuv_proc.h.generated.h"
|
||||||
#endif
|
#endif
|
@ -4,24 +4,24 @@
|
|||||||
#include <uv.h>
|
#include <uv.h>
|
||||||
|
|
||||||
#include "klib/klist.h"
|
#include "klib/klist.h"
|
||||||
#include "nvim/event/libuv_process.h"
|
#include "nvim/event/libuv_proc.h"
|
||||||
#include "nvim/event/loop.h"
|
#include "nvim/event/loop.h"
|
||||||
#include "nvim/event/multiqueue.h"
|
#include "nvim/event/multiqueue.h"
|
||||||
#include "nvim/event/process.h"
|
#include "nvim/event/proc.h"
|
||||||
#include "nvim/event/rstream.h"
|
#include "nvim/event/rstream.h"
|
||||||
#include "nvim/event/stream.h"
|
#include "nvim/event/stream.h"
|
||||||
#include "nvim/event/wstream.h"
|
#include "nvim/event/wstream.h"
|
||||||
#include "nvim/globals.h"
|
#include "nvim/globals.h"
|
||||||
#include "nvim/log.h"
|
#include "nvim/log.h"
|
||||||
#include "nvim/main.h"
|
#include "nvim/main.h"
|
||||||
#include "nvim/os/process.h"
|
#include "nvim/os/proc.h"
|
||||||
#include "nvim/os/pty_process.h"
|
#include "nvim/os/pty_proc.h"
|
||||||
#include "nvim/os/shell.h"
|
#include "nvim/os/shell.h"
|
||||||
#include "nvim/os/time.h"
|
#include "nvim/os/time.h"
|
||||||
#include "nvim/ui_client.h"
|
#include "nvim/ui_client.h"
|
||||||
|
|
||||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||||
# include "event/process.c.generated.h"
|
# include "event/proc.c.generated.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Time for a process to exit cleanly before we send KILL.
|
// Time for a process to exit cleanly before we send KILL.
|
||||||
@ -33,13 +33,13 @@
|
|||||||
void __gcov_flush(void);
|
void __gcov_flush(void);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static bool process_is_tearing_down = false;
|
static bool proc_is_tearing_down = false;
|
||||||
|
|
||||||
// Delay exit until handles are closed, to avoid deadlocks
|
// Delay exit until handles are closed, to avoid deadlocks
|
||||||
static int exit_need_delay = 0;
|
static int exit_need_delay = 0;
|
||||||
|
|
||||||
/// @returns zero on success, or negative error code
|
/// @returns zero on success, or negative error code
|
||||||
int process_spawn(Process *proc, bool in, bool out, bool err)
|
int proc_spawn(Proc *proc, bool in, bool out, bool err)
|
||||||
FUNC_ATTR_NONNULL_ALL
|
FUNC_ATTR_NONNULL_ALL
|
||||||
{
|
{
|
||||||
// forwarding stderr contradicts with processing it internally
|
// forwarding stderr contradicts with processing it internally
|
||||||
@ -70,11 +70,11 @@ int process_spawn(Process *proc, bool in, bool out, bool err)
|
|||||||
|
|
||||||
int status;
|
int status;
|
||||||
switch (proc->type) {
|
switch (proc->type) {
|
||||||
case kProcessTypeUv:
|
case kProcTypeUv:
|
||||||
status = libuv_process_spawn((LibuvProcess *)proc);
|
status = libuv_proc_spawn((LibuvProc *)proc);
|
||||||
break;
|
break;
|
||||||
case kProcessTypePty:
|
case kProcTypePty:
|
||||||
status = pty_process_spawn((PtyProcess *)proc);
|
status = pty_proc_spawn((PtyProc *)proc);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -89,12 +89,12 @@ int process_spawn(Process *proc, bool in, bool out, bool err)
|
|||||||
uv_close((uv_handle_t *)&proc->err.s.uv.pipe, NULL);
|
uv_close((uv_handle_t *)&proc->err.s.uv.pipe, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (proc->type == kProcessTypeUv) {
|
if (proc->type == kProcTypeUv) {
|
||||||
uv_close((uv_handle_t *)&(((LibuvProcess *)proc)->uv), NULL);
|
uv_close((uv_handle_t *)&(((LibuvProc *)proc)->uv), NULL);
|
||||||
} else {
|
} else {
|
||||||
process_close(proc);
|
proc_close(proc);
|
||||||
}
|
}
|
||||||
process_free(proc);
|
proc_free(proc);
|
||||||
proc->status = -1;
|
proc->status = -1;
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
@ -102,52 +102,52 @@ int process_spawn(Process *proc, bool in, bool out, bool err)
|
|||||||
if (in) {
|
if (in) {
|
||||||
stream_init(NULL, &proc->in, -1, (uv_stream_t *)&proc->in.uv.pipe);
|
stream_init(NULL, &proc->in, -1, (uv_stream_t *)&proc->in.uv.pipe);
|
||||||
proc->in.internal_data = proc;
|
proc->in.internal_data = proc;
|
||||||
proc->in.internal_close_cb = on_process_stream_close;
|
proc->in.internal_close_cb = on_proc_stream_close;
|
||||||
proc->refcount++;
|
proc->refcount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (out) {
|
if (out) {
|
||||||
stream_init(NULL, &proc->out.s, -1, (uv_stream_t *)&proc->out.s.uv.pipe);
|
stream_init(NULL, &proc->out.s, -1, (uv_stream_t *)&proc->out.s.uv.pipe);
|
||||||
proc->out.s.internal_data = proc;
|
proc->out.s.internal_data = proc;
|
||||||
proc->out.s.internal_close_cb = on_process_stream_close;
|
proc->out.s.internal_close_cb = on_proc_stream_close;
|
||||||
proc->refcount++;
|
proc->refcount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (err) {
|
if (err) {
|
||||||
stream_init(NULL, &proc->err.s, -1, (uv_stream_t *)&proc->err.s.uv.pipe);
|
stream_init(NULL, &proc->err.s, -1, (uv_stream_t *)&proc->err.s.uv.pipe);
|
||||||
proc->err.s.internal_data = proc;
|
proc->err.s.internal_data = proc;
|
||||||
proc->err.s.internal_close_cb = on_process_stream_close;
|
proc->err.s.internal_close_cb = on_proc_stream_close;
|
||||||
proc->refcount++;
|
proc->refcount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
proc->internal_exit_cb = on_process_exit;
|
proc->internal_exit_cb = on_proc_exit;
|
||||||
proc->internal_close_cb = decref;
|
proc->internal_close_cb = decref;
|
||||||
proc->refcount++;
|
proc->refcount++;
|
||||||
kl_push(WatcherPtr, proc->loop->children, proc);
|
kl_push(WatcherPtr, proc->loop->children, proc);
|
||||||
DLOG("new: pid=%d exepath=[%s]", proc->pid, process_get_exepath(proc));
|
DLOG("new: pid=%d exepath=[%s]", proc->pid, proc_get_exepath(proc));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void process_teardown(Loop *loop) FUNC_ATTR_NONNULL_ALL
|
void proc_teardown(Loop *loop) FUNC_ATTR_NONNULL_ALL
|
||||||
{
|
{
|
||||||
process_is_tearing_down = true;
|
proc_is_tearing_down = true;
|
||||||
kl_iter(WatcherPtr, loop->children, current) {
|
kl_iter(WatcherPtr, loop->children, current) {
|
||||||
Process *proc = (*current)->data;
|
Proc *proc = (*current)->data;
|
||||||
if (proc->detach || proc->type == kProcessTypePty) {
|
if (proc->detach || proc->type == kProcTypePty) {
|
||||||
// Close handles to process without killing it.
|
// Close handles to process without killing it.
|
||||||
CREATE_EVENT(loop->events, process_close_handles, proc);
|
CREATE_EVENT(loop->events, proc_close_handles, proc);
|
||||||
} else {
|
} else {
|
||||||
process_stop(proc);
|
proc_stop(proc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait until all children exit and all close events are processed.
|
// Wait until all children exit and all close events are processed.
|
||||||
LOOP_PROCESS_EVENTS_UNTIL(loop, loop->events, -1,
|
LOOP_PROCESS_EVENTS_UNTIL(loop, loop->events, -1,
|
||||||
kl_empty(loop->children) && multiqueue_empty(loop->events));
|
kl_empty(loop->children) && multiqueue_empty(loop->events));
|
||||||
pty_process_teardown(loop);
|
pty_proc_teardown(loop);
|
||||||
}
|
}
|
||||||
|
|
||||||
void process_close_streams(Process *proc) FUNC_ATTR_NONNULL_ALL
|
void proc_close_streams(Proc *proc) FUNC_ATTR_NONNULL_ALL
|
||||||
{
|
{
|
||||||
wstream_may_close(&proc->in);
|
wstream_may_close(&proc->in);
|
||||||
rstream_may_close(&proc->out);
|
rstream_may_close(&proc->out);
|
||||||
@ -162,7 +162,7 @@ void process_close_streams(Process *proc) FUNC_ATTR_NONNULL_ALL
|
|||||||
/// @return Exit code of the process. proc->status will have the same value.
|
/// @return Exit code of the process. proc->status will have the same value.
|
||||||
/// -1 if the timeout expired while the process is still running.
|
/// -1 if the timeout expired while the process is still running.
|
||||||
/// -2 if the user interrupted the wait.
|
/// -2 if the user interrupted the wait.
|
||||||
int process_wait(Process *proc, int ms, MultiQueue *events)
|
int proc_wait(Proc *proc, int ms, MultiQueue *events)
|
||||||
FUNC_ATTR_NONNULL_ARG(1)
|
FUNC_ATTR_NONNULL_ARG(1)
|
||||||
{
|
{
|
||||||
if (!proc->refcount) {
|
if (!proc->refcount) {
|
||||||
@ -186,7 +186,7 @@ int process_wait(Process *proc, int ms, MultiQueue *events)
|
|||||||
// Assume that a user hitting CTRL-C does not like the current job. Kill it.
|
// Assume that a user hitting CTRL-C does not like the current job. Kill it.
|
||||||
if (got_int) {
|
if (got_int) {
|
||||||
got_int = false;
|
got_int = false;
|
||||||
process_stop(proc);
|
proc_stop(proc);
|
||||||
if (ms == -1) {
|
if (ms == -1) {
|
||||||
// We can only return if all streams/handles are closed and the job
|
// We can only return if all streams/handles are closed and the job
|
||||||
// exited.
|
// exited.
|
||||||
@ -214,7 +214,7 @@ int process_wait(Process *proc, int ms, MultiQueue *events)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Ask a process to terminate and eventually kill if it doesn't respond
|
/// Ask a process to terminate and eventually kill if it doesn't respond
|
||||||
void process_stop(Process *proc) FUNC_ATTR_NONNULL_ALL
|
void proc_stop(Proc *proc) FUNC_ATTR_NONNULL_ALL
|
||||||
{
|
{
|
||||||
bool exited = (proc->status >= 0);
|
bool exited = (proc->status >= 0);
|
||||||
if (exited || proc->stopped_time) {
|
if (exited || proc->stopped_time) {
|
||||||
@ -224,13 +224,13 @@ void process_stop(Process *proc) FUNC_ATTR_NONNULL_ALL
|
|||||||
proc->exit_signal = SIGTERM;
|
proc->exit_signal = SIGTERM;
|
||||||
|
|
||||||
switch (proc->type) {
|
switch (proc->type) {
|
||||||
case kProcessTypeUv:
|
case kProcTypeUv:
|
||||||
os_proc_tree_kill(proc->pid, SIGTERM);
|
os_proc_tree_kill(proc->pid, SIGTERM);
|
||||||
break;
|
break;
|
||||||
case kProcessTypePty:
|
case kProcTypePty:
|
||||||
// close all streams for pty processes to send SIGHUP to the process
|
// close all streams for pty processes to send SIGHUP to the process
|
||||||
process_close_streams(proc);
|
proc_close_streams(proc);
|
||||||
pty_process_close_master((PtyProcess *)proc);
|
pty_proc_close_master((PtyProc *)proc);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -240,7 +240,7 @@ void process_stop(Process *proc) FUNC_ATTR_NONNULL_ALL
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Frees process-owned resources.
|
/// Frees process-owned resources.
|
||||||
void process_free(Process *proc) FUNC_ATTR_NONNULL_ALL
|
void proc_free(Proc *proc) FUNC_ATTR_NONNULL_ALL
|
||||||
{
|
{
|
||||||
if (proc->argv != NULL) {
|
if (proc->argv != NULL) {
|
||||||
shell_free_argv(proc->argv);
|
shell_free_argv(proc->argv);
|
||||||
@ -249,19 +249,19 @@ void process_free(Process *proc) FUNC_ATTR_NONNULL_ALL
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Sends SIGKILL (or SIGTERM..SIGKILL for PTY jobs) to processes that did
|
/// Sends SIGKILL (or SIGTERM..SIGKILL for PTY jobs) to processes that did
|
||||||
/// not terminate after process_stop().
|
/// not terminate after proc_stop().
|
||||||
static void children_kill_cb(uv_timer_t *handle)
|
static void children_kill_cb(uv_timer_t *handle)
|
||||||
{
|
{
|
||||||
Loop *loop = handle->loop->data;
|
Loop *loop = handle->loop->data;
|
||||||
|
|
||||||
kl_iter(WatcherPtr, loop->children, current) {
|
kl_iter(WatcherPtr, loop->children, current) {
|
||||||
Process *proc = (*current)->data;
|
Proc *proc = (*current)->data;
|
||||||
bool exited = (proc->status >= 0);
|
bool exited = (proc->status >= 0);
|
||||||
if (exited || !proc->stopped_time) {
|
if (exited || !proc->stopped_time) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
uint64_t term_sent = UINT64_MAX == proc->stopped_time;
|
uint64_t term_sent = UINT64_MAX == proc->stopped_time;
|
||||||
if (kProcessTypePty != proc->type || term_sent) {
|
if (kProcTypePty != proc->type || term_sent) {
|
||||||
proc->exit_signal = SIGKILL;
|
proc->exit_signal = SIGKILL;
|
||||||
os_proc_tree_kill(proc->pid, SIGKILL);
|
os_proc_tree_kill(proc->pid, SIGKILL);
|
||||||
} else {
|
} else {
|
||||||
@ -275,19 +275,19 @@ static void children_kill_cb(uv_timer_t *handle)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void process_close_event(void **argv)
|
static void proc_close_event(void **argv)
|
||||||
{
|
{
|
||||||
Process *proc = argv[0];
|
Proc *proc = argv[0];
|
||||||
if (proc->cb) {
|
if (proc->cb) {
|
||||||
// User (hint: channel_job_start) is responsible for calling
|
// User (hint: channel_job_start) is responsible for calling
|
||||||
// process_free().
|
// proc_free().
|
||||||
proc->cb(proc, proc->status, proc->data);
|
proc->cb(proc, proc->status, proc->data);
|
||||||
} else {
|
} else {
|
||||||
process_free(proc);
|
proc_free(proc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void decref(Process *proc)
|
static void decref(Proc *proc)
|
||||||
{
|
{
|
||||||
if (--proc->refcount != 0) {
|
if (--proc->refcount != 0) {
|
||||||
return;
|
return;
|
||||||
@ -303,13 +303,13 @@ static void decref(Process *proc)
|
|||||||
}
|
}
|
||||||
assert(node);
|
assert(node);
|
||||||
kl_shift_at(WatcherPtr, loop->children, node);
|
kl_shift_at(WatcherPtr, loop->children, node);
|
||||||
CREATE_EVENT(proc->events, process_close_event, proc);
|
CREATE_EVENT(proc->events, proc_close_event, proc);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void process_close(Process *proc)
|
static void proc_close(Proc *proc)
|
||||||
FUNC_ATTR_NONNULL_ARG(1)
|
FUNC_ATTR_NONNULL_ARG(1)
|
||||||
{
|
{
|
||||||
if (process_is_tearing_down && (proc->detach || proc->type == kProcessTypePty)
|
if (proc_is_tearing_down && (proc->detach || proc->type == kProcTypePty)
|
||||||
&& proc->closed) {
|
&& proc->closed) {
|
||||||
// If a detached/pty process dies while tearing down it might get closed
|
// If a detached/pty process dies while tearing down it might get closed
|
||||||
// twice.
|
// twice.
|
||||||
@ -319,17 +319,17 @@ static void process_close(Process *proc)
|
|||||||
proc->closed = true;
|
proc->closed = true;
|
||||||
|
|
||||||
if (proc->detach) {
|
if (proc->detach) {
|
||||||
if (proc->type == kProcessTypeUv) {
|
if (proc->type == kProcTypeUv) {
|
||||||
uv_unref((uv_handle_t *)&(((LibuvProcess *)proc)->uv));
|
uv_unref((uv_handle_t *)&(((LibuvProc *)proc)->uv));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (proc->type) {
|
switch (proc->type) {
|
||||||
case kProcessTypeUv:
|
case kProcTypeUv:
|
||||||
libuv_process_close((LibuvProcess *)proc);
|
libuv_proc_close((LibuvProc *)proc);
|
||||||
break;
|
break;
|
||||||
case kProcessTypePty:
|
case kProcTypePty:
|
||||||
pty_process_close((PtyProcess *)proc);
|
pty_proc_close((PtyProc *)proc);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -338,7 +338,7 @@ static void process_close(Process *proc)
|
|||||||
///
|
///
|
||||||
/// @param proc Process, for which an output stream should be flushed.
|
/// @param proc Process, for which an output stream should be flushed.
|
||||||
/// @param stream Stream to flush.
|
/// @param stream Stream to flush.
|
||||||
static void flush_stream(Process *proc, RStream *stream)
|
static void flush_stream(Proc *proc, RStream *stream)
|
||||||
FUNC_ATTR_NONNULL_ARG(1)
|
FUNC_ATTR_NONNULL_ARG(1)
|
||||||
{
|
{
|
||||||
if (!stream || stream->s.closed) {
|
if (!stream || stream->s.closed) {
|
||||||
@ -382,16 +382,16 @@ static void flush_stream(Process *proc, RStream *stream)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void process_close_handles(void **argv)
|
static void proc_close_handles(void **argv)
|
||||||
{
|
{
|
||||||
Process *proc = argv[0];
|
Proc *proc = argv[0];
|
||||||
|
|
||||||
exit_need_delay++;
|
exit_need_delay++;
|
||||||
flush_stream(proc, &proc->out);
|
flush_stream(proc, &proc->out);
|
||||||
flush_stream(proc, &proc->err);
|
flush_stream(proc, &proc->err);
|
||||||
|
|
||||||
process_close_streams(proc);
|
proc_close_streams(proc);
|
||||||
process_close(proc);
|
proc_close(proc);
|
||||||
exit_need_delay--;
|
exit_need_delay--;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -426,7 +426,7 @@ void exit_from_channel(int status)
|
|||||||
multiqueue_put(main_loop.fast_events, exit_event, (void *)(intptr_t)status);
|
multiqueue_put(main_loop.fast_events, exit_event, (void *)(intptr_t)status);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void on_process_exit(Process *proc)
|
static void on_proc_exit(Proc *proc)
|
||||||
{
|
{
|
||||||
Loop *loop = proc->loop;
|
Loop *loop = proc->loop;
|
||||||
ILOG("exited: pid=%d status=%d stoptime=%" PRIu64, proc->pid, proc->status,
|
ILOG("exited: pid=%d status=%d stoptime=%" PRIu64, proc->pid, proc->status,
|
||||||
@ -439,13 +439,13 @@ static void on_process_exit(Process *proc)
|
|||||||
// Process has terminated, but there could still be data to be read from the
|
// Process has terminated, but there could still be data to be read from the
|
||||||
// OS. We are still in the libuv loop, so we cannot call code that polls for
|
// OS. We are still in the libuv loop, so we cannot call code that polls for
|
||||||
// more data directly. Instead delay the reading after the libuv loop by
|
// more data directly. Instead delay the reading after the libuv loop by
|
||||||
// queueing process_close_handles() as an event.
|
// queueing proc_close_handles() as an event.
|
||||||
MultiQueue *queue = proc->events ? proc->events : loop->events;
|
MultiQueue *queue = proc->events ? proc->events : loop->events;
|
||||||
CREATE_EVENT(queue, process_close_handles, proc);
|
CREATE_EVENT(queue, proc_close_handles, proc);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void on_process_stream_close(Stream *stream, void *data)
|
static void on_proc_stream_close(Stream *stream, void *data)
|
||||||
{
|
{
|
||||||
Process *proc = data;
|
Proc *proc = data;
|
||||||
decref(proc);
|
decref(proc);
|
||||||
}
|
}
|
@ -6,9 +6,9 @@
|
|||||||
#include "nvim/event/defs.h" // IWYU pragma: keep
|
#include "nvim/event/defs.h" // IWYU pragma: keep
|
||||||
#include "nvim/types_defs.h"
|
#include "nvim/types_defs.h"
|
||||||
|
|
||||||
static inline Process process_init(Loop *loop, ProcessType type, void *data)
|
static inline Proc proc_init(Loop *loop, ProcType type, void *data)
|
||||||
{
|
{
|
||||||
return (Process) {
|
return (Proc) {
|
||||||
.type = type,
|
.type = type,
|
||||||
.data = data,
|
.data = data,
|
||||||
.loop = loop,
|
.loop = loop,
|
||||||
@ -33,17 +33,17 @@ static inline Process process_init(Loop *loop, ProcessType type, void *data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Get the path to the executable of the process.
|
/// Get the path to the executable of the process.
|
||||||
static inline const char *process_get_exepath(Process *proc)
|
static inline const char *proc_get_exepath(Proc *proc)
|
||||||
{
|
{
|
||||||
return proc->exepath != NULL ? proc->exepath : proc->argv[0];
|
return proc->exepath != NULL ? proc->exepath : proc->argv[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool process_is_stopped(Process *proc)
|
static inline bool proc_is_stopped(Proc *proc)
|
||||||
{
|
{
|
||||||
bool exited = (proc->status >= 0);
|
bool exited = (proc->status >= 0);
|
||||||
return exited || (proc->stopped_time != 0);
|
return exited || (proc->stopped_time != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||||
# include "event/process.h.generated.h"
|
# include "event/proc.h.generated.h"
|
||||||
#endif
|
#endif
|
@ -43,7 +43,7 @@
|
|||||||
#include "nvim/eval/userfunc.h"
|
#include "nvim/eval/userfunc.h"
|
||||||
#include "nvim/event/loop.h"
|
#include "nvim/event/loop.h"
|
||||||
#include "nvim/event/multiqueue.h"
|
#include "nvim/event/multiqueue.h"
|
||||||
#include "nvim/event/process.h"
|
#include "nvim/event/proc.h"
|
||||||
#include "nvim/event/stream.h"
|
#include "nvim/event/stream.h"
|
||||||
#include "nvim/ex_cmds.h"
|
#include "nvim/ex_cmds.h"
|
||||||
#include "nvim/ex_docmd.h"
|
#include "nvim/ex_docmd.h"
|
||||||
@ -174,7 +174,7 @@ bool event_teardown(void)
|
|||||||
loop_poll_events(&main_loop, 0); // Drain thread_events, fast_events.
|
loop_poll_events(&main_loop, 0); // Drain thread_events, fast_events.
|
||||||
input_stop();
|
input_stop();
|
||||||
channel_teardown();
|
channel_teardown();
|
||||||
process_teardown(&main_loop);
|
proc_teardown(&main_loop);
|
||||||
timer_teardown();
|
timer_teardown();
|
||||||
server_teardown();
|
server_teardown();
|
||||||
signal_teardown();
|
signal_teardown();
|
||||||
@ -2207,7 +2207,7 @@ static void usage(void)
|
|||||||
printf(_(" --headless Don't start a user interface\n"));
|
printf(_(" --headless Don't start a user interface\n"));
|
||||||
printf(_(" --listen <address> Serve RPC API from this address\n"));
|
printf(_(" --listen <address> Serve RPC API from this address\n"));
|
||||||
printf(_(" --remote[-subcommand] Execute commands remotely on a server\n"));
|
printf(_(" --remote[-subcommand] Execute commands remotely on a server\n"));
|
||||||
printf(_(" --server <address> Specify RPC server to send commands to\n"));
|
printf(_(" --server <address> Connect to this Nvim server\n"));
|
||||||
printf(_(" --startuptime <file> Write startup timing messages to <file>\n"));
|
printf(_(" --startuptime <file> Write startup timing messages to <file>\n"));
|
||||||
printf(_("\nSee \":help startup-options\" for all options.\n"));
|
printf(_("\nSee \":help startup-options\" for all options.\n"));
|
||||||
}
|
}
|
||||||
|
@ -84,7 +84,7 @@
|
|||||||
#include "nvim/os/input.h"
|
#include "nvim/os/input.h"
|
||||||
#include "nvim/os/os.h"
|
#include "nvim/os/os.h"
|
||||||
#include "nvim/os/os_defs.h"
|
#include "nvim/os/os_defs.h"
|
||||||
#include "nvim/os/process.h"
|
#include "nvim/os/proc.h"
|
||||||
#include "nvim/os/time.h"
|
#include "nvim/os/time.h"
|
||||||
#include "nvim/os/time_defs.h"
|
#include "nvim/os/time_defs.h"
|
||||||
#include "nvim/path.h"
|
#include "nvim/path.h"
|
||||||
@ -743,7 +743,7 @@ static void add_b0_fenc(ZeroBlock *b0p, buf_T *buf)
|
|||||||
/// @param swap_fname Name of the swapfile. If it's from before a reboot, the result is 0.
|
/// @param swap_fname Name of the swapfile. If it's from before a reboot, the result is 0.
|
||||||
///
|
///
|
||||||
/// @return PID, or 0 if process is not running or the swapfile is from before a reboot.
|
/// @return PID, or 0 if process is not running or the swapfile is from before a reboot.
|
||||||
static int swapfile_process_running(const ZeroBlock *b0p, const char *swap_fname)
|
static int swapfile_proc_running(const ZeroBlock *b0p, const char *swap_fname)
|
||||||
{
|
{
|
||||||
FileInfo st;
|
FileInfo st;
|
||||||
double uptime;
|
double uptime;
|
||||||
@ -1214,7 +1214,7 @@ void ml_recover(bool checkext)
|
|||||||
msg(_("Recovery completed. Buffer contents equals file contents."), 0);
|
msg(_("Recovery completed. Buffer contents equals file contents."), 0);
|
||||||
}
|
}
|
||||||
msg_puts(_("\nYou may want to delete the .swp file now."));
|
msg_puts(_("\nYou may want to delete the .swp file now."));
|
||||||
if (swapfile_process_running(b0p, fname_used)) {
|
if (swapfile_proc_running(b0p, fname_used)) {
|
||||||
// Warn there could be an active Vim on the same file, the user may
|
// Warn there could be an active Vim on the same file, the user may
|
||||||
// want to kill it.
|
// want to kill it.
|
||||||
msg_puts(_("\nNote: process STILL RUNNING: "));
|
msg_puts(_("\nNote: process STILL RUNNING: "));
|
||||||
@ -1462,7 +1462,7 @@ char *make_percent_swname(char *dir, char *dir_end, const char *name)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// PID of swapfile owner, or zero if not running.
|
// PID of swapfile owner, or zero if not running.
|
||||||
static int process_running;
|
static int proc_running;
|
||||||
|
|
||||||
/// For Vimscript "swapinfo()".
|
/// For Vimscript "swapinfo()".
|
||||||
///
|
///
|
||||||
@ -1488,7 +1488,7 @@ void swapfile_dict(const char *fname, dict_T *d)
|
|||||||
tv_dict_add_str_len(d, S_LEN("fname"), b0.b0_fname,
|
tv_dict_add_str_len(d, S_LEN("fname"), b0.b0_fname,
|
||||||
B0_FNAME_SIZE_ORG);
|
B0_FNAME_SIZE_ORG);
|
||||||
|
|
||||||
tv_dict_add_nr(d, S_LEN("pid"), swapfile_process_running(&b0, fname));
|
tv_dict_add_nr(d, S_LEN("pid"), swapfile_proc_running(&b0, fname));
|
||||||
tv_dict_add_nr(d, S_LEN("mtime"), char_to_long(b0.b0_mtime));
|
tv_dict_add_nr(d, S_LEN("mtime"), char_to_long(b0.b0_mtime));
|
||||||
tv_dict_add_nr(d, S_LEN("dirty"), b0.b0_dirty ? 1 : 0);
|
tv_dict_add_nr(d, S_LEN("dirty"), b0.b0_dirty ? 1 : 0);
|
||||||
tv_dict_add_nr(d, S_LEN("inode"), char_to_long(b0.b0_ino));
|
tv_dict_add_nr(d, S_LEN("inode"), char_to_long(b0.b0_ino));
|
||||||
@ -1572,7 +1572,7 @@ static time_t swapfile_info(char *fname)
|
|||||||
if (char_to_long(b0.b0_pid) != 0) {
|
if (char_to_long(b0.b0_pid) != 0) {
|
||||||
msg_puts(_("\n process ID: "));
|
msg_puts(_("\n process ID: "));
|
||||||
msg_outnum((int)char_to_long(b0.b0_pid));
|
msg_outnum((int)char_to_long(b0.b0_pid));
|
||||||
if ((process_running = swapfile_process_running(&b0, fname))) {
|
if ((proc_running = swapfile_proc_running(&b0, fname))) {
|
||||||
msg_puts(_(" (STILL RUNNING)"));
|
msg_puts(_(" (STILL RUNNING)"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1640,7 +1640,7 @@ static bool swapfile_unchanged(char *fname)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// process must be known and not running.
|
// process must be known and not running.
|
||||||
if (char_to_long(b0.b0_pid) == 0 || swapfile_process_running(&b0, fname)) {
|
if (char_to_long(b0.b0_pid) == 0 || swapfile_proc_running(&b0, fname)) {
|
||||||
ret = false;
|
ret = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3399,7 +3399,7 @@ static char *findswapname(buf_T *buf, char **dirp, char *old_fname, bool *found_
|
|||||||
fd = os_open(fname, O_RDONLY, 0);
|
fd = os_open(fname, O_RDONLY, 0);
|
||||||
if (fd >= 0) {
|
if (fd >= 0) {
|
||||||
if (read_eintr(fd, &b0, sizeof(b0)) == sizeof(b0)) {
|
if (read_eintr(fd, &b0, sizeof(b0)) == sizeof(b0)) {
|
||||||
process_running = swapfile_process_running(&b0, fname);
|
proc_running = swapfile_proc_running(&b0, fname);
|
||||||
|
|
||||||
// If the swapfile has the same directory as the
|
// If the swapfile has the same directory as the
|
||||||
// buffer don't compare the directory names, they can
|
// buffer don't compare the directory names, they can
|
||||||
@ -3459,7 +3459,7 @@ static char *findswapname(buf_T *buf, char **dirp, char *old_fname, bool *found_
|
|||||||
choice = SEA_CHOICE_READONLY;
|
choice = SEA_CHOICE_READONLY;
|
||||||
}
|
}
|
||||||
|
|
||||||
process_running = 0; // Set by attention_message..swapfile_info.
|
proc_running = 0; // Set by attention_message..swapfile_info.
|
||||||
if (choice == SEA_CHOICE_NONE) {
|
if (choice == SEA_CHOICE_NONE) {
|
||||||
// Show info about the existing swapfile.
|
// Show info about the existing swapfile.
|
||||||
attention_message(buf, fname);
|
attention_message(buf, fname);
|
||||||
@ -3491,12 +3491,12 @@ static char *findswapname(buf_T *buf, char **dirp, char *old_fname, bool *found_
|
|||||||
= do_dialog(VIM_WARNING,
|
= do_dialog(VIM_WARNING,
|
||||||
_("VIM - ATTENTION"),
|
_("VIM - ATTENTION"),
|
||||||
name,
|
name,
|
||||||
process_running
|
proc_running
|
||||||
? _("&Open Read-Only\n&Edit anyway\n&Recover\n&Quit\n&Abort")
|
? _("&Open Read-Only\n&Edit anyway\n&Recover\n&Quit\n&Abort")
|
||||||
: _("&Open Read-Only\n&Edit anyway\n&Recover\n&Delete it\n&Quit\n&Abort"),
|
: _("&Open Read-Only\n&Edit anyway\n&Recover\n&Delete it\n&Quit\n&Abort"),
|
||||||
1, NULL, false);
|
1, NULL, false);
|
||||||
|
|
||||||
if (process_running && dialog_result >= 4) {
|
if (proc_running && dialog_result >= 4) {
|
||||||
// compensate for missing "Delete it" button
|
// compensate for missing "Delete it" button
|
||||||
dialog_result++;
|
dialog_result++;
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
#include "nvim/event/defs.h"
|
#include "nvim/event/defs.h"
|
||||||
#include "nvim/event/loop.h"
|
#include "nvim/event/loop.h"
|
||||||
#include "nvim/event/multiqueue.h"
|
#include "nvim/event/multiqueue.h"
|
||||||
#include "nvim/event/process.h"
|
#include "nvim/event/proc.h"
|
||||||
#include "nvim/event/rstream.h"
|
#include "nvim/event/rstream.h"
|
||||||
#include "nvim/event/wstream.h"
|
#include "nvim/event/wstream.h"
|
||||||
#include "nvim/globals.h"
|
#include "nvim/globals.h"
|
||||||
|
@ -344,7 +344,7 @@ char *os_getenvname_at_index(size_t index)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the process ID of the Neovim process.
|
/// Get the process ID of the Nvim process.
|
||||||
///
|
///
|
||||||
/// @return the process ID.
|
/// @return the process ID.
|
||||||
int64_t os_get_pid(void)
|
int64_t os_get_pid(void)
|
||||||
|
@ -37,24 +37,24 @@
|
|||||||
|
|
||||||
#include "nvim/log.h"
|
#include "nvim/log.h"
|
||||||
#include "nvim/memory.h"
|
#include "nvim/memory.h"
|
||||||
#include "nvim/os/process.h"
|
#include "nvim/os/proc.h"
|
||||||
|
|
||||||
#ifdef MSWIN
|
#ifdef MSWIN
|
||||||
# include "nvim/api/private/helpers.h"
|
# include "nvim/api/private/helpers.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||||
# include "os/process.c.generated.h"
|
# include "os/proc.c.generated.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef MSWIN
|
#ifdef MSWIN
|
||||||
static bool os_proc_tree_kill_rec(HANDLE process, int sig)
|
static bool os_proc_tree_kill_rec(HANDLE proc, int sig)
|
||||||
{
|
{
|
||||||
if (process == NULL) {
|
if (proc == NULL) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
PROCESSENTRY32 pe;
|
PROCESSENTRY32 pe;
|
||||||
DWORD pid = GetProcessId(process);
|
DWORD pid = GetProcessId(proc);
|
||||||
|
|
||||||
if (pid != 0) {
|
if (pid != 0) {
|
||||||
HANDLE h = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
|
HANDLE h = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
|
||||||
@ -77,7 +77,7 @@ static bool os_proc_tree_kill_rec(HANDLE process, int sig)
|
|||||||
}
|
}
|
||||||
|
|
||||||
theend:
|
theend:
|
||||||
return (bool)TerminateProcess(process, (unsigned)sig);
|
return (bool)TerminateProcess(proc, (unsigned)sig);
|
||||||
}
|
}
|
||||||
/// Kills process `pid` and its descendants recursively.
|
/// Kills process `pid` and its descendants recursively.
|
||||||
bool os_proc_tree_kill(int pid, int sig)
|
bool os_proc_tree_kill(int pid, int sig)
|
@ -7,5 +7,5 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||||
# include "os/process.h.generated.h"
|
# include "os/proc.h.generated.h"
|
||||||
#endif
|
#endif
|
@ -143,7 +143,7 @@ finished:
|
|||||||
return conpty_object;
|
return conpty_object;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool os_conpty_spawn(conpty_t *conpty_object, HANDLE *process_handle, wchar_t *name,
|
bool os_conpty_spawn(conpty_t *conpty_object, HANDLE *proc_handle, wchar_t *name,
|
||||||
wchar_t *cmd_line, wchar_t *cwd, wchar_t *env)
|
wchar_t *cmd_line, wchar_t *cwd, wchar_t *env)
|
||||||
{
|
{
|
||||||
PROCESS_INFORMATION pi = { 0 };
|
PROCESS_INFORMATION pi = { 0 };
|
||||||
@ -159,7 +159,7 @@ bool os_conpty_spawn(conpty_t *conpty_object, HANDLE *process_handle, wchar_t *n
|
|||||||
&pi)) {
|
&pi)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
*process_handle = pi.hProcess;
|
*proc_handle = pi.hProcess;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
7
src/nvim/os/pty_proc.h
Normal file
7
src/nvim/os/pty_proc.h
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifdef MSWIN
|
||||||
|
# include "nvim/os/pty_proc_win.h"
|
||||||
|
#else
|
||||||
|
# include "nvim/os/pty_proc_unix.h"
|
||||||
|
#endif
|
@ -34,16 +34,16 @@
|
|||||||
#include "nvim/eval/typval.h"
|
#include "nvim/eval/typval.h"
|
||||||
#include "nvim/event/defs.h"
|
#include "nvim/event/defs.h"
|
||||||
#include "nvim/event/loop.h"
|
#include "nvim/event/loop.h"
|
||||||
#include "nvim/event/process.h"
|
#include "nvim/event/proc.h"
|
||||||
#include "nvim/log.h"
|
#include "nvim/log.h"
|
||||||
#include "nvim/os/fs.h"
|
#include "nvim/os/fs.h"
|
||||||
#include "nvim/os/os_defs.h"
|
#include "nvim/os/os_defs.h"
|
||||||
#include "nvim/os/pty_process.h"
|
#include "nvim/os/pty_proc.h"
|
||||||
#include "nvim/os/pty_process_unix.h"
|
#include "nvim/os/pty_proc_unix.h"
|
||||||
#include "nvim/types_defs.h"
|
#include "nvim/types_defs.h"
|
||||||
|
|
||||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||||
# include "os/pty_process_unix.c.generated.h"
|
# include "os/pty_proc_unix.c.generated.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(__sun) && !defined(HAVE_FORKPTY)
|
#if defined(__sun) && !defined(HAVE_FORKPTY)
|
||||||
@ -158,7 +158,7 @@ static pid_t forkpty(int *amaster, char *name, struct termios *termp, struct win
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/// @returns zero on success, or negative error code
|
/// @returns zero on success, or negative error code
|
||||||
int pty_process_spawn(PtyProcess *ptyproc)
|
int pty_proc_spawn(PtyProc *ptyproc)
|
||||||
FUNC_ATTR_NONNULL_ALL
|
FUNC_ATTR_NONNULL_ALL
|
||||||
{
|
{
|
||||||
// termios initialized at first use
|
// termios initialized at first use
|
||||||
@ -168,7 +168,7 @@ int pty_process_spawn(PtyProcess *ptyproc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int status = 0; // zero or negative error code (libuv convention)
|
int status = 0; // zero or negative error code (libuv convention)
|
||||||
Process *proc = (Process *)ptyproc;
|
Proc *proc = (Proc *)ptyproc;
|
||||||
assert(proc->err.s.closed);
|
assert(proc->err.s.closed);
|
||||||
uv_signal_start(&proc->loop->children_watcher, chld_handler, SIGCHLD);
|
uv_signal_start(&proc->loop->children_watcher, chld_handler, SIGCHLD);
|
||||||
ptyproc->winsize = (struct winsize){ ptyproc->height, ptyproc->width, 0, 0 };
|
ptyproc->winsize = (struct winsize){ ptyproc->height, ptyproc->width, 0, 0 };
|
||||||
@ -224,29 +224,29 @@ error:
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *pty_process_tty_name(PtyProcess *ptyproc)
|
const char *pty_proc_tty_name(PtyProc *ptyproc)
|
||||||
{
|
{
|
||||||
return ptsname(ptyproc->tty_fd);
|
return ptsname(ptyproc->tty_fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pty_process_resize(PtyProcess *ptyproc, uint16_t width, uint16_t height)
|
void pty_proc_resize(PtyProc *ptyproc, uint16_t width, uint16_t height)
|
||||||
FUNC_ATTR_NONNULL_ALL
|
FUNC_ATTR_NONNULL_ALL
|
||||||
{
|
{
|
||||||
ptyproc->winsize = (struct winsize){ height, width, 0, 0 };
|
ptyproc->winsize = (struct winsize){ height, width, 0, 0 };
|
||||||
ioctl(ptyproc->tty_fd, TIOCSWINSZ, &ptyproc->winsize);
|
ioctl(ptyproc->tty_fd, TIOCSWINSZ, &ptyproc->winsize);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pty_process_close(PtyProcess *ptyproc)
|
void pty_proc_close(PtyProc *ptyproc)
|
||||||
FUNC_ATTR_NONNULL_ALL
|
FUNC_ATTR_NONNULL_ALL
|
||||||
{
|
{
|
||||||
pty_process_close_master(ptyproc);
|
pty_proc_close_master(ptyproc);
|
||||||
Process *proc = (Process *)ptyproc;
|
Proc *proc = (Proc *)ptyproc;
|
||||||
if (proc->internal_close_cb) {
|
if (proc->internal_close_cb) {
|
||||||
proc->internal_close_cb(proc);
|
proc->internal_close_cb(proc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void pty_process_close_master(PtyProcess *ptyproc) FUNC_ATTR_NONNULL_ALL
|
void pty_proc_close_master(PtyProc *ptyproc) FUNC_ATTR_NONNULL_ALL
|
||||||
{
|
{
|
||||||
if (ptyproc->tty_fd >= 0) {
|
if (ptyproc->tty_fd >= 0) {
|
||||||
close(ptyproc->tty_fd);
|
close(ptyproc->tty_fd);
|
||||||
@ -254,12 +254,12 @@ void pty_process_close_master(PtyProcess *ptyproc) FUNC_ATTR_NONNULL_ALL
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void pty_process_teardown(Loop *loop)
|
void pty_proc_teardown(Loop *loop)
|
||||||
{
|
{
|
||||||
uv_signal_stop(&loop->children_watcher);
|
uv_signal_stop(&loop->children_watcher);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void init_child(PtyProcess *ptyproc)
|
static void init_child(PtyProc *ptyproc)
|
||||||
FUNC_ATTR_NONNULL_ALL
|
FUNC_ATTR_NONNULL_ALL
|
||||||
{
|
{
|
||||||
#if defined(HAVE__NSGETENVIRON)
|
#if defined(HAVE__NSGETENVIRON)
|
||||||
@ -277,13 +277,13 @@ static void init_child(PtyProcess *ptyproc)
|
|||||||
signal(SIGTERM, SIG_DFL);
|
signal(SIGTERM, SIG_DFL);
|
||||||
signal(SIGALRM, SIG_DFL);
|
signal(SIGALRM, SIG_DFL);
|
||||||
|
|
||||||
Process *proc = (Process *)ptyproc;
|
Proc *proc = (Proc *)ptyproc;
|
||||||
if (proc->cwd && os_chdir(proc->cwd) != 0) {
|
if (proc->cwd && os_chdir(proc->cwd) != 0) {
|
||||||
ELOG("chdir(%s) failed: %s", proc->cwd, strerror(errno));
|
ELOG("chdir(%s) failed: %s", proc->cwd, strerror(errno));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *prog = process_get_exepath(proc);
|
const char *prog = proc_get_exepath(proc);
|
||||||
|
|
||||||
assert(proc->env);
|
assert(proc->env);
|
||||||
environ = tv_dict_to_env(proc->env);
|
environ = tv_dict_to_env(proc->env);
|
||||||
@ -388,7 +388,7 @@ static void chld_handler(uv_signal_t *handle, int signum)
|
|||||||
Loop *loop = handle->loop->data;
|
Loop *loop = handle->loop->data;
|
||||||
|
|
||||||
kl_iter(WatcherPtr, loop->children, current) {
|
kl_iter(WatcherPtr, loop->children, current) {
|
||||||
Process *proc = (*current)->data;
|
Proc *proc = (*current)->data;
|
||||||
do {
|
do {
|
||||||
pid = waitpid(proc->pid, &stat, WNOHANG);
|
pid = waitpid(proc->pid, &stat, WNOHANG);
|
||||||
} while (pid < 0 && errno == EINTR);
|
} while (pid < 0 && errno == EINTR);
|
||||||
@ -406,10 +406,10 @@ static void chld_handler(uv_signal_t *handle, int signum)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PtyProcess pty_process_init(Loop *loop, void *data)
|
PtyProc pty_proc_init(Loop *loop, void *data)
|
||||||
{
|
{
|
||||||
PtyProcess rv;
|
PtyProc rv;
|
||||||
rv.process = process_init(loop, kProcessTypePty, data);
|
rv.proc = proc_init(loop, kProcTypePty, data);
|
||||||
rv.width = 80;
|
rv.width = 80;
|
||||||
rv.height = 24;
|
rv.height = 24;
|
||||||
rv.tty_fd = -1;
|
rv.tty_fd = -1;
|
@ -1,5 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
// IWYU pragma: private, include "nvim/os/pty_process.h"
|
// IWYU pragma: private, include "nvim/os/pty_proc.h"
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
@ -7,12 +7,12 @@
|
|||||||
#include "nvim/event/defs.h"
|
#include "nvim/event/defs.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
Process process;
|
Proc proc;
|
||||||
uint16_t width, height;
|
uint16_t width, height;
|
||||||
struct winsize winsize;
|
struct winsize winsize;
|
||||||
int tty_fd;
|
int tty_fd;
|
||||||
} PtyProcess;
|
} PtyProc;
|
||||||
|
|
||||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||||
# include "os/pty_process_unix.h.generated.h"
|
# include "os/pty_proc_unix.h.generated.h"
|
||||||
#endif
|
#endif
|
@ -10,20 +10,20 @@
|
|||||||
#include "nvim/memory.h"
|
#include "nvim/memory.h"
|
||||||
#include "nvim/os/os.h"
|
#include "nvim/os/os.h"
|
||||||
#include "nvim/os/pty_conpty_win.h"
|
#include "nvim/os/pty_conpty_win.h"
|
||||||
#include "nvim/os/pty_process_win.h"
|
#include "nvim/os/pty_proc_win.h"
|
||||||
|
|
||||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||||
# include "os/pty_process_win.c.generated.h"
|
# include "os/pty_proc_win.c.generated.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void CALLBACK pty_process_finish1(void *context, BOOLEAN unused)
|
static void CALLBACK pty_proc_finish1(void *context, BOOLEAN unused)
|
||||||
FUNC_ATTR_NONNULL_ALL
|
FUNC_ATTR_NONNULL_ALL
|
||||||
{
|
{
|
||||||
PtyProcess *ptyproc = (PtyProcess *)context;
|
PtyProc *ptyproc = (PtyProc *)context;
|
||||||
Process *proc = (Process *)ptyproc;
|
Proc *proc = (Proc *)ptyproc;
|
||||||
|
|
||||||
os_conpty_free(ptyproc->conpty);
|
os_conpty_free(ptyproc->conpty);
|
||||||
// NB: pty_process_finish1() is called on a separate thread,
|
// NB: pty_proc_finish1() is called on a separate thread,
|
||||||
// but the timer only works properly if it's started by the main thread.
|
// but the timer only works properly if it's started by the main thread.
|
||||||
loop_schedule_fast(proc->loop, event_create(start_wait_eof_timer, ptyproc));
|
loop_schedule_fast(proc->loop, event_create(start_wait_eof_timer, ptyproc));
|
||||||
}
|
}
|
||||||
@ -31,7 +31,7 @@ static void CALLBACK pty_process_finish1(void *context, BOOLEAN unused)
|
|||||||
static void start_wait_eof_timer(void **argv)
|
static void start_wait_eof_timer(void **argv)
|
||||||
FUNC_ATTR_NONNULL_ALL
|
FUNC_ATTR_NONNULL_ALL
|
||||||
{
|
{
|
||||||
PtyProcess *ptyproc = (PtyProcess *)argv[0];
|
PtyProc *ptyproc = (PtyProc *)argv[0];
|
||||||
|
|
||||||
if (ptyproc->finish_wait != NULL) {
|
if (ptyproc->finish_wait != NULL) {
|
||||||
uv_timer_start(&ptyproc->wait_eof_timer, wait_eof_timer_cb, 200, 200);
|
uv_timer_start(&ptyproc->wait_eof_timer, wait_eof_timer_cb, 200, 200);
|
||||||
@ -39,15 +39,15 @@ static void start_wait_eof_timer(void **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// @returns zero on success, or negative error code.
|
/// @returns zero on success, or negative error code.
|
||||||
int pty_process_spawn(PtyProcess *ptyproc)
|
int pty_proc_spawn(PtyProc *ptyproc)
|
||||||
FUNC_ATTR_NONNULL_ALL
|
FUNC_ATTR_NONNULL_ALL
|
||||||
{
|
{
|
||||||
Process *proc = (Process *)ptyproc;
|
Proc *proc = (Proc *)ptyproc;
|
||||||
int status = 0;
|
int status = 0;
|
||||||
conpty_t *conpty_object = NULL;
|
conpty_t *conpty_object = NULL;
|
||||||
char *in_name = NULL;
|
char *in_name = NULL;
|
||||||
char *out_name = NULL;
|
char *out_name = NULL;
|
||||||
HANDLE process_handle = NULL;
|
HANDLE proc_handle = NULL;
|
||||||
uv_connect_t *in_req = NULL;
|
uv_connect_t *in_req = NULL;
|
||||||
uv_connect_t *out_req = NULL;
|
uv_connect_t *out_req = NULL;
|
||||||
wchar_t *cmd_line = NULL;
|
wchar_t *cmd_line = NULL;
|
||||||
@ -69,7 +69,7 @@ int pty_process_spawn(PtyProcess *ptyproc)
|
|||||||
uv_pipe_connect(in_req,
|
uv_pipe_connect(in_req,
|
||||||
&proc->in.uv.pipe,
|
&proc->in.uv.pipe,
|
||||||
in_name,
|
in_name,
|
||||||
pty_process_connect_cb);
|
pty_proc_connect_cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!proc->out.s.closed) {
|
if (!proc->out.s.closed) {
|
||||||
@ -77,7 +77,7 @@ int pty_process_spawn(PtyProcess *ptyproc)
|
|||||||
uv_pipe_connect(out_req,
|
uv_pipe_connect(out_req,
|
||||||
&proc->out.s.uv.pipe,
|
&proc->out.s.uv.pipe,
|
||||||
out_name,
|
out_name,
|
||||||
pty_process_connect_cb);
|
pty_proc_connect_cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (proc->cwd != NULL) {
|
if (proc->cwd != NULL) {
|
||||||
@ -105,7 +105,7 @@ int pty_process_spawn(PtyProcess *ptyproc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!os_conpty_spawn(conpty_object,
|
if (!os_conpty_spawn(conpty_object,
|
||||||
&process_handle,
|
&proc_handle,
|
||||||
NULL,
|
NULL,
|
||||||
cmd_line,
|
cmd_line,
|
||||||
cwd,
|
cwd,
|
||||||
@ -114,42 +114,42 @@ int pty_process_spawn(PtyProcess *ptyproc)
|
|||||||
status = (int)GetLastError();
|
status = (int)GetLastError();
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
proc->pid = (int)GetProcessId(process_handle);
|
proc->pid = (int)GetProcessId(proc_handle);
|
||||||
|
|
||||||
uv_timer_init(&proc->loop->uv, &ptyproc->wait_eof_timer);
|
uv_timer_init(&proc->loop->uv, &ptyproc->wait_eof_timer);
|
||||||
ptyproc->wait_eof_timer.data = (void *)ptyproc;
|
ptyproc->wait_eof_timer.data = (void *)ptyproc;
|
||||||
if (!RegisterWaitForSingleObject(&ptyproc->finish_wait,
|
if (!RegisterWaitForSingleObject(&ptyproc->finish_wait,
|
||||||
process_handle,
|
proc_handle,
|
||||||
pty_process_finish1,
|
pty_proc_finish1,
|
||||||
ptyproc,
|
ptyproc,
|
||||||
INFINITE,
|
INFINITE,
|
||||||
WT_EXECUTEDEFAULT | WT_EXECUTEONLYONCE)) {
|
WT_EXECUTEDEFAULT | WT_EXECUTEONLYONCE)) {
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait until pty_process_connect_cb is called.
|
// Wait until pty_proc_connect_cb is called.
|
||||||
while ((in_req != NULL && in_req->handle != NULL)
|
while ((in_req != NULL && in_req->handle != NULL)
|
||||||
|| (out_req != NULL && out_req->handle != NULL)) {
|
|| (out_req != NULL && out_req->handle != NULL)) {
|
||||||
uv_run(&proc->loop->uv, UV_RUN_ONCE);
|
uv_run(&proc->loop->uv, UV_RUN_ONCE);
|
||||||
}
|
}
|
||||||
|
|
||||||
ptyproc->conpty = conpty_object;
|
ptyproc->conpty = conpty_object;
|
||||||
ptyproc->process_handle = process_handle;
|
ptyproc->proc_handle = proc_handle;
|
||||||
conpty_object = NULL;
|
conpty_object = NULL;
|
||||||
process_handle = NULL;
|
proc_handle = NULL;
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
if (status) {
|
if (status) {
|
||||||
// In the case of an error of MultiByteToWideChar or CreateProcessW.
|
// In the case of an error of MultiByteToWideChar or CreateProcessW.
|
||||||
ELOG("pty_process_spawn(%s): %s: error code: %d",
|
ELOG("pty_proc_spawn(%s): %s: error code: %d",
|
||||||
proc->argv[0], emsg, status);
|
proc->argv[0], emsg, status);
|
||||||
status = os_translate_sys_error(status);
|
status = os_translate_sys_error(status);
|
||||||
}
|
}
|
||||||
os_conpty_free(conpty_object);
|
os_conpty_free(conpty_object);
|
||||||
xfree(in_name);
|
xfree(in_name);
|
||||||
xfree(out_name);
|
xfree(out_name);
|
||||||
if (process_handle != NULL) {
|
if (proc_handle != NULL) {
|
||||||
CloseHandle(process_handle);
|
CloseHandle(proc_handle);
|
||||||
}
|
}
|
||||||
xfree(in_req);
|
xfree(in_req);
|
||||||
xfree(out_req);
|
xfree(out_req);
|
||||||
@ -159,32 +159,32 @@ cleanup:
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *pty_process_tty_name(PtyProcess *ptyproc)
|
const char *pty_proc_tty_name(PtyProc *ptyproc)
|
||||||
{
|
{
|
||||||
return "?";
|
return "?";
|
||||||
}
|
}
|
||||||
|
|
||||||
void pty_process_resize(PtyProcess *ptyproc, uint16_t width, uint16_t height)
|
void pty_proc_resize(PtyProc *ptyproc, uint16_t width, uint16_t height)
|
||||||
FUNC_ATTR_NONNULL_ALL
|
FUNC_ATTR_NONNULL_ALL
|
||||||
{
|
{
|
||||||
os_conpty_set_size(ptyproc->conpty, width, height);
|
os_conpty_set_size(ptyproc->conpty, width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pty_process_close(PtyProcess *ptyproc)
|
void pty_proc_close(PtyProc *ptyproc)
|
||||||
FUNC_ATTR_NONNULL_ALL
|
FUNC_ATTR_NONNULL_ALL
|
||||||
{
|
{
|
||||||
Process *proc = (Process *)ptyproc;
|
Proc *proc = (Proc *)ptyproc;
|
||||||
|
|
||||||
pty_process_close_master(ptyproc);
|
pty_proc_close_master(ptyproc);
|
||||||
|
|
||||||
if (ptyproc->finish_wait != NULL) {
|
if (ptyproc->finish_wait != NULL) {
|
||||||
UnregisterWaitEx(ptyproc->finish_wait, NULL);
|
UnregisterWaitEx(ptyproc->finish_wait, NULL);
|
||||||
ptyproc->finish_wait = NULL;
|
ptyproc->finish_wait = NULL;
|
||||||
uv_close((uv_handle_t *)&ptyproc->wait_eof_timer, NULL);
|
uv_close((uv_handle_t *)&ptyproc->wait_eof_timer, NULL);
|
||||||
}
|
}
|
||||||
if (ptyproc->process_handle != NULL) {
|
if (ptyproc->proc_handle != NULL) {
|
||||||
CloseHandle(ptyproc->process_handle);
|
CloseHandle(ptyproc->proc_handle);
|
||||||
ptyproc->process_handle = NULL;
|
ptyproc->proc_handle = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (proc->internal_close_cb) {
|
if (proc->internal_close_cb) {
|
||||||
@ -192,17 +192,17 @@ void pty_process_close(PtyProcess *ptyproc)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void pty_process_close_master(PtyProcess *ptyproc)
|
void pty_proc_close_master(PtyProc *ptyproc)
|
||||||
FUNC_ATTR_NONNULL_ALL
|
FUNC_ATTR_NONNULL_ALL
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void pty_process_teardown(Loop *loop)
|
void pty_proc_teardown(Loop *loop)
|
||||||
FUNC_ATTR_NONNULL_ALL
|
FUNC_ATTR_NONNULL_ALL
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pty_process_connect_cb(uv_connect_t *req, int status)
|
static void pty_proc_connect_cb(uv_connect_t *req, int status)
|
||||||
FUNC_ATTR_NONNULL_ALL
|
FUNC_ATTR_NONNULL_ALL
|
||||||
{
|
{
|
||||||
assert(status == 0);
|
assert(status == 0);
|
||||||
@ -212,23 +212,23 @@ static void pty_process_connect_cb(uv_connect_t *req, int status)
|
|||||||
static void wait_eof_timer_cb(uv_timer_t *wait_eof_timer)
|
static void wait_eof_timer_cb(uv_timer_t *wait_eof_timer)
|
||||||
FUNC_ATTR_NONNULL_ALL
|
FUNC_ATTR_NONNULL_ALL
|
||||||
{
|
{
|
||||||
PtyProcess *ptyproc = wait_eof_timer->data;
|
PtyProc *ptyproc = wait_eof_timer->data;
|
||||||
Process *proc = (Process *)ptyproc;
|
Proc *proc = (Proc *)ptyproc;
|
||||||
|
|
||||||
assert(ptyproc->finish_wait != NULL);
|
assert(ptyproc->finish_wait != NULL);
|
||||||
if (proc->out.s.closed || proc->out.did_eof || !uv_is_readable(proc->out.s.uvstream)) {
|
if (proc->out.s.closed || proc->out.did_eof || !uv_is_readable(proc->out.s.uvstream)) {
|
||||||
uv_timer_stop(&ptyproc->wait_eof_timer);
|
uv_timer_stop(&ptyproc->wait_eof_timer);
|
||||||
pty_process_finish2(ptyproc);
|
pty_proc_finish2(ptyproc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pty_process_finish2(PtyProcess *ptyproc)
|
static void pty_proc_finish2(PtyProc *ptyproc)
|
||||||
FUNC_ATTR_NONNULL_ALL
|
FUNC_ATTR_NONNULL_ALL
|
||||||
{
|
{
|
||||||
Process *proc = (Process *)ptyproc;
|
Proc *proc = (Proc *)ptyproc;
|
||||||
|
|
||||||
DWORD exit_code = 0;
|
DWORD exit_code = 0;
|
||||||
GetExitCodeProcess(ptyproc->process_handle, &exit_code);
|
GetExitCodeProcess(ptyproc->proc_handle, &exit_code);
|
||||||
proc->status = proc->exit_signal ? 128 + proc->exit_signal : (int)exit_code;
|
proc->status = proc->exit_signal ? 128 + proc->exit_signal : (int)exit_code;
|
||||||
|
|
||||||
proc->internal_exit_cb(proc);
|
proc->internal_exit_cb(proc);
|
||||||
@ -427,14 +427,14 @@ cleanup:
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
PtyProcess pty_process_init(Loop *loop, void *data)
|
PtyProc pty_proc_init(Loop *loop, void *data)
|
||||||
{
|
{
|
||||||
PtyProcess rv;
|
PtyProc rv;
|
||||||
rv.process = process_init(loop, kProcessTypePty, data);
|
rv.proc = proc_init(loop, kProcTypePty, data);
|
||||||
rv.width = 80;
|
rv.width = 80;
|
||||||
rv.height = 24;
|
rv.height = 24;
|
||||||
rv.conpty = NULL;
|
rv.conpty = NULL;
|
||||||
rv.finish_wait = NULL;
|
rv.finish_wait = NULL;
|
||||||
rv.process_handle = NULL;
|
rv.proc_handle = NULL;
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
@ -1,20 +1,20 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
// IWYU pragma: private, include "nvim/os/pty_process.h"
|
// IWYU pragma: private, include "nvim/os/pty_proc.h"
|
||||||
|
|
||||||
#include <uv.h>
|
#include <uv.h>
|
||||||
|
|
||||||
#include "nvim/event/process.h"
|
#include "nvim/event/proc.h"
|
||||||
#include "nvim/lib/queue_defs.h"
|
#include "nvim/lib/queue_defs.h"
|
||||||
#include "nvim/os/pty_conpty_win.h"
|
#include "nvim/os/pty_conpty_win.h"
|
||||||
|
|
||||||
typedef struct pty_process {
|
typedef struct pty_process {
|
||||||
Process process;
|
Proc proc;
|
||||||
uint16_t width, height;
|
uint16_t width, height;
|
||||||
conpty_t *conpty;
|
conpty_t *conpty;
|
||||||
HANDLE finish_wait;
|
HANDLE finish_wait;
|
||||||
HANDLE process_handle;
|
HANDLE proc_handle;
|
||||||
uv_timer_t wait_eof_timer;
|
uv_timer_t wait_eof_timer;
|
||||||
} PtyProcess;
|
} PtyProc;
|
||||||
|
|
||||||
// Structure used by build_cmd_line()
|
// Structure used by build_cmd_line()
|
||||||
typedef struct arg_node {
|
typedef struct arg_node {
|
||||||
@ -23,5 +23,5 @@ typedef struct arg_node {
|
|||||||
} ArgNode;
|
} ArgNode;
|
||||||
|
|
||||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||||
# include "os/pty_process_win.h.generated.h"
|
# include "os/pty_proc_win.h.generated.h"
|
||||||
#endif
|
#endif
|
@ -1,7 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#ifdef MSWIN
|
|
||||||
# include "nvim/os/pty_process_win.h"
|
|
||||||
#else
|
|
||||||
# include "nvim/os/pty_process_unix.h"
|
|
||||||
#endif
|
|
@ -14,10 +14,10 @@
|
|||||||
#include "nvim/eval.h"
|
#include "nvim/eval.h"
|
||||||
#include "nvim/eval/typval_defs.h"
|
#include "nvim/eval/typval_defs.h"
|
||||||
#include "nvim/event/defs.h"
|
#include "nvim/event/defs.h"
|
||||||
#include "nvim/event/libuv_process.h"
|
#include "nvim/event/libuv_proc.h"
|
||||||
#include "nvim/event/loop.h"
|
#include "nvim/event/loop.h"
|
||||||
#include "nvim/event/multiqueue.h"
|
#include "nvim/event/multiqueue.h"
|
||||||
#include "nvim/event/process.h"
|
#include "nvim/event/proc.h"
|
||||||
#include "nvim/event/rstream.h"
|
#include "nvim/event/rstream.h"
|
||||||
#include "nvim/event/stream.h"
|
#include "nvim/event/stream.h"
|
||||||
#include "nvim/event/wstream.h"
|
#include "nvim/event/wstream.h"
|
||||||
@ -872,12 +872,12 @@ static int do_os_system(char **argv, const char *input, size_t len, char **outpu
|
|||||||
char prog[MAXPATHL];
|
char prog[MAXPATHL];
|
||||||
xstrlcpy(prog, argv[0], MAXPATHL);
|
xstrlcpy(prog, argv[0], MAXPATHL);
|
||||||
|
|
||||||
LibuvProcess uvproc = libuv_process_init(&main_loop, &buf);
|
LibuvProc uvproc = libuv_proc_init(&main_loop, &buf);
|
||||||
Process *proc = &uvproc.process;
|
Proc *proc = &uvproc.proc;
|
||||||
MultiQueue *events = multiqueue_new_child(main_loop.events);
|
MultiQueue *events = multiqueue_new_child(main_loop.events);
|
||||||
proc->events = events;
|
proc->events = events;
|
||||||
proc->argv = argv;
|
proc->argv = argv;
|
||||||
int status = process_spawn(proc, has_input, true, true);
|
int status = proc_spawn(proc, has_input, true, true);
|
||||||
if (status) {
|
if (status) {
|
||||||
loop_poll_events(&main_loop, 0);
|
loop_poll_events(&main_loop, 0);
|
||||||
// Failed, probably 'shell' is not executable.
|
// Failed, probably 'shell' is not executable.
|
||||||
@ -910,7 +910,7 @@ static int do_os_system(char **argv, const char *input, size_t len, char **outpu
|
|||||||
|
|
||||||
if (!wstream_write(&proc->in, input_buffer)) {
|
if (!wstream_write(&proc->in, input_buffer)) {
|
||||||
// couldn't write, stop the process and tell the user about it
|
// couldn't write, stop the process and tell the user about it
|
||||||
process_stop(proc);
|
proc_stop(proc);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
// close the input stream after everything is written
|
// close the input stream after everything is written
|
||||||
@ -927,7 +927,7 @@ static int do_os_system(char **argv, const char *input, size_t len, char **outpu
|
|||||||
msg_no_more = true;
|
msg_no_more = true;
|
||||||
lines_left = -1;
|
lines_left = -1;
|
||||||
}
|
}
|
||||||
int exitcode = process_wait(proc, -1, NULL);
|
int exitcode = proc_wait(proc, -1, NULL);
|
||||||
if (!got_int && out_data_decide_throttle(0)) {
|
if (!got_int && out_data_decide_throttle(0)) {
|
||||||
// Last chunk of output was skipped; display it now.
|
// Last chunk of output was skipped; display it now.
|
||||||
out_data_ring(NULL, SIZE_MAX);
|
out_data_ring(NULL, SIZE_MAX);
|
||||||
|
@ -950,8 +950,8 @@ void time_msg(const char *mesg, const proftime_T *start)
|
|||||||
/// Initializes the `time_fd` stream for the --startuptime report.
|
/// Initializes the `time_fd` stream for the --startuptime report.
|
||||||
///
|
///
|
||||||
/// @param fname startuptime report file path
|
/// @param fname startuptime report file path
|
||||||
/// @param process_name name of the current Nvim process to write in the report.
|
/// @param proc_name name of the current Nvim process to write in the report.
|
||||||
void time_init(const char *fname, const char *process_name)
|
void time_init(const char *fname, const char *proc_name)
|
||||||
{
|
{
|
||||||
const size_t bufsize = 8192; // Big enough for the entire --startuptime report.
|
const size_t bufsize = 8192; // Big enough for the entire --startuptime report.
|
||||||
time_fd = fopen(fname, "a");
|
time_fd = fopen(fname, "a");
|
||||||
@ -972,7 +972,7 @@ void time_init(const char *fname, const char *process_name)
|
|||||||
semsg("time_init: setvbuf failed: %d %s", r, uv_err_name(r));
|
semsg("time_init: setvbuf failed: %d %s", r, uv_err_name(r));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
fprintf(time_fd, "--- Startup times for process: %s ---\n", process_name);
|
fprintf(time_fd, "--- Startup times for process: %s ---\n", proc_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Flushes the startuptimes to disk for the current process
|
/// Flushes the startuptimes to disk for the current process
|
||||||
|
@ -103,7 +103,7 @@ Debugging tests
|
|||||||
DBG 2022-06-15T18:37:45.227 T57.58016.0/c UI: stop
|
DBG 2022-06-15T18:37:45.227 T57.58016.0/c UI: stop
|
||||||
INF 2022-06-15T18:37:45.227 T57.58016.0/c os_exit:595: Nvim exit: 0
|
INF 2022-06-15T18:37:45.227 T57.58016.0/c os_exit:595: Nvim exit: 0
|
||||||
DBG 2022-06-15T18:37:45.229 T57.58016.0 read_cb:118: closing Stream (0x7fd5d700ea18): EOF (end of file)
|
DBG 2022-06-15T18:37:45.229 T57.58016.0 read_cb:118: closing Stream (0x7fd5d700ea18): EOF (end of file)
|
||||||
INF 2022-06-15T18:37:45.229 T57.58016.0 on_process_exit:400: exited: pid=58017 status=0 stoptime=0
|
INF 2022-06-15T18:37:45.229 T57.58016.0 on_proc_exit:400: exited: pid=58017 status=0 stoptime=0
|
||||||
```
|
```
|
||||||
- You can set `$GDB` to [run functional tests under gdbserver](https://github.com/neovim/neovim/pull/1527):
|
- You can set `$GDB` to [run functional tests under gdbserver](https://github.com/neovim/neovim/pull/1527):
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user