summaryrefslogtreecommitdiffabout
path: root/src
authorSergey Poznyakoff <gray@gnu.org>2016-03-06 13:25:06 (GMT)
committer Sergey Poznyakoff <gray@gnu.org>2016-03-06 13:27:39 (GMT)
commit1a37a444eea3d238e45d01d47ac157b470f536ac (patch) (side-by-side diff)
tree5a992298b9cdc93c31ffce6a7db302670e8eb0b9 /src
parentad5bd6e401657b9cb0fed04d15cdc6feeef91e15 (diff)
downloadpies-1a37a444eea3d238e45d01d47ac157b470f536ac.tar.gz
pies-1a37a444eea3d238e45d01d47ac157b470f536ac.tar.bz2
Reimplement the telinit legacy interface.
pies -T is now fully compatible with the legacy telinit command * src/telinit.opt: New file. * src/Makefile.am: Add telinit.opt * src/cmdline.opt (-T): Remove explicit variable. Rest of command line is processed specially. * src/pies.h (telinit): Change prototype. * src/sysvinit.c (telinit): Rewrite. * src/.gitignore: Update. * doc/pies.texi: Document telinit.
Diffstat (limited to 'src') (more/less context) (ignore whitespace changes)
-rw-r--r--src/.gitignore1
-rw-r--r--src/Makefile.am8
-rw-r--r--src/cmdline.opt6
-rw-r--r--src/pies.h2
-rw-r--r--src/sysvinit.c28
-rw-r--r--src/telinit.opt89
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)
diff --git a/src/pies.h b/src/pies.h
index 4eb2aca..b0cc746 100644
--- a/src/pies.h
+++ b/src/pies.h
@@ -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
--- a/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;
+ }
+}

Return to:

Send suggestions and report system problems to the System administrator.