Skip to content

Commit 2060892

Browse files
committed
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.
1 parent 9980b37 commit 2060892

File tree

7 files changed

+121
-123
lines changed

7 files changed

+121
-123
lines changed

src/channel.c

Lines changed: 32 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -5021,11 +5021,11 @@ job_free_contents(job_T *job)
50215021
vim_free(job->jv_tty_out);
50225022
vim_free(job->jv_stoponexit);
50235023
free_callback(job->jv_exit_cb, job->jv_exit_partial);
5024-
if (job->argv != NULL)
5024+
if (job->jv_argv != NULL)
50255025
{
5026-
for (i = 0; job->argv[i] != NULL; i++)
5027-
vim_free(job->argv[i]);
5028-
vim_free(job->argv);
5026+
for (i = 0; job->jv_argv[i] != NULL; i++)
5027+
vim_free(job->jv_argv[i]);
5028+
vim_free(job->jv_argv);
50295029
}
50305030
}
50315031

@@ -5462,16 +5462,15 @@ job_start(typval_T *argvars, char **argv_arg, jobopt_T *opt_arg)
54625462
{
54635463
job_T *job;
54645464
char_u *cmd = NULL;
5465-
#if defined(UNIX)
5466-
# define USE_ARGV
54675465
char **argv = NULL;
54685466
int argc = 0;
5467+
#if defined(UNIX)
5468+
# define USE_ARGV
54695469
#else
54705470
garray_T ga;
54715471
#endif
54725472
jobopt_T opt;
54735473
ch_part_T part;
5474-
int len;
54755474
int i;
54765475

54775476
job = job_alloc();
@@ -5550,7 +5549,15 @@ job_start(typval_T *argvars, char **argv_arg, jobopt_T *opt_arg)
55505549
#ifdef USE_ARGV
55515550
if (argv_arg != NULL)
55525551
{
5553-
argv = argv_arg;
5552+
/* Make a copy of argv_arg for job->jv_argv. */
5553+
for (i = 0; argv_arg[i] != NULL; i++)
5554+
argc++;
5555+
argv = (char **)alloc(sizeof(char_u *) * (argc + 1));
5556+
if (argv == NULL)
5557+
goto theend;
5558+
for (i = 0; i < argc; i++)
5559+
argv[i] = (char *)vim_strsave((char_u *)argv_arg[i]);
5560+
argv[argc] = NULL;
55545561
}
55555562
else
55565563
#endif
@@ -5563,12 +5570,12 @@ job_start(typval_T *argvars, char **argv_arg, jobopt_T *opt_arg)
55635570
EMSG(_(e_invarg));
55645571
goto theend;
55655572
}
5566-
#ifdef USE_ARGV
55675573
/* This will modify "cmd". */
55685574
if (mch_parse_cmd(cmd, FALSE, &argv, &argc) == FAIL)
55695575
goto theend;
5576+
for (i = 0; i < argc; i++)
5577+
argv[i] = (char *)vim_strsave((char_u *)argv[i]);
55705578
argv[argc] = NULL;
5571-
#endif
55725579
}
55735580
else if (argvars[0].v_type != VAR_LIST
55745581
|| argvars[0].vval.v_list == NULL
@@ -5580,7 +5587,6 @@ job_start(typval_T *argvars, char **argv_arg, jobopt_T *opt_arg)
55805587
else
55815588
{
55825589
list_T *l = argvars[0].vval.v_list;
5583-
#ifdef USE_ARGV
55845590
listitem_T *li;
55855591
char_u *s;
55865592

@@ -5592,27 +5598,24 @@ job_start(typval_T *argvars, char **argv_arg, jobopt_T *opt_arg)
55925598
{
55935599
s = get_tv_string_chk(&li->li_tv);
55945600
if (s == NULL)
5601+
{
5602+
for (i = 0; i < argc; ++i)
5603+
vim_free(argv[i]);
55955604
goto theend;
5596-
argv[argc++] = (char *)s;
5605+
}
5606+
argv[argc++] = (char *)vim_strsave(s);
55975607
}
55985608
argv[argc] = NULL;
5599-
#else
5609+
5610+
#ifndef USE_ARGV
56005611
if (win32_build_cmd(l, &ga) == FAIL)
56015612
goto theend;
56025613
cmd = ga.ga_data;
56035614
#endif
56045615
}
56055616

5606-
/* Save the command used to start the job */
5607-
len = 0;
5608-
for (i = 0; argv[i] != NULL; i++)
5609-
len++;
5610-
job->argv = (char_u **)alloc(sizeof(char_u *) * (len + 1));
5611-
if (job->argv == NULL)
5612-
goto theend;
5613-
for (i = 0; argv[i] != NULL; i++)
5614-
job->argv[i] = vim_strsave((char_u *)argv[i]);
5615-
job->argv[i] = NULL;
5617+
/* Save the command used to start the job. */
5618+
job->jv_argv = (char_u **)argv;
56165619

56175620
#ifdef USE_ARGV
56185621
if (ch_log_active())
@@ -5640,12 +5643,11 @@ job_start(typval_T *argvars, char **argv_arg, jobopt_T *opt_arg)
56405643
channel_write_in(job->jv_channel);
56415644

56425645
theend:
5643-
#ifdef USE_ARGV
5644-
if (argv != argv_arg)
5645-
vim_free(argv);
5646-
#else
5646+
#ifndef USE_ARGV
56475647
vim_free(ga.ga_data);
56485648
#endif
5649+
if ((char_u **)argv != job->jv_argv)
5650+
vim_free(argv);
56495651
free_job_options(&opt);
56505652
return job;
56515653
}
@@ -5716,8 +5718,9 @@ job_info(job_T *job, dict_T *dict)
57165718
if (l != NULL)
57175719
{
57185720
dict_add_list(dict, "cmd", l);
5719-
for (i = 0; job->argv[i] != NULL; i++)
5720-
list_append_string(l, job->argv[i], -1);
5721+
if (job->jv_argv != NULL)
5722+
for (i = 0; job->jv_argv[i] != NULL; i++)
5723+
list_append_string(l, job->jv_argv[i], -1);
57215724
}
57225725
}
57235726

src/misc2.c

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6429,3 +6429,88 @@ elapsed(DWORD start_tick)
64296429
}
64306430
# endif
64316431
#endif
6432+
6433+
#if defined(FEAT_JOB_CHANNEL) \
6434+
|| (defined(UNIX) && (!defined(USE_SYSTEM) \
6435+
|| (defined(FEAT_GUI) && defined(FEAT_TERMINAL)))) \
6436+
|| defined(PROTO)
6437+
/*
6438+
* Parse "cmd" and put the white-separated parts in "argv".
6439+
* "argv" is an allocated array with "argc" entries and room for 4 more.
6440+
* Returns FAIL when out of memory.
6441+
*/
6442+
int
6443+
mch_parse_cmd(char_u *cmd, int use_shcf, char ***argv, int *argc)
6444+
{
6445+
int i;
6446+
char_u *p, *d;
6447+
int inquote;
6448+
6449+
/*
6450+
* Do this loop twice:
6451+
* 1: find number of arguments
6452+
* 2: separate them and build argv[]
6453+
*/
6454+
for (i = 0; i < 2; ++i)
6455+
{
6456+
p = skipwhite(cmd);
6457+
inquote = FALSE;
6458+
*argc = 0;
6459+
for (;;)
6460+
{
6461+
if (i == 1)
6462+
(*argv)[*argc] = (char *)p;
6463+
++*argc;
6464+
d = p;
6465+
while (*p != NUL && (inquote || (*p != ' ' && *p != TAB)))
6466+
{
6467+
if (p[0] == '"')
6468+
/* quotes surrounding an argument and are dropped */
6469+
inquote = !inquote;
6470+
else
6471+
{
6472+
if (p[0] == '\\' && p[1] != NUL)
6473+
{
6474+
/* First pass: skip over "\ " and "\"".
6475+
* Second pass: Remove the backslash. */
6476+
++p;
6477+
}
6478+
if (i == 1)
6479+
*d++ = *p;
6480+
}
6481+
++p;
6482+
}
6483+
if (*p == NUL)
6484+
{
6485+
if (i == 1)
6486+
*d++ = NUL;
6487+
break;
6488+
}
6489+
if (i == 1)
6490+
*d++ = NUL;
6491+
p = skipwhite(p + 1);
6492+
}
6493+
if (*argv == NULL)
6494+
{
6495+
if (use_shcf)
6496+
{
6497+
/* Account for possible multiple args in p_shcf. */
6498+
p = p_shcf;
6499+
for (;;)
6500+
{
6501+
p = skiptowhite(p);
6502+
if (*p == NUL)
6503+
break;
6504+
++*argc;
6505+
p = skipwhite(p);
6506+
}
6507+
}
6508+
6509+
*argv = (char **)alloc((unsigned)((*argc + 4) * sizeof(char *)));
6510+
if (*argv == NULL) /* out of memory */
6511+
return FAIL;
6512+
}
6513+
}
6514+
return OK;
6515+
}
6516+
#endif

src/os_unix.c

Lines changed: 0 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -4154,91 +4154,6 @@ wait4pid(pid_t child, waitstatus *status)
41544154
return wait_pid;
41554155
}
41564156

4157-
#if defined(FEAT_JOB_CHANNEL) \
4158-
|| !defined(USE_SYSTEM) \
4159-
|| (defined(FEAT_GUI) && defined(FEAT_TERMINAL)) \
4160-
|| defined(PROTO)
4161-
/*
4162-
* Parse "cmd" and put the white-separated parts in "argv".
4163-
* "argv" is an allocated array with "argc" entries and room for 4 more.
4164-
* Returns FAIL when out of memory.
4165-
*/
4166-
int
4167-
mch_parse_cmd(char_u *cmd, int use_shcf, char ***argv, int *argc)
4168-
{
4169-
int i;
4170-
char_u *p, *d;
4171-
int inquote;
4172-
4173-
/*
4174-
* Do this loop twice:
4175-
* 1: find number of arguments
4176-
* 2: separate them and build argv[]
4177-
*/
4178-
for (i = 0; i < 2; ++i)
4179-
{
4180-
p = skipwhite(cmd);
4181-
inquote = FALSE;
4182-
*argc = 0;
4183-
for (;;)
4184-
{
4185-
if (i == 1)
4186-
(*argv)[*argc] = (char *)p;
4187-
++*argc;
4188-
d = p;
4189-
while (*p != NUL && (inquote || (*p != ' ' && *p != TAB)))
4190-
{
4191-
if (p[0] == '"')
4192-
/* quotes surrounding an argument and are dropped */
4193-
inquote = !inquote;
4194-
else
4195-
{
4196-
if (p[0] == '\\' && p[1] != NUL)
4197-
{
4198-
/* First pass: skip over "\ " and "\"".
4199-
* Second pass: Remove the backslash. */
4200-
++p;
4201-
}
4202-
if (i == 1)
4203-
*d++ = *p;
4204-
}
4205-
++p;
4206-
}
4207-
if (*p == NUL)
4208-
{
4209-
if (i == 1)
4210-
*d++ = NUL;
4211-
break;
4212-
}
4213-
if (i == 1)
4214-
*d++ = NUL;
4215-
p = skipwhite(p + 1);
4216-
}
4217-
if (*argv == NULL)
4218-
{
4219-
if (use_shcf)
4220-
{
4221-
/* Account for possible multiple args in p_shcf. */
4222-
p = p_shcf;
4223-
for (;;)
4224-
{
4225-
p = skiptowhite(p);
4226-
if (*p == NUL)
4227-
break;
4228-
++*argc;
4229-
p = skipwhite(p);
4230-
}
4231-
}
4232-
4233-
*argv = (char **)alloc((unsigned)((*argc + 4) * sizeof(char *)));
4234-
if (*argv == NULL) /* out of memory */
4235-
return FAIL;
4236-
}
4237-
}
4238-
return OK;
4239-
}
4240-
#endif
4241-
42424157
#if !defined(USE_SYSTEM) || defined(FEAT_JOB_CHANNEL)
42434158
/*
42444159
* Set the environment for a child process.

src/proto/misc2.pro

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,4 +110,5 @@ int put_time(FILE *fd, time_T the_time);
110110
void time_to_bytes(time_T the_time, char_u *buf);
111111
int has_non_ascii(char_u *s);
112112
void parse_queued_messages(void);
113+
int mch_parse_cmd(char_u *cmd, int use_shcf, char ***argv, int *argc);
113114
/* vim: set ft=c : */

src/structs.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1488,7 +1488,7 @@ struct jobvar_S
14881488
int jv_copyID;
14891489

14901490
channel_T *jv_channel; /* channel for I/O, reference counted */
1491-
char_u **argv; /* command line used to start the job */
1491+
char_u **jv_argv; /* command line used to start the job */
14921492
};
14931493

14941494
/*

src/terminal.c

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5312,14 +5312,6 @@ term_and_job_init(
53125312
win32_build_env(opt->jo_env, &ga_env, TRUE);
53135313
env_wchar = ga_env.ga_data;
53145314

5315-
job = job_alloc();
5316-
if (job == NULL)
5317-
goto failed;
5318-
5319-
channel = add_channel();
5320-
if (channel == NULL)
5321-
goto failed;
5322-
53235315
term->tl_winpty_config = winpty_config_new(0, &winpty_err);
53245316
if (term->tl_winpty_config == NULL)
53255317
goto failed;

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -761,6 +761,8 @@ static char *(features[]) =
761761

762762
static int included_patches[] =
763763
{ /* Add new patch number below this line */
764+
/**/
765+
1745,
764766
/**/
765767
1744,
766768
/**/

0 commit comments

Comments
 (0)