mirror of
				https://github.com/neovim/neovim.git
				synced 2025-11-04 01:34:25 +00:00 
			
		
		
		
	fix(startup): run embedded Nvim with real path (#24282)
fix(startup): run embedded process with real path
This commit is contained in:
		@@ -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;
 | 
			
		||||
 
 | 
			
		||||
@@ -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);
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 
 | 
			
		||||
@@ -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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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);
 | 
			
		||||
 
 | 
			
		||||
@@ -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);
 | 
			
		||||
 
 | 
			
		||||
@@ -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);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user