aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzeertzjq <zeertzjq@outlook.com>2023-07-08 08:27:39 +0800
committerGitHub <noreply@github.com>2023-07-08 08:27:39 +0800
commit559c4cfd52e385c1b9bd5fa66a0eeb7e8d9e018a (patch)
treea03244eafab3110b07c1895fc8059bf7c85513eb
parentc379d72c490544b3a56eb0e52ce3c8ef740051d8 (diff)
downloadrneovim-559c4cfd52e385c1b9bd5fa66a0eeb7e8d9e018a.tar.gz
rneovim-559c4cfd52e385c1b9bd5fa66a0eeb7e8d9e018a.tar.bz2
rneovim-559c4cfd52e385c1b9bd5fa66a0eeb7e8d9e018a.zip
fix(startup): run embedded Nvim with real path (#24282)
fix(startup): run embedded process with real path
-rw-r--r--src/nvim/channel.c13
-rw-r--r--src/nvim/eval/funcs.c6
-rw-r--r--src/nvim/event/libuv_process.c2
-rw-r--r--src/nvim/event/process.c2
-rw-r--r--src/nvim/event/process.h8
-rw-r--r--src/nvim/os/pty_process_unix.c2
-rw-r--r--src/nvim/ui_client.c4
7 files changed, 24 insertions, 13 deletions
diff --git a/src/nvim/channel.c b/src/nvim/channel.c
index 569d3f5887..f9ce62dbd2 100644
--- a/src/nvim/channel.c
+++ b/src/nvim/channel.c
@@ -309,6 +309,7 @@ static void close_cb(Stream *stream, void *data)
///
/// @param[in] argv Arguments vector specifying the command to run,
/// NULL-terminated
+/// @param[in] exepath The path to the executable. If NULL, use `argv[0]`.
/// @param[in] on_stdout Callback to read the job's stdout
/// @param[in] on_stderr Callback to read the job's stderr
/// @param[in] on_exit Callback to receive the job's exit status
@@ -330,10 +331,11 @@ static void close_cb(Stream *stream, void *data)
/// < 0 if the job can't start
///
/// @returns [allocated] channel
-Channel *channel_job_start(char **argv, CallbackReader on_stdout, CallbackReader on_stderr,
- Callback on_exit, bool pty, bool rpc, bool overlapped, bool detach,
- ChannelStdinMode stdin_mode, const char *cwd, uint16_t pty_width,
- uint16_t pty_height, dict_T *env, varnumber_T *status_out)
+Channel *channel_job_start(char **argv, const char *exepath, CallbackReader on_stdout,
+ CallbackReader on_stderr, Callback on_exit, bool pty, bool rpc,
+ bool overlapped, bool detach, ChannelStdinMode stdin_mode,
+ const char *cwd, uint16_t pty_width, uint16_t pty_height, dict_T *env,
+ varnumber_T *status_out)
{
Channel *chan = channel_alloc(kChannelStreamProc);
chan->on_data = on_stdout;
@@ -364,6 +366,7 @@ Channel *channel_job_start(char **argv, CallbackReader on_stdout, CallbackReader
Process *proc = &chan->stream.proc;
proc->argv = argv;
+ proc->exepath = exepath;
proc->cb = channel_process_exit_cb;
proc->events = chan->events;
proc->detach = detach;
@@ -371,7 +374,7 @@ Channel *channel_job_start(char **argv, CallbackReader on_stdout, CallbackReader
proc->env = env;
proc->overlapped = overlapped;
- char *cmd = xstrdup(proc->argv[0]);
+ char *cmd = xstrdup(process_get_exepath(proc));
bool has_out, has_err;
if (proc->type == kProcessTypePty) {
has_out = true;
diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c
index 7c3c5cc274..e823e131b1 100644
--- a/src/nvim/eval/funcs.c
+++ b/src/nvim/eval/funcs.c
@@ -4120,7 +4120,7 @@ static void f_jobstart(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
env = create_environment(job_env, clear_env, pty, term_name);
- Channel *chan = channel_job_start(argv, on_stdout, on_stderr, on_exit, pty,
+ Channel *chan = channel_job_start(argv, NULL, on_stdout, on_stderr, on_exit, pty,
rpc, overlapped, detach, stdin_mode, cwd,
width, height, env, &rettv->vval.v_number);
if (chan) {
@@ -6678,7 +6678,7 @@ static void f_rpcstart(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
// The last item of argv must be NULL
argv[i] = NULL;
- Channel *chan = channel_job_start(argv, CALLBACK_READER_INIT,
+ Channel *chan = channel_job_start(argv, NULL, CALLBACK_READER_INIT,
CALLBACK_READER_INIT, CALLBACK_NONE,
false, true, false, false,
kChannelStdinPipe, NULL, 0, 0, NULL,
@@ -8455,7 +8455,7 @@ static void f_termopen(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
const bool detach = false;
ChannelStdinMode stdin_mode = kChannelStdinPipe;
uint16_t term_width = (uint16_t)MAX(0, curwin->w_width_inner - win_col_off(curwin));
- Channel *chan = channel_job_start(argv, on_stdout, on_stderr, on_exit,
+ Channel *chan = channel_job_start(argv, NULL, on_stdout, on_stderr, on_exit,
pty, rpc, overlapped, detach, stdin_mode,
cwd, term_width, (uint16_t)curwin->w_height_inner,
env, &rettv->vval.v_number);
diff --git a/src/nvim/event/libuv_process.c b/src/nvim/event/libuv_process.c
index e528d21a71..1bb0511f12 100644
--- a/src/nvim/event/libuv_process.c
+++ b/src/nvim/event/libuv_process.c
@@ -24,7 +24,7 @@ int libuv_process_spawn(LibuvProcess *uvproc)
FUNC_ATTR_NONNULL_ALL
{
Process *proc = (Process *)uvproc;
- uvproc->uvopts.file = proc->argv[0];
+ uvproc->uvopts.file = process_get_exepath(proc);
uvproc->uvopts.args = proc->argv;
uvproc->uvopts.flags = UV_PROCESS_WINDOWS_HIDE;
#ifdef MSWIN
diff --git a/src/nvim/event/process.c b/src/nvim/event/process.c
index 1219566e9b..95bf4d1c3b 100644
--- a/src/nvim/event/process.c
+++ b/src/nvim/event/process.c
@@ -131,7 +131,7 @@ int process_spawn(Process *proc, bool in, bool out, bool err)
proc->internal_close_cb = decref;
proc->refcount++;
kl_push(WatcherPtr, proc->loop->children, proc);
- DLOG("new: pid=%d argv=[%s]", proc->pid, proc->argv[0]);
+ DLOG("new: pid=%d exepath=[%s]", proc->pid, process_get_exepath(proc));
return 0;
}
diff --git a/src/nvim/event/process.h b/src/nvim/event/process.h
index 39fed08c77..69fe229b0e 100644
--- a/src/nvim/event/process.h
+++ b/src/nvim/event/process.h
@@ -32,6 +32,7 @@ struct process {
uint64_t stopped_time; // process_stop() timestamp
const char *cwd;
char **argv;
+ const char *exepath;
dict_T *env;
Stream in, out, err;
/// Exit handler. If set, user must call process_free().
@@ -54,6 +55,7 @@ static inline Process process_init(Loop *loop, ProcessType type, void *data)
.stopped_time = 0,
.cwd = NULL,
.argv = NULL,
+ .exepath = NULL,
.in = { .closed = false },
.out = { .closed = false },
.err = { .closed = false },
@@ -66,6 +68,12 @@ static inline Process process_init(Loop *loop, ProcessType type, void *data)
};
}
+/// Get the path to the executable of the process.
+static inline const char *process_get_exepath(Process *proc)
+{
+ return proc->exepath != NULL ? proc->exepath : proc->argv[0];
+}
+
static inline bool process_is_stopped(Process *proc)
{
bool exited = (proc->status >= 0);
diff --git a/src/nvim/os/pty_process_unix.c b/src/nvim/os/pty_process_unix.c
index b5423c59d7..15a4ef6230 100644
--- a/src/nvim/os/pty_process_unix.c
+++ b/src/nvim/os/pty_process_unix.c
@@ -285,7 +285,7 @@ static void init_child(PtyProcess *ptyproc)
return;
}
- char *prog = ptyproc->process.argv[0];
+ const char *prog = process_get_exepath(proc);
assert(proc->env);
environ = tv_dict_to_env(proc->env);
diff --git a/src/nvim/ui_client.c b/src/nvim/ui_client.c
index 0fc6d4936d..cc564f4777 100644
--- a/src/nvim/ui_client.c
+++ b/src/nvim/ui_client.c
@@ -53,8 +53,8 @@ uint64_t ui_client_start_server(int argc, char **argv)
CallbackReader on_err = CALLBACK_READER_INIT;
on_err.fwd_err = true;
- Channel *channel = channel_job_start(args, CALLBACK_READER_INIT,
- on_err, CALLBACK_NONE,
+ Channel *channel = channel_job_start(args, get_vim_var_str(VV_PROGPATH),
+ CALLBACK_READER_INIT, on_err, CALLBACK_NONE,
false, true, true, false, kChannelStdinPipe,
NULL, 0, 0, NULL, &exit_status);