Skip to content

Commit f8bb9f9

Browse files
committed
updated for version 7.4.247
Problem: When passing input to system() there is no way to keep NUL and NL characters separate. Solution: Optionally use a list for the system() input. (ZyX)
1 parent 9e0e6f4 commit f8bb9f9

3 files changed

Lines changed: 73 additions & 40 deletions

File tree

runtime/doc/eval.txt

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5964,10 +5964,17 @@ synstack({lnum}, {col}) *synstack()*
59645964

59655965
system({expr} [, {input}]) *system()* *E677*
59665966
Get the output of the shell command {expr}.
5967-
When {input} is given, this string is written to a file and
5968-
passed as stdin to the command. The string is written as-is,
5969-
you need to take care of using the correct line separators
5970-
yourself. Pipes are not used.
5967+
5968+
When {input} is given and is a string this string is written
5969+
to a file and passed as stdin to the command. The string is
5970+
written as-is, you need to take care of using the correct line
5971+
separators yourself.
5972+
If {input} is given and is a |List| it is written to the file
5973+
in a way |writefile()| does with {binary} set to "b" (i.e.
5974+
with a newline between each list item with newlines inside
5975+
list items converted to NULs).
5976+
Pipes are not used.
5977+
59715978
Note: Use |shellescape()| or |::S| with |expand()| or
59725979
|fnamemodify()| to escape special characters in a command
59735980
argument. Newlines in {expr} may cause the command to fail.

src/eval.c

Lines changed: 60 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -836,6 +836,7 @@ static void getwinvar __ARGS((typval_T *argvars, typval_T *rettv, int off));
836836
static int searchpair_cmn __ARGS((typval_T *argvars, pos_T *match_pos));
837837
static int search_cmn __ARGS((typval_T *argvars, pos_T *match_pos, int *flagsp));
838838
static void setwinvar __ARGS((typval_T *argvars, typval_T *rettv, int off));
839+
static int write_list __ARGS((FILE *fd, list_T *list, int binary));
839840

840841

841842
#ifdef EBCDIC
@@ -18267,14 +18268,22 @@ f_system(argvars, rettv)
1826718268
EMSG2(_(e_notopen), infile);
1826818269
goto done;
1826918270
}
18270-
p = get_tv_string_buf_chk(&argvars[1], buf);
18271-
if (p == NULL)
18271+
if (argvars[1].v_type == VAR_LIST)
1827218272
{
18273-
fclose(fd);
18274-
goto done; /* type error; errmsg already given */
18273+
if (write_list(fd, argvars[1].vval.v_list, TRUE) == FAIL)
18274+
err = TRUE;
18275+
}
18276+
else
18277+
{
18278+
p = get_tv_string_buf_chk(&argvars[1], buf);
18279+
if (p == NULL)
18280+
{
18281+
fclose(fd);
18282+
goto done; /* type error; errmsg already given */
18283+
}
18284+
if (fwrite(p, STRLEN(p), 1, fd) != 1)
18285+
err = TRUE;
1827518286
}
18276-
if (fwrite(p, STRLEN(p), 1, fd) != 1)
18277-
err = TRUE;
1827818287
if (fclose(fd) != 0)
1827918288
err = TRUE;
1828018289
if (err)
@@ -19172,6 +19181,49 @@ f_winwidth(argvars, rettv)
1917219181
#endif
1917319182
}
1917419183

19184+
/*
19185+
* Write list of strings to file
19186+
*/
19187+
static int
19188+
write_list(fd, list, binary)
19189+
FILE *fd;
19190+
list_T *list;
19191+
int binary;
19192+
{
19193+
listitem_T *li;
19194+
int c;
19195+
int ret = OK;
19196+
char_u *s;
19197+
19198+
for (li = list->lv_first; li != NULL; li = li->li_next)
19199+
{
19200+
for (s = get_tv_string(&li->li_tv); *s != NUL; ++s)
19201+
{
19202+
if (*s == '\n')
19203+
c = putc(NUL, fd);
19204+
else
19205+
c = putc(*s, fd);
19206+
if (c == EOF)
19207+
{
19208+
ret = FAIL;
19209+
break;
19210+
}
19211+
}
19212+
if (!binary || li->li_next != NULL)
19213+
if (putc('\n', fd) == EOF)
19214+
{
19215+
ret = FAIL;
19216+
break;
19217+
}
19218+
if (ret == FAIL)
19219+
{
19220+
EMSG(_(e_write));
19221+
break;
19222+
}
19223+
}
19224+
return ret;
19225+
}
19226+
1917519227
/*
1917619228
* "writefile()" function
1917719229
*/
@@ -19183,10 +19235,7 @@ f_writefile(argvars, rettv)
1918319235
int binary = FALSE;
1918419236
char_u *fname;
1918519237
FILE *fd;
19186-
listitem_T *li;
19187-
char_u *s;
1918819238
int ret = 0;
19189-
int c;
1919019239

1919119240
if (check_restricted() || check_secure())
1919219241
return;
@@ -19213,33 +19262,8 @@ f_writefile(argvars, rettv)
1921319262
}
1921419263
else
1921519264
{
19216-
for (li = argvars[0].vval.v_list->lv_first; li != NULL;
19217-
li = li->li_next)
19218-
{
19219-
for (s = get_tv_string(&li->li_tv); *s != NUL; ++s)
19220-
{
19221-
if (*s == '\n')
19222-
c = putc(NUL, fd);
19223-
else
19224-
c = putc(*s, fd);
19225-
if (c == EOF)
19226-
{
19227-
ret = -1;
19228-
break;
19229-
}
19230-
}
19231-
if (!binary || li->li_next != NULL)
19232-
if (putc('\n', fd) == EOF)
19233-
{
19234-
ret = -1;
19235-
break;
19236-
}
19237-
if (ret < 0)
19238-
{
19239-
EMSG(_(e_write));
19240-
break;
19241-
}
19242-
}
19265+
if (write_list(fd, argvars[0].vval.v_list, binary) == FAIL)
19266+
ret = -1;
1924319267
fclose(fd);
1924419268
}
1924519269

src/version.c

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

735735
static int included_patches[] =
736736
{ /* Add new patch number below this line */
737+
/**/
738+
247,
737739
/**/
738740
246,
739741
/**/

0 commit comments

Comments
 (0)