diff options
author | Sergey Poznyakoff <gray@gnu.org> | 2020-12-01 23:11:39 +0200 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org> | 2020-12-02 08:11:26 +0200 |
commit | c0f4c3b99bb3364fe3f840b1ecb44af2eeba097b (patch) | |
tree | 374bc9fe1a9802d97f027b56ddf9a1f59268fb4e /src | |
parent | c26297063aa2dad0fecd28791a47a8bffcfc9925 (diff) | |
download | pies-c0f4c3b99bb3364fe3f840b1ecb44af2eeba097b.tar.gz pies-c0f4c3b99bb3364fe3f840b1ecb44af2eeba097b.tar.bz2 |
New component flag: expandenv
* NEWS: Update.
* doc/pies.texi: Document the expandenv flag.
* src/comp.c (component_finish): Warn if both "shell" and "expandenv"
are used together.
Expand command to argc/argv only unless the CF_EXPANDENV flag is given.
* src/pies.c (str_to_cf): New flag: expandenv
* src/pies.h (CF_EXPANDENV): New define.
* src/prog.h (struct prog): New member: argv.
* src/progman.c (destroy_prog): Free argv.
(prog_start_prologue): Expand the command line taking into account
the current environment if CF_EXPANDENV flag is given. Otherwise,
copy the component argv to the prog.
(prog_execute): Use prog->v.p.argv
* tests/Makefile.am: Add expandenv.at
* tests/testsuite.at: Likewise.
* tests/expandenv.at: New file.
Diffstat (limited to 'src')
-rw-r--r-- | src/comp.c | 10 | ||||
-rw-r--r-- | src/pies.c | 1 | ||||
-rw-r--r-- | src/pies.h | 2 | ||||
-rw-r--r-- | src/prog.h | 1 | ||||
-rw-r--r-- | src/progman.c | 33 |
5 files changed, 39 insertions, 8 deletions
@@ -724,6 +724,14 @@ component_finish (struct component *comp, grecs_locus_t *locus) if (comp->flags & CF_SHELL) { + if (comp->flags & CF_EXPANDENV) + { + grecs_warning (locus, 0, + "%s", + _("flags \"shell\" and \"expandenv\" used together: " + "ignoring \"expandenv\"")); + comp->flags &= ~CF_EXPANDENV; + } comp->argc = 3; comp->argv = grecs_calloc (comp->argc + 1, sizeof (comp->argv[0])); comp->argv[0] = grecs_strdup (comp->program ? comp->program : "/bin/sh"); @@ -731,7 +739,7 @@ component_finish (struct component *comp, grecs_locus_t *locus) comp->argv[2] = grecs_strdup (comp->command); comp->argv[3] = NULL; } - else if (comp->command) + else if (comp->command && !(comp->flags & CF_EXPANDENV)) { struct wordsplit ws; if (wordsplit (comp->command, &ws, WRDSF_DEFFLAGS)) @@ -1143,6 +1143,7 @@ str_to_cf (const char *string, int *flags) { "siggroup", CF_SIGGROUP }, { "nullinput", CF_NULLINPUT }, { "shell", CF_SHELL }, + { "expandenv", CF_EXPANDENV }, { NULL } }; @@ -209,6 +209,8 @@ enum pies_comp_mode #define CF_SIGGROUP 0x100 /* Send signals to the process group */ #define CF_NULLINPUT 0x200 /* Provide null input stream */ #define CF_SHELL 0x400 /* Invoke via sh -c */ +#define CF_EXPANDENV 0x800 /* Expand environment variables in the command + line */ #define CF_REMOVE 0xf000 /* Marked for removal */ @@ -53,6 +53,7 @@ struct prog struct { struct component *comp; + char **argv; /* Actual command line (NULL-terminated) */ int socket; struct prog *redir[2]; /* Pointers to redirectors */ time_t timestamp; /* Time of last startup */ diff --git a/src/progman.c b/src/progman.c index 2a073af..1cd5f9d 100644 --- a/src/progman.c +++ b/src/progman.c @@ -156,6 +156,8 @@ destroy_prog (struct prog **pp) switch (p->type) { case TYPE_COMPONENT: + if (p->v.p.comp->flags & CF_EXPANDENV) + argv_free (p->v.p.argv); component_ref_decr (p->v.p.comp); if (p->v.p.status == status_listener && p->v.p.socket != -1) deregister_socket (p->v.p.socket); @@ -840,14 +842,31 @@ prog_start_prologue (struct prog *prog) prog->v.p.comp->limits ? prog->v.p.comp->limits : pies_limits); - if (debug_level >= 1) + if (prog->v.p.comp->flags & CF_EXPANDENV) { - int i; - struct component *comp = prog->v.p.comp; + struct wordsplit ws; + size_t argc; + ws.ws_env = (const char **) environ_ptr (prog->v.p.env); + if (wordsplit (prog->v.p.comp->command, &ws, + WRDSF_QUOTE | WRDSF_SQUEEZE_DELIMS | WRDSF_NOCMD | WRDSF_ENV)) + { + logmsg (LOG_ERR, _("%s: can't split command line: %s"), + prog_tag (prog), wordsplit_strerror (&ws)); + _exit (127); + } + wordsplit_get_words (&ws, &argc, &prog->v.p.argv); + wordsplit_free (&ws); + } + else + prog->v.p.argv = prog->v.p.comp->argv; + + if (debug_level >= 1 && prog->v.p.argv) + { + int i; logmsg_printf (LOG_DEBUG, "executing"); - for (i = 0; i < comp->argc; i++) - logmsg_printf (LOG_DEBUG, " %s", quotearg (comp->argv[i])); + for (i = 0; prog->v.p.argv[i]; i++) + logmsg_printf (LOG_DEBUG, " %s", quotearg (prog->v.p.argv[i])); logmsg_printf (LOG_DEBUG, "\n"); } } @@ -865,8 +884,8 @@ prog_execute (struct prog *prog) } execvp (prog->v.p.comp->program ? - prog->v.p.comp->program : prog->v.p.comp->argv[0], - prog->v.p.comp->argv); + prog->v.p.comp->program : prog->v.p.argv[0], + prog->v.p.argv); openlog (log_tag, LOG_PID, prog->v.p.comp->facility); syslog (LOG_CRIT, _("cannot start `%s': %s"), prog_tag (prog), strerror (errno)); |