# HG changeset patch # User Christian Brabandt # Date 1524343507 -7200 # Node ID 260256caac38b836fb2c1e8712ce266d58de576a # Parent b8d9c3a2e7f960f7adc82bbdd6019c19198b46bf patch 8.0.1745: build failure on MS-Windows commit https://github.com/vim/vim/commit/2060892028e05b1325dc0759259254180669eb5e Author: Bram Moolenaar Date: Sat Apr 21 22:30:08 2018 +0200 patch 8.0.1745: build failure on MS-Windows Problem: Build failure on MS-Windows. Solution: Build job arguments for MS-Windows. Fix allocating job twice. diff --git a/src/channel.c b/src/channel.c --- a/src/channel.c +++ b/src/channel.c @@ -5021,11 +5021,11 @@ job_free_contents(job_T *job) vim_free(job->jv_tty_out); vim_free(job->jv_stoponexit); free_callback(job->jv_exit_cb, job->jv_exit_partial); - if (job->argv != NULL) + if (job->jv_argv != NULL) { - for (i = 0; job->argv[i] != NULL; i++) - vim_free(job->argv[i]); - vim_free(job->argv); + for (i = 0; job->jv_argv[i] != NULL; i++) + vim_free(job->jv_argv[i]); + vim_free(job->jv_argv); } } @@ -5462,16 +5462,15 @@ job_start(typval_T *argvars, char **argv { job_T *job; char_u *cmd = NULL; + char **argv = NULL; + int argc = 0; #if defined(UNIX) # define USE_ARGV - char **argv = NULL; - int argc = 0; #else garray_T ga; #endif jobopt_T opt; ch_part_T part; - int len; int i; job = job_alloc(); @@ -5550,7 +5549,15 @@ job_start(typval_T *argvars, char **argv #ifdef USE_ARGV if (argv_arg != NULL) { - argv = argv_arg; + /* Make a copy of argv_arg for job->jv_argv. */ + for (i = 0; argv_arg[i] != NULL; i++) + argc++; + argv = (char **)alloc(sizeof(char_u *) * (argc + 1)); + if (argv == NULL) + goto theend; + for (i = 0; i < argc; i++) + argv[i] = (char *)vim_strsave((char_u *)argv_arg[i]); + argv[argc] = NULL; } else #endif @@ -5563,12 +5570,12 @@ job_start(typval_T *argvars, char **argv EMSG(_(e_invarg)); goto theend; } -#ifdef USE_ARGV /* This will modify "cmd". */ if (mch_parse_cmd(cmd, FALSE, &argv, &argc) == FAIL) goto theend; + for (i = 0; i < argc; i++) + argv[i] = (char *)vim_strsave((char_u *)argv[i]); argv[argc] = NULL; -#endif } else if (argvars[0].v_type != VAR_LIST || argvars[0].vval.v_list == NULL @@ -5580,7 +5587,6 @@ job_start(typval_T *argvars, char **argv else { list_T *l = argvars[0].vval.v_list; -#ifdef USE_ARGV listitem_T *li; char_u *s; @@ -5592,27 +5598,24 @@ job_start(typval_T *argvars, char **argv { s = get_tv_string_chk(&li->li_tv); if (s == NULL) + { + for (i = 0; i < argc; ++i) + vim_free(argv[i]); goto theend; - argv[argc++] = (char *)s; + } + argv[argc++] = (char *)vim_strsave(s); } argv[argc] = NULL; -#else + +#ifndef USE_ARGV if (win32_build_cmd(l, &ga) == FAIL) goto theend; cmd = ga.ga_data; #endif } - /* Save the command used to start the job */ - len = 0; - for (i = 0; argv[i] != NULL; i++) - len++; - job->argv = (char_u **)alloc(sizeof(char_u *) * (len + 1)); - if (job->argv == NULL) - goto theend; - for (i = 0; argv[i] != NULL; i++) - job->argv[i] = vim_strsave((char_u *)argv[i]); - job->argv[i] = NULL; + /* Save the command used to start the job. */ + job->jv_argv = (char_u **)argv; #ifdef USE_ARGV if (ch_log_active()) @@ -5640,12 +5643,11 @@ job_start(typval_T *argvars, char **argv channel_write_in(job->jv_channel); theend: -#ifdef USE_ARGV - if (argv != argv_arg) - vim_free(argv); -#else +#ifndef USE_ARGV vim_free(ga.ga_data); #endif + if ((char_u **)argv != job->jv_argv) + vim_free(argv); free_job_options(&opt); return job; } @@ -5716,8 +5718,9 @@ job_info(job_T *job, dict_T *dict) if (l != NULL) { dict_add_list(dict, "cmd", l); - for (i = 0; job->argv[i] != NULL; i++) - list_append_string(l, job->argv[i], -1); + if (job->jv_argv != NULL) + for (i = 0; job->jv_argv[i] != NULL; i++) + list_append_string(l, job->jv_argv[i], -1); } } diff --git a/src/misc2.c b/src/misc2.c --- a/src/misc2.c +++ b/src/misc2.c @@ -6429,3 +6429,88 @@ elapsed(DWORD start_tick) } # endif #endif + +#if defined(FEAT_JOB_CHANNEL) \ + || (defined(UNIX) && (!defined(USE_SYSTEM) \ + || (defined(FEAT_GUI) && defined(FEAT_TERMINAL)))) \ + || defined(PROTO) +/* + * Parse "cmd" and put the white-separated parts in "argv". + * "argv" is an allocated array with "argc" entries and room for 4 more. + * Returns FAIL when out of memory. + */ + int +mch_parse_cmd(char_u *cmd, int use_shcf, char ***argv, int *argc) +{ + int i; + char_u *p, *d; + int inquote; + + /* + * Do this loop twice: + * 1: find number of arguments + * 2: separate them and build argv[] + */ + for (i = 0; i < 2; ++i) + { + p = skipwhite(cmd); + inquote = FALSE; + *argc = 0; + for (;;) + { + if (i == 1) + (*argv)[*argc] = (char *)p; + ++*argc; + d = p; + while (*p != NUL && (inquote || (*p != ' ' && *p != TAB))) + { + if (p[0] == '"') + /* quotes surrounding an argument and are dropped */ + inquote = !inquote; + else + { + if (p[0] == '\\' && p[1] != NUL) + { + /* First pass: skip over "\ " and "\"". + * Second pass: Remove the backslash. */ + ++p; + } + if (i == 1) + *d++ = *p; + } + ++p; + } + if (*p == NUL) + { + if (i == 1) + *d++ = NUL; + break; + } + if (i == 1) + *d++ = NUL; + p = skipwhite(p + 1); + } + if (*argv == NULL) + { + if (use_shcf) + { + /* Account for possible multiple args in p_shcf. */ + p = p_shcf; + for (;;) + { + p = skiptowhite(p); + if (*p == NUL) + break; + ++*argc; + p = skipwhite(p); + } + } + + *argv = (char **)alloc((unsigned)((*argc + 4) * sizeof(char *))); + if (*argv == NULL) /* out of memory */ + return FAIL; + } + } + return OK; +} +#endif diff --git a/src/os_unix.c b/src/os_unix.c --- a/src/os_unix.c +++ b/src/os_unix.c @@ -4154,91 +4154,6 @@ wait4pid(pid_t child, waitstatus *status return wait_pid; } -#if defined(FEAT_JOB_CHANNEL) \ - || !defined(USE_SYSTEM) \ - || (defined(FEAT_GUI) && defined(FEAT_TERMINAL)) \ - || defined(PROTO) -/* - * Parse "cmd" and put the white-separated parts in "argv". - * "argv" is an allocated array with "argc" entries and room for 4 more. - * Returns FAIL when out of memory. - */ - int -mch_parse_cmd(char_u *cmd, int use_shcf, char ***argv, int *argc) -{ - int i; - char_u *p, *d; - int inquote; - - /* - * Do this loop twice: - * 1: find number of arguments - * 2: separate them and build argv[] - */ - for (i = 0; i < 2; ++i) - { - p = skipwhite(cmd); - inquote = FALSE; - *argc = 0; - for (;;) - { - if (i == 1) - (*argv)[*argc] = (char *)p; - ++*argc; - d = p; - while (*p != NUL && (inquote || (*p != ' ' && *p != TAB))) - { - if (p[0] == '"') - /* quotes surrounding an argument and are dropped */ - inquote = !inquote; - else - { - if (p[0] == '\\' && p[1] != NUL) - { - /* First pass: skip over "\ " and "\"". - * Second pass: Remove the backslash. */ - ++p; - } - if (i == 1) - *d++ = *p; - } - ++p; - } - if (*p == NUL) - { - if (i == 1) - *d++ = NUL; - break; - } - if (i == 1) - *d++ = NUL; - p = skipwhite(p + 1); - } - if (*argv == NULL) - { - if (use_shcf) - { - /* Account for possible multiple args in p_shcf. */ - p = p_shcf; - for (;;) - { - p = skiptowhite(p); - if (*p == NUL) - break; - ++*argc; - p = skipwhite(p); - } - } - - *argv = (char **)alloc((unsigned)((*argc + 4) * sizeof(char *))); - if (*argv == NULL) /* out of memory */ - return FAIL; - } - } - return OK; -} -#endif - #if !defined(USE_SYSTEM) || defined(FEAT_JOB_CHANNEL) /* * Set the environment for a child process. diff --git a/src/proto/misc2.pro b/src/proto/misc2.pro --- a/src/proto/misc2.pro +++ b/src/proto/misc2.pro @@ -110,4 +110,5 @@ int put_time(FILE *fd, time_T the_time); void time_to_bytes(time_T the_time, char_u *buf); int has_non_ascii(char_u *s); void parse_queued_messages(void); +int mch_parse_cmd(char_u *cmd, int use_shcf, char ***argv, int *argc); /* vim: set ft=c : */ diff --git a/src/structs.h b/src/structs.h --- a/src/structs.h +++ b/src/structs.h @@ -1488,7 +1488,7 @@ struct jobvar_S int jv_copyID; channel_T *jv_channel; /* channel for I/O, reference counted */ - char_u **argv; /* command line used to start the job */ + char_u **jv_argv; /* command line used to start the job */ }; /* diff --git a/src/terminal.c b/src/terminal.c --- a/src/terminal.c +++ b/src/terminal.c @@ -5312,14 +5312,6 @@ term_and_job_init( win32_build_env(opt->jo_env, &ga_env, TRUE); env_wchar = ga_env.ga_data; - job = job_alloc(); - if (job == NULL) - goto failed; - - channel = add_channel(); - if (channel == NULL) - goto failed; - term->tl_winpty_config = winpty_config_new(0, &winpty_err); if (term->tl_winpty_config == NULL) goto failed; diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -762,6 +762,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1745, +/**/ 1744, /**/ 1743,