summaryrefslogtreecommitdiffabout
Side-by-side diff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--NEWS22
-rw-r--r--doc/pies.texi21
-rw-r--r--src/comp.c24
-rw-r--r--src/pies.c48
-rw-r--r--src/pies.h5
-rw-r--r--tests/Makefile.am1
-rwxr-xr-xtests/aux/respawn2
-rw-r--r--tests/respawn.at2
-rw-r--r--tests/shell.at58
-rw-r--r--tests/testsuite.at1
10 files changed, 137 insertions, 47 deletions
diff --git a/NEWS b/NEWS
index 0840055..f34a6f0 100644
--- a/NEWS
+++ b/NEWS
@@ -1,4 +1,4 @@
-GNU Pies NEWS -- history of user-visible changes. 2019-05-28
+GNU Pies NEWS -- history of user-visible changes. 2019-05-31
See the end of file for copying conditions.
Please send Pies bug reports to <bug-pies@gnu.org> or
@@ -25,8 +25,28 @@ configuration file. Such multiple components are run simultaneously,
unless required otherwise by their "prerequisites" and "dependents"
statements.
+* New component flag: shell
+
+The 'shell' flag instructs pies to run the component via "/bin/sh -c
+$command". Use it if the command should undergo variable expansion,
+contains redirections, pipes, etc. E.g.
+
+ component X {
+ flags shell;
+ command "if [ -n "$X" ]; then foo; else bar; fi"
+ }
+
* Improved cyclic dependency diagnostics
+* Fix a bug in 'env' statement
+
+Previous versions applied unnecessary word splitting if given a
+single argument. This is now fixed, so that e.g. the following
+statement is processed correctly and defines a single variable
+X to have the value "foo bar":
+
+ env "X=foo bar"
+
Version 1.3, 2016-10-01
diff --git a/doc/pies.texi b/doc/pies.texi
index 012ac88..1a798e1 100644
--- a/doc/pies.texi
+++ b/doc/pies.texi
@@ -176,7 +176,11 @@ foreground.
Upon startup, @command{pies} reads the list of components
from its configuration file, starts them, and remains in the
-background, controlling their execution.
+background, controlling their execution. Each component is
+defined by the name of the external program to be run and its
+arguments (command line). The program is normally run directly
+(via @code{exec}), but you can instruct @command{pies} to run
+it via @code{sh -c} as well.
The standard output and standard error streams of a component can be
redirected to a file or to an arbitrary @command{syslog} channel.
@@ -870,6 +874,21 @@ their standard input to be open (e.g.@: @command{pppd nodetach}).
Mark this component as @dfn{precious}. Precious components are never
disabled by @command{pies}, even if they respawn too fast.
+@kwindex shell
+@item shell
+Run command as @code{/bin/sh -c "$command"}. Use this flag if command
+contains shell-specific features, such as I/O redirections, pipes,
+variables or the like. You can change the shell program using the
+@code{program} statement. For example, to use Korn shell:
+
+@example
+component X @{
+ flags shell;
+ program "/bin/ksh";
+ command "myprog $HOME";
+@}
+@end example
+
@kwindex wait
@item wait
This flag is valid only for @samp{inetd} components. It has the same
diff --git a/src/comp.c b/src/comp.c
index 25f2657..499dfe5 100644
--- a/src/comp.c
+++ b/src/comp.c
@@ -171,6 +171,7 @@ component_free (struct component *comp)
component_unlink (comp);
free (comp->tag);
free (comp->program);
+ free (comp->command);
if (comp->argv)
{
for (i = 0; i < comp->argc; i++)
@@ -747,6 +748,29 @@ component_verify (struct component *comp, grecs_locus_t *locus)
void
component_finish (struct component *comp, grecs_locus_t *locus)
{
+ if (comp->flags & CF_SHELL)
+ {
+ 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");
+ comp->argv[1] = grecs_strdup ("-c");
+ comp->argv[2] = grecs_strdup (comp->command);
+ comp->argv[3] = NULL;
+ }
+ else
+ {
+ struct wordsplit ws;
+ if (wordsplit (comp->command, &ws, WRDSF_DEFFLAGS))
+ {
+ grecs_error (locus, 0, "wordsplit: %s",
+ wordsplit_strerror (&ws));
+ component_free (comp);
+ return;
+ }
+ wordsplit_get_words (&ws, &comp->argc, &comp->argv);
+ wordsplit_free (&ws);
+ }
+
if (comp->prereq)
comp->prereq->cmp = list_str_cmp;
if (comp->depend)
diff --git a/src/pies.c b/src/pies.c
index 98488a6..6105ae6 100644
--- a/src/pies.c
+++ b/src/pies.c
@@ -524,37 +524,6 @@ config_array_to_argv (grecs_value_t *val, grecs_locus_t *locus, size_t *pargc)
}
static int
-_cb_command (enum grecs_callback_command cmd,
- grecs_locus_t *locus,
- void *varptr, grecs_value_t *value, void *cb_data)
-{
- struct component *comp = varptr;
- struct wordsplit ws;
-
- switch (value->type)
- {
- case GRECS_TYPE_STRING:
- if (wordsplit (value->v.string, &ws, WRDSF_DEFFLAGS))
- {
- grecs_error (locus, 0, "wordsplit: %s", strerror (errno));
- return 1;
- }
- wordsplit_get_words (&ws, &comp->argc, &comp->argv);
- wordsplit_free (&ws);
- break;
-
- case GRECS_TYPE_ARRAY:
- comp->argv = config_array_to_argv (value, locus, &comp->argc);
- break;
-
- case GRECS_TYPE_LIST:
- grecs_error (locus, 0, _("unexpected list"));
- return 1;
- }
- return 0;
-}
-
-static int
_cb_umask (enum grecs_callback_command cmd,
grecs_locus_t *locus,
void *varptr, grecs_value_t *value, void *cb_data)
@@ -589,13 +558,9 @@ _cb_env (enum grecs_callback_command cmd,
switch (value->type)
{
case GRECS_TYPE_STRING:
- if (wordsplit (value->v.string, &ws, WRDSF_DEFFLAGS))
- {
- grecs_error (locus, 0, "wordsplit: %s", strerror (errno));
- return 1;
- }
- wordsplit_get_words (&ws, &argc, &argv);
- wordsplit_free (&ws);
+ argv = grecs_calloc (2, sizeof (argv[0]));
+ argv[0] = grecs_strdup (value->v.string);
+ argv[1] = NULL;
break;
case GRECS_TYPE_ARRAY:
@@ -887,6 +852,7 @@ str_to_cf (const char *string, int *flags)
{ "resolve", CF_RESOLVE },
{ "siggroup", CF_SIGGROUP },
{ "nullinput", CF_NULLINPUT },
+ { "shell", CF_SHELL },
{ NULL }
};
@@ -1014,9 +980,9 @@ struct grecs_keyword component_keywords[] = {
NULL,
N_("Command line."),
grecs_type_string, GRECS_DFLT,
- NULL, 0,
- _cb_command,
- },
+ NULL, offsetof (struct component, command),
+ NULL,
+ },
{"prerequisites",
N_("list"),
N_("List of prerequisites."),
diff --git a/src/pies.h b/src/pies.h
index 74cb346..2e544e1 100644
--- a/src/pies.h
+++ b/src/pies.h
@@ -206,10 +206,10 @@ enum pies_comp_mode
the environment */
#define CF_RESOLVE 0x080 /* Resolve IP addresses */
#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_REMOVE 0x400 /* Marked for removal */
+#define CF_REMOVE 0xf000 /* Marked for removal */
#define ISCF_TCPMUX(f) ((f) & (CF_TCPMUX | CF_TCPMUXPLUS))
@@ -226,6 +226,7 @@ struct component
enum pies_comp_mode mode;
char *tag; /* Entry tag (for diagnostics purposes) */
char *program; /* Program name */
+ char *command; /* Full command line */
size_t argc; /* Number of command line arguments */
char **argv; /* Program command line */
char **env; /* Program environment */
diff --git a/tests/Makefile.am b/tests/Makefile.am
index b404ed4..39899c8 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -52,6 +52,7 @@ TESTSUITE_AT = \
redirect.at\
ret-exec.at\
ret-notify.at\
+ shell.at\
startup.at\
shutdown.at\
version.at
diff --git a/tests/aux/respawn b/tests/aux/respawn
index 11d59f6..cd9687a 100755
--- a/tests/aux/respawn
+++ b/tests/aux/respawn
@@ -5,7 +5,7 @@
append=0
unset name
-time=10
+time=1
tag=$0
code=0
diff --git a/tests/respawn.at b/tests/respawn.at
index 4a8e3a7..6b51ca6 100644
--- a/tests/respawn.at
+++ b/tests/respawn.at
@@ -34,7 +34,7 @@ while :
do
if test -f $comp_pid_file; then
lines=`wc -l $comp_pid_file | awk '{print $1}'`
- if test "$lines" -ge 3 ; then
+ if test "$lines" -ge 2 ; then
break
fi
fi
diff --git a/tests/shell.at b/tests/shell.at
new file mode 100644
index 0000000..0ef2271
--- a/dev/null
+++ b/tests/shell.at
@@ -0,0 +1,58 @@
+# This file is part of GNU pies testsuite. -*- Autotest -*-
+# Copyright (C) 2016-2019 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 shell])
+
+AT_CHECK([
+PIES_XFAIL_CHECK
+PIES_CONTROL_INIT
+outfile=$PWD/respawn.out
+cat > pies.conf <<_EOT
+component test {
+ mode respawn;
+ flags shell;
+ command "$auxdir/respawn -tag respawn > $outfile";
+}
+_EOT
+
+pies --config-file control.conf --config-file pies.conf
+
+n=0
+while :
+do
+ if test -f $outfile; then
+ lines=`wc -l $outfile | awk '{print $1}'`
+ if test "$lines" -ge 2 ; then
+ break
+ fi
+ fi
+ sleep 1
+ n=$(($n + 1))
+ if test $n -gt 35; then
+ echo >&2 "timed out"
+ break
+ fi
+done
+
+PIES_STOP
+head -n3 $outfile
+],
+[0],
+[respawn: start
+respawn: stop
+])
+
+AT_CLEANUP
diff --git a/tests/testsuite.at b/tests/testsuite.at
index 6775ee7..28d1f9d 100644
--- a/tests/testsuite.at
+++ b/tests/testsuite.at
@@ -67,3 +67,4 @@ m4_include([ret-exec.at])
m4_include([ret-notify.at])
m4_include([startup.at])
m4_include([shutdown.at])
+m4_include([shell.at])

Return to:

Send suggestions and report system problems to the System administrator.