diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/.gitignore | 1 | ||||
-rw-r--r-- | src/Makefile.am | 8 | ||||
-rw-r--r-- | src/cmdline.opt | 6 | ||||
-rw-r--r-- | src/pies.h | 2 | ||||
-rw-r--r-- | src/sysvinit.c | 28 | ||||
-rw-r--r-- | src/telinit.opt | 89 |
6 files changed, 111 insertions, 23 deletions
diff --git a/src/.gitignore b/src/.gitignore index a83b9ab..3bf90ef 100644 --- a/src/.gitignore +++ b/src/.gitignore @@ -8,3 +8,4 @@ pies pies.rc piesctl piesctl-cl.h +telinit.h diff --git a/src/Makefile.am b/src/Makefile.am index 6515804..b0e9b6f 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -41,13 +41,14 @@ noinst_HEADERS = \ meta1parse.h\ pies.h\ prog.h\ - piesctl-cl.h + piesctl-cl.h\ + telinit.h -BUILT_SOURCES=cmdline.h piesctl-cl.h +BUILT_SOURCES=cmdline.h piesctl-cl.h telinit.h incdir=$(pkgdatadir)/$(VERSION)/include inc_DATA = pp-setup -EXTRA_DIST = cmdline.opt piesctl-cl.opt pp-setup inetd.in +EXTRA_DIST = cmdline.opt piesctl-cl.opt telinit.opt pp-setup inetd.in SUFFIXES=.opt .c .h .opt.h: @@ -55,6 +56,7 @@ SUFFIXES=.opt .c .h cmdline.h: cmdline.opt piesctl-cl.h: piesctl-cl.opt +telinit.h: telinit.opt pies_LDADD = \ ../ident/libident.a\ diff --git a/src/cmdline.opt b/src/cmdline.opt index 7d6f7d4..d8bd02f 100644 --- a/src/cmdline.opt +++ b/src/cmdline.opt @@ -112,11 +112,11 @@ BEGIN lint_mode = 1; END -OPTION(telinit,T,RUNLEVEL, - [<emulate telinit command>]) +OPTION(telinit,T,, + [<telinit command: run "pies -T --help" for help>]) BEGIN log_to_stderr_only = 1; - exit (telinit (optarg)); + exit (telinit (argc - (optind - 1), argv + (optind - 1))); END GROUP(Preprocessor) @@ -535,7 +535,7 @@ void sysvinit_begin (void); int is_comp_wait (struct component *comp); int is_valid_runlevel (int c); int console_open (int mode); -int telinit (const char *arg); +int telinit (int argc, char **argv); int inittab_parse (const char *file); int sysvinit_sigtrans (int sig, int *pact); void sysvinit_runlevel_setup (int mask); diff --git a/src/sysvinit.c b/src/sysvinit.c index a150058..9043619 100644 --- a/src/sysvinit.c +++ b/src/sysvinit.c @@ -529,6 +529,8 @@ sysvinit_fifo_handler (int fd, void *data) { debug (1, ("INITREQ: cmd=%d, runlevel=%d, sleeptime=%d", buf.req.cmd, buf.req.runlevel, buf.req.sleeptime)); + if (buf.req.sleeptime > 0) + shutdown_timeout = buf.req.sleeptime; switch (buf.req.cmd) { case INIT_CMD_RUNLVL: @@ -907,25 +909,19 @@ is_comp_wait (struct component *comp) } return 0; } - + +#include "telinit.h" + int -telinit (const char *arg) +telinit (int argc, char **argv) { int fd; struct sysvinit_request req; - - if (arg[1] || !is_valid_runlevel (*arg)) - { - logmsg (LOG_CRIT, "invalid argument"); - exit (EX_USAGE); - } + memset (&req, 0, sizeof (req)); req.magic = INIT_MAGIC; - req.cmd = INIT_CMD_RUNLVL; - req.runlevel = *arg; -#if 0 - req.sleeptime = sltime; -#endif + + telinit_parser (&req, argc, argv); signal (SIGALRM, SIG_DFL); alarm (5); @@ -933,17 +929,17 @@ telinit (const char *arg) if (fd < 0) { logmsg (LOG_ERR, _("cannot open %s: %s"), init_fifo, strerror (errno)); - exit (EX_UNAVAILABLE); + return EX_UNAVAILABLE; } if (write (fd, &req, sizeof (req)) != sizeof (req)) { logmsg (LOG_ERR, _("error writing to %s: %s"), init_fifo, strerror (errno)); - exit (EX_UNAVAILABLE); + return EX_UNAVAILABLE; } alarm (0); close (fd); - exit (0); + return 0; } static char * diff --git a/src/telinit.opt b/src/telinit.opt new file mode 100644 index 0000000..f052a53 --- /dev/null +++ b/src/telinit.opt @@ -0,0 +1,89 @@ +/* This file is part of GNU Pies. -*- c -*- + Copyright (C) 2016 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/>. */ + +OPTIONS_COMMAND_BEGIN("pies", + [<>], + [<send command to init process via the legacy interface>], + [<[RUNLEVEL]>], + [<gnu>], + [<noversion>]) + +OPTION(timeout,t,[<SECONDS>], + [<set interval between sending TERM and KILL signals>]) +BEGIN + char *p; + errno = 0; + shutdown_timeout = strtoul (optarg, &p, 0); + if (*p || errno) + { + logmsg (LOG_ERR, _("invalid number: %s"), optarg); + exit (EX_USAGE); + } +END + +OPTION(environment,e,[<VAR=[VAL]>],[<change environment>]) +BEGIN + size_t len = strlen (optarg); + if (envsize + len + 2 > sizeof(req->data)) + { + logmsg (LOG_ERR, _("-e argument too long")); + exit (EX_USAGE); + } + memcpy (req->data + envsize, optarg, len); + envsize += len; + req->data[envsize++] = 0; +END + +OPTIONS_END + +static void +telinit_parser (struct sysvinit_request *req, int argc, char *argv[]) +{ + int i; + char *cmds[] = { "-T", NULL }; + size_t envsize = 0; + + proginfo.subcmd = cmds; + GETOPT(argc, argv, i); + argc -= i; + argv += i; + if (envsize) + { + req->data[envsize++] = 0; + req->cmd = INIT_CMD_SETENV; + if (argc) + { + logmsg (LOG_ERR, _("too many arguments")); + exit (EX_USAGE); + } + } + else + { + if (argc != 1) + { + logmsg (LOG_ERR, _("bad number of arguments")); + exit (EX_USAGE); + } + if (argv[0][1] || !is_valid_runlevel (argv[0][0])) + { + logmsg (LOG_ERR, _("invalid runlevel: %s"), argv[0]); + exit (EX_USAGE); + } + req->cmd = INIT_CMD_RUNLVL; + req->runlevel = argv[0][0]; + req->sleeptime = shutdown_timeout; + } +} |