aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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,2 +1,2 @@
-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.
@@ -27,4 +27,24 @@ 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"
+
diff --git a/doc/pies.texi b/doc/pies.texi
index 012ac88..1a798e1 100644
--- a/doc/pies.texi
+++ b/doc/pies.texi
@@ -178,3 +178,7 @@ foreground.
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.
@@ -872,2 +876,17 @@ 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
diff --git a/src/comp.c b/src/comp.c
index 25f2657..499dfe5 100644
--- a/src/comp.c
+++ b/src/comp.c
@@ -173,2 +173,3 @@ component_free (struct component *comp)
free (comp->program);
+ free (comp->command);
if (comp->argv)
@@ -749,2 +750,25 @@ 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)
diff --git a/src/pies.c b/src/pies.c
index 98488a6..6105ae6 100644
--- a/src/pies.c
+++ b/src/pies.c
@@ -526,33 +526,2 @@ 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,
@@ -591,9 +560,5 @@ _cb_env (enum grecs_callback_command cmd,
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;
@@ -889,2 +854,3 @@ str_to_cf (const char *string, int *flags)
{ "nullinput", CF_NULLINPUT },
+ { "shell", CF_SHELL },
{ NULL }
@@ -1016,5 +982,5 @@ struct grecs_keyword component_keywords[] = {
grecs_type_string, GRECS_DFLT,
- NULL, 0,
- _cb_command,
- },
+ NULL, offsetof (struct component, command),
+ NULL,
+ },
{"prerequisites",
diff --git a/src/pies.h b/src/pies.h
index 74cb346..2e544e1 100644
--- a/src/pies.h
+++ b/src/pies.h
@@ -208,6 +208,6 @@ 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_REMOVE 0x400 /* Marked for removal */
+#define CF_REMOVE 0xf000 /* Marked for removal */
@@ -228,2 +228,3 @@ struct component
char *program; /* Program name */
+ char *command; /* Full command line */
size_t argc; /* Number of command line arguments */
diff --git a/tests/Makefile.am b/tests/Makefile.am
index b404ed4..39899c8 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -54,2 +54,3 @@ TESTSUITE_AT = \
ret-notify.at\
+ shell.at\
startup.at\
diff --git a/tests/aux/respawn b/tests/aux/respawn
index 11d59f6..cd9687a 100755
--- a/tests/aux/respawn
+++ b/tests/aux/respawn
@@ -7,3 +7,3 @@ append=0
unset name
-time=10
+time=1
tag=$0
diff --git a/tests/respawn.at b/tests/respawn.at
index 4a8e3a7..6b51ca6 100644
--- a/tests/respawn.at
+++ b/tests/respawn.at
@@ -36,3 +36,3 @@ do
lines=`wc -l $comp_pid_file | awk '{print $1}'`
- if test "$lines" -ge 3 ; then
+ if test "$lines" -ge 2 ; then
break
diff --git a/tests/shell.at b/tests/shell.at
new file mode 100644
index 0000000..0ef2271
--- /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
@@ -69 +69,2 @@ m4_include([startup.at])
m4_include([shutdown.at])
+m4_include([shell.at])

Return to:

Send suggestions and report system problems to the System administrator.