diff options
| author | Bram Moolenaar <Bram@vim.org> | 2017-08-13 17:13:09 +0200 |
|---|---|---|
| committer | Bram Moolenaar <Bram@vim.org> | 2017-08-13 17:13:09 +0200 |
| commit | dcaa61384ca76e42f7feda5640fb85b58cee03e5 (patch) | |
| tree | 21eb8c92bc31eae5fe4d51c6f19bed1c05f01eb9 /src/terminal.c | |
| parent | 274a52fd58bbd88f5fe8b96d87abe3574c8169af (diff) | |
| download | vim-git-dcaa61384ca76e42f7feda5640fb85b58cee03e5.tar.gz | |
patch 8.0.0928: MS-Windows: passing arglist to job has escaping problemsv8.0.0928
Problem: MS-Windows: passing arglist to job has escaping problems.
Solution: Improve escaping. (Yasuhiro Matsumoto, closes #1954)
Diffstat (limited to 'src/terminal.c')
| -rw-r--r-- | src/terminal.c | 67 |
1 files changed, 43 insertions, 24 deletions
diff --git a/src/terminal.c b/src/terminal.c index 0024d5f8d..0267e5f54 100644 --- a/src/terminal.c +++ b/src/terminal.c @@ -39,7 +39,6 @@ * * TODO: * - Make argument list work on MS-Windows. #1954 - * - MS-Windows: no redraw for 'updatetime' #1915 * - To set BS correctly, check get_stty(); Pass the fd of the pty. * For the GUI fill termios with default values, perhaps like pangoterm: * http://bazaar.launchpad.net/~leonerd/pangoterm/trunk/view/head:/main.c#L134 @@ -165,7 +164,8 @@ static term_T *in_terminal_loop = NULL; /* * Functions with separate implementation for MS-Windows and Unix-like systems. */ -static int term_and_job_init(term_T *term, int rows, int cols, char_u *cmd, jobopt_T *opt); +static int term_and_job_init(term_T *term, int rows, int cols, + typval_T *argvar, jobopt_T *opt); static void term_report_winsize(term_T *term, int rows, int cols); static void term_free_vterm(term_T *term); @@ -244,7 +244,7 @@ setup_job_options(jobopt_T *opt, int rows, int cols) } static void -term_start(char_u *cmd, jobopt_T *opt, int forceit) +term_start(typval_T *argvar, jobopt_T *opt, int forceit) { exarg_T split_ea; win_T *old_curwin = curwin; @@ -340,16 +340,25 @@ term_start(char_u *cmd, jobopt_T *opt, int forceit) term->tl_next = first_term; first_term = term; - if (cmd == NULL || *cmd == NUL) - cmd = p_sh; - if (opt->jo_term_name != NULL) curbuf->b_ffname = vim_strsave(opt->jo_term_name); else { int i; - size_t len = STRLEN(cmd) + 10; - char_u *p = alloc((int)len); + size_t len; + char_u *cmd, *p; + + if (argvar->v_type == VAR_STRING) + cmd = argvar->vval.v_string; + else if (argvar->v_type != VAR_LIST + || argvar->vval.v_list == NULL + || argvar->vval.v_list->lv_len < 1) + cmd = (char_u*)""; + else + cmd = get_tv_string_chk(&argvar->vval.v_list->lv_first->li_tv); + + len = STRLEN(cmd) + 10; + p = alloc((int)len); for (i = 0; p != NULL; ++i) { @@ -386,7 +395,7 @@ term_start(char_u *cmd, jobopt_T *opt, int forceit) setup_job_options(opt, term->tl_rows, term->tl_cols); /* System dependent: setup the vterm and start the job in it. */ - if (term_and_job_init(term, term->tl_rows, term->tl_cols, cmd, opt) == OK) + if (term_and_job_init(term, term->tl_rows, term->tl_cols, argvar, opt) == OK) { /* Get and remember the size we ended up with. Update the pty. */ vterm_get_size(term->tl_vterm, &term->tl_rows, &term->tl_cols); @@ -425,6 +434,7 @@ term_start(char_u *cmd, jobopt_T *opt, int forceit) void ex_terminal(exarg_T *eap) { + typval_T argvar; jobopt_T opt; char_u *cmd; @@ -468,7 +478,9 @@ ex_terminal(exarg_T *eap) opt.jo_term_rows = eap->line2; } - term_start(cmd, &opt, eap->forceit); + argvar.v_type = VAR_STRING; + argvar.vval.v_string = cmd; + term_start(&argvar, &opt, eap->forceit); } /* @@ -2585,11 +2597,8 @@ f_term_sendkeys(typval_T *argvars, typval_T *rettv) void f_term_start(typval_T *argvars, typval_T *rettv) { - char_u *cmd = get_tv_string_chk(&argvars[0]); jobopt_T opt; - if (cmd == NULL) - return; init_job_options(&opt); /* TODO: allow more job options */ if (argvars[1].v_type != VAR_UNKNOWN @@ -2603,7 +2612,7 @@ f_term_start(typval_T *argvars, typval_T *rettv) if (opt.jo_vertical) cmdmod.split = WSP_VERT; - term_start(cmd, &opt, FALSE); + term_start(&argvars[0], &opt, FALSE); if (curbuf->b_term != NULL) rettv->vval.v_number = curbuf->b_fnum; @@ -2749,9 +2758,9 @@ dyn_winpty_init(void) * Return OK or FAIL. */ static int -term_and_job_init(term_T *term, int rows, int cols, char_u *cmd, jobopt_T *opt) +term_and_job_init(term_T *term, int rows, int cols, typval_T *argvar, jobopt_T *opt) { - WCHAR *p; + WCHAR *p = NULL; channel_T *channel = NULL; job_T *job = NULL; DWORD error; @@ -2759,10 +2768,22 @@ term_and_job_init(term_T *term, int rows, int cols, char_u *cmd, jobopt_T *opt) void *winpty_err; void *spawn_config = NULL; char buf[MAX_PATH]; + garray_T ga; + char_u *cmd; if (!dyn_winpty_init()) return FAIL; + if (argvar->v_type == VAR_STRING) + cmd = argvar->vval.v_string; + else + { + ga_init2(&ga, (int)sizeof(char*), 20); + if (win32_build_cmd(argvar->vval.v_list, &ga) == FAIL) + goto failed; + cmd = ga.ga_data; + } + p = enc_to_utf16(cmd, NULL); if (p == NULL) return FAIL; @@ -2855,9 +2876,12 @@ term_and_job_init(term_T *term, int rows, int cols, char_u *cmd, jobopt_T *opt) return OK; failed: + if (argvar->v_type == VAR_LIST) + vim_free(ga.ga_data); + if (p != NULL) + vim_free(p); if (spawn_config != NULL) winpty_spawn_config_free(spawn_config); - vim_free(p); if (channel != NULL) channel_clear(channel); if (job != NULL) @@ -2924,17 +2948,12 @@ term_report_winsize(term_T *term, int rows, int cols) * Return OK or FAIL. */ static int -term_and_job_init(term_T *term, int rows, int cols, char_u *cmd, jobopt_T *opt) +term_and_job_init(term_T *term, int rows, int cols, typval_T *argvar, jobopt_T *opt) { - typval_T argvars[2]; - create_vterm(term, rows, cols); /* TODO: if the command is "NONE" only create a pty. */ - argvars[0].v_type = VAR_STRING; - argvars[0].vval.v_string = cmd; - - term->tl_job = job_start(argvars, opt); + term->tl_job = job_start(argvar, opt); if (term->tl_job != NULL) ++term->tl_job->jv_refcount; |
