summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org>2021-11-18 13:30:03 +0200
committerSergey Poznyakoff <gray@gnu.org>2021-11-18 13:30:03 +0200
commitc6c8162e6d81fdd5994007f4407de4305f4778bf (patch)
treea3ec0d127c717e1582fde4861d35a6eeff76e462
parentf3c7872fed5e0782438d186ac88c63035a637462 (diff)
downloadgdbm-c6c8162e6d81fdd5994007f4407de4305f4778bf.tar.gz
Fix shell command in gdbmtool
Trailing whitespace was erroneously recognized as argument. * src/lex.l (string_end): Optionally return NULL if the collected string is of zero length. When leaving the SHELL condition, don't return T_WORD for trailing whitespace. * src/gdbmshell.c (shell_handler): Perror after failed execv.
-rw-r--r--src/gdbmshell.c1
-rw-r--r--src/lex.l42
2 files changed, 27 insertions, 16 deletions
diff --git a/src/gdbmshell.c b/src/gdbmshell.c
index 96b5844..6e4d8ff 100644
--- a/src/gdbmshell.c
+++ b/src/gdbmshell.c
@@ -1771,6 +1771,7 @@ shell_handler (struct command_param *param,
if (pid == 0)
{
execv (argv[0], argv);
+ perror (argv[0]);
_exit (127);
}
diff --git a/src/lex.l b/src/lex.l
index 00a641f..3d63687 100644
--- a/src/lex.l
+++ b/src/lex.l
@@ -64,7 +64,7 @@ advance_line (void)
void string_begin (void);
void string_add (const char *s, int l);
void string_addc (int c);
-char *string_end (void);
+char *string_end (int empty_null);
int unescape (int c);
struct file_name
@@ -341,7 +341,7 @@ pad { return T_PAD; }
<STR,MLSTR>{
[^\\\"\n]*\" { if (yyleng > 1)
string_add (yytext, yyleng - 1);
- yylval.string = string_end ();
+ yylval.string = string_end (FALSE);
BEGIN (CMD);
return T_WORD; }
[^\\\"\n]*\\\n { advance_line ();
@@ -376,8 +376,8 @@ pad { return T_PAD; }
BEGIN (INITIAL);
advance_line ();
yyless (0);
- yylval.string = string_end ();
- return T_WORD;
+ if ((yylval.string = string_end (TRUE)) != NULL)
+ return T_WORD;
}
. string_addc (yytext[0]);
}
@@ -475,28 +475,38 @@ string_addc (int c)
strseg_attach (seg);
}
+/*
+ * Compose the collected string segments into a nul-terminated string.
+ * Return the allocated string.
+ * If EMPTY_NULL is TRUE and the resulting string length is 0, return
+ * NULL instead.
+ */
char *
-string_end (void)
+string_end (int empty_null)
{
- int len = 1;
+ int len = 0;
struct strseg *seg;
char *ret, *p;
for (seg = strseg_head; seg; seg = seg->next)
len += seg->len;
- ret = emalloc (len);
- p = ret;
- for (seg = strseg_head; seg; )
+ if (len == 0 && empty_null)
+ ret = NULL;
+ else
{
- struct strseg *next = seg->next;
- memcpy (p, seg->ptr, seg->len);
- p += seg->len;
- free (seg);
- seg = next;
+ ret = emalloc (len + 1);
+ p = ret;
+ for (seg = strseg_head; seg; )
+ {
+ struct strseg *next = seg->next;
+ memcpy (p, seg->ptr, seg->len);
+ p += seg->len;
+ free (seg);
+ seg = next;
+ }
+ *p = 0;
}
- *p = 0;
-
strseg_head = strseg_tail = NULL;
return ret;