aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org>2020-12-01 23:11:39 +0200
committerSergey Poznyakoff <gray@gnu.org>2020-12-02 08:11:26 +0200
commitc0f4c3b99bb3364fe3f840b1ecb44af2eeba097b (patch)
tree374bc9fe1a9802d97f027b56ddf9a1f59268fb4e
parentc26297063aa2dad0fecd28791a47a8bffcfc9925 (diff)
downloadpies-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.
-rw-r--r--NEWS13
-rw-r--r--doc/pies.texi68
-rw-r--r--src/comp.c10
-rw-r--r--src/pies.c1
-rw-r--r--src/pies.h2
-rw-r--r--src/prog.h1
-rw-r--r--src/progman.c33
-rw-r--r--tests/Makefile.am1
-rw-r--r--tests/expandenv.at50
-rw-r--r--tests/testsuite.at3
10 files changed, 159 insertions, 23 deletions
diff --git a/NEWS b/NEWS
index 8f873c8..2dcc6b4 100644
--- a/NEWS
+++ b/NEWS
@@ -1,4 +1,4 @@
-GNU Pies NEWS -- history of user-visible changes. 2020-10-18
+GNU Pies NEWS -- history of user-visible changes. 2020-12-01
See the end of file for copying conditions.
Please send Pies bug reports to <bug-pies@gnu.org> or
@@ -17,6 +17,17 @@ properly.
* Fix cyclic dependency detection
+* New component flag: expandenv
+
+The "expandenv" flag instructs pies to parse the command line
+and to expand any references to environment variables within it
+as the Bourne shell would have done it. This allows for expanding
+the environment variables without the overhead of actually running
+the shell.
+
+This flag is incompatible with the "shell" flag. When both are used,
+the preference is given to "shell" and a warning message to that
+effect is issued.
Version 1.4, 2019-07-02
diff --git a/doc/pies.texi b/doc/pies.texi
index b2c9716..7a21434 100644
--- a/doc/pies.texi
+++ b/doc/pies.texi
@@ -124,6 +124,7 @@ Component Statement
* Component Privileges::
* Resources::
* Environment::
+* Early Environment Expansion::
* Actions Before Startup::
* Exit Actions::
* Output Redirectors::
@@ -836,22 +837,19 @@ any other processes.
@end table
@end deffn
-@deffn {Config: component} program @var{name}
-Full file name of the component binary. This binary will be executed
-(via @command{/bin/sh -c}) each time @command{pies} decides it needs
-to start the component.
-
-To supply command line arguments, use @code{command} statement.
-@end deffn
-
@deffn {Config: component} command @var{string}
-Command line for the program. The argument should be just as
-arguments normally are, starting with the name of the program. The
-latter may be different from the one specified to @code{program}
-statement. Its value will be available to the program as
-@code{argv[0]}.
+Command line to run. The argument is the full command line. The
+first word (in the shell sense) in @var{string} is the name of the
+program to invoke.
@end deffn
+@deffn {Config: component} program @var{name}
+Full file name of the program to run. When supplied, @command{pies}
+will execute the program @var{name} instead of the first word in the
+@code{command} statement. The latter, however, will be passed to
+the running program as @code{argv[0]}.
+@end deffn
+
@anchor{flags}
@deffn {Config: component} flags (@var{flag-list})
Define flags for this component. The @var{flag-list} is a
@@ -891,6 +889,13 @@ component X @{
@}
@end example
+@kwindex expandenv
+@item expandenv
+Expand environment variables in the @samp{command} statement prior to
+running it. When used together with the @samp{shell} flag, this flag
+produces a warning and has no effect. @xref{Early Environment
+Expansion}, for a detailed discussion.
+
@kwindex wait
@item wait
This flag is valid only for @samp{inetd} components. It has the same
@@ -940,6 +945,7 @@ substatements.
* Component Privileges::
* Resources::
* Environment::
+* Early Environment Expansion::
* Actions Before Startup::
* Exit Actions::
* Output Redirectors::
@@ -1293,6 +1299,42 @@ env @{
@end table
@end deffn
+@node Early Environment Expansion
+@subsection Early Environment Expansion
+
+ By default any references to environment variables encountered in
+the @code{command} statement are not expanded. If you need to expand
+them, there are two @dfn{flags} (@pxref{flags}) at your disposal:
+@samp{shell} and @samp{expandenv}.
+
+The @samp{shell} flag instructs @command{pies} to pass the command
+line specified by the the @code{command} statement as the argument to
+the @samp{/bin/sh -c} command (or another shell, if specified by the
+@samp{program} statement). This naturaly causes all references to the
+environment variables to be expanded, as in shell. The overhead is
+that two processes are run instead of the one: first the shell and
+second the command itself, being run as its child. This overhead
+can be eliminated by using the @code{exec} statement before the
+command, to instruct the shell to replace itself with the command
+without creating a new process.
+
+ Another way to expand environment variables in the command line is by
+specifying the @samp{expandenv} flag. This flag instructs
+@command{pies} to expand any variable references the same way that the
+Bourne shell would expand them, but without actually invoking the
+shell.
+
+ Which way to choose depends on he command. If it is a shell
+built-in, a pipe or a complex shell command, use @samp{flags shell}.
+Otherwise, you'd be better off using @samp{flags expandenv}.
+
+ When the two flags are used together, the preference is given to
+@samp{shell}, and a warning message to that effect is issued.
+
+ Also, please note, that whichever option you chose the environment
+variables available for expansion are those inherited by the parent
+shell and modified by the @code{env} statement (@pxref{Environment}).
+
@node Actions Before Startup
@subsection Actions Before Startup
diff --git a/src/comp.c b/src/comp.c
index 09f9611..2027b47 100644
--- a/src/comp.c
+++ b/src/comp.c
@@ -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))
diff --git a/src/pies.c b/src/pies.c
index d879db8..7d7f370 100644
--- a/src/pies.c
+++ b/src/pies.c
@@ -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 }
};
diff --git a/src/pies.h b/src/pies.h
index d397f88..ffccecd 100644
--- a/src/pies.h
+++ b/src/pies.h
@@ -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 */
diff --git a/src/prog.h b/src/prog.h
index aac5b17..96abeb7 100644
--- a/src/prog.h
+++ b/src/prog.h
@@ -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));
diff --git a/tests/Makefile.am b/tests/Makefile.am
index bfdc692..6a9a0d8 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -55,6 +55,7 @@ TESTSUITE_AT = \
cyclic.at\
env.at\
envop.at\
+ expandenv.at\
inet.at\
maxinst.at\
passfd.at\
diff --git a/tests/expandenv.at b/tests/expandenv.at
new file mode 100644
index 0000000..5518472
--- /dev/null
+++ b/tests/expandenv.at
@@ -0,0 +1,50 @@
+# This file is part of GNU pies testsuite. -*- Autotest -*-
+# Copyright (C) 2016-2020 Sergey Poznyakoff
+#
+# GNU pies is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU pies is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU pies. If not, see <http://www.gnu.org/licenses/>.
+
+AT_SETUP([flags expandenv])
+
+AT_CHECK([
+PIES_XFAIL_CHECK
+PIES_CONTROL_INIT
+statefile=$PWD/state
+cat > pies.conf <<EOT
+component test {
+ mode respawn;
+ flags expandenv;
+ command "\$auxdir/respawn \$statefile 3";
+ chdir "$PWD";
+ return-code 1 {
+ action disable;
+ exec "piesctl --url unix:///$PWD/pies.ctl --no-netrc shutdown";
+ }
+}
+EOT
+
+export auxdir
+export statefile
+
+set -e
+to 5 \
+ pies --foreground --stderr \
+ --config-file control.conf --config-file pies.conf --debug 4 2>errlog
+
+cat state
+],
+[0],
+[3
+])
+
+AT_CLEANUP
diff --git a/tests/testsuite.at b/tests/testsuite.at
index eab643d..277cf8b 100644
--- a/tests/testsuite.at
+++ b/tests/testsuite.at
@@ -1,4 +1,4 @@
-# This file is part of GNU pies testsuite. -*- Autotest -*-
+# This file is part of GNU pies testsuite. -*- autotest -*-
# Copyright (C) 2016-2020 Sergey Poznyakoff
#
# GNU pies is free software; you can redistribute it and/or modify
@@ -69,6 +69,7 @@ m4_include([ret-notify.at])
m4_include([startup.at])
m4_include([shutdown.at])
m4_include([shell.at])
+m4_include([expandenv.at])
m4_include([inet.at])
m4_include([maxinst.at])
m4_include([builtin.at])

Return to:

Send suggestions and report system problems to the System administrator.