diff options
author | Sergey Poznyakoff <gray@gnu.org> | 2016-03-06 15:25:06 +0200 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org> | 2016-03-06 15:27:39 +0200 |
commit | 1a37a444eea3d238e45d01d47ac157b470f536ac (patch) | |
tree | 5a992298b9cdc93c31ffce6a7db302670e8eb0b9 /src | |
parent | ad5bd6e401657b9cb0fed04d15cdc6feeef91e15 (diff) | |
download | pies-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')
-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 | |||
8 | pies.rc | 8 | pies.rc |
9 | piesctl | 9 | piesctl |
10 | piesctl-cl.h | 10 | piesctl-cl.h |
11 | 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 = \ | |||
41 | meta1parse.h\ | 41 | meta1parse.h\ |
42 | pies.h\ | 42 | pies.h\ |
43 | prog.h\ | 43 | prog.h\ |
44 | piesctl-cl.h | 44 | piesctl-cl.h\ |
45 | telinit.h | ||
45 | 46 | ||
46 | BUILT_SOURCES=cmdline.h piesctl-cl.h | 47 | BUILT_SOURCES=cmdline.h piesctl-cl.h telinit.h |
47 | 48 | ||
48 | incdir=$(pkgdatadir)/$(VERSION)/include | 49 | incdir=$(pkgdatadir)/$(VERSION)/include |
49 | inc_DATA = pp-setup | 50 | inc_DATA = pp-setup |
50 | EXTRA_DIST = cmdline.opt piesctl-cl.opt pp-setup inetd.in | 51 | EXTRA_DIST = cmdline.opt piesctl-cl.opt telinit.opt pp-setup inetd.in |
51 | 52 | ||
52 | SUFFIXES=.opt .c .h | 53 | SUFFIXES=.opt .c .h |
53 | .opt.h: | 54 | .opt.h: |
@@ -55,6 +56,7 @@ SUFFIXES=.opt .c .h | |||
55 | 56 | ||
56 | cmdline.h: cmdline.opt | 57 | cmdline.h: cmdline.opt |
57 | piesctl-cl.h: piesctl-cl.opt | 58 | piesctl-cl.h: piesctl-cl.opt |
59 | telinit.h: telinit.opt | ||
58 | 60 | ||
59 | pies_LDADD = \ | 61 | pies_LDADD = \ |
60 | ../ident/libident.a\ | 62 | ../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 | |||
112 | lint_mode = 1; | 112 | lint_mode = 1; |
113 | END | 113 | END |
114 | 114 | ||
115 | OPTION(telinit,T,RUNLEVEL, | 115 | OPTION(telinit,T,, |
116 | [<emulate telinit command>]) | 116 | [<telinit command: run "pies -T --help" for help>]) |
117 | BEGIN | 117 | BEGIN |
118 | log_to_stderr_only = 1; | 118 | log_to_stderr_only = 1; |
119 | exit (telinit (optarg)); | 119 | exit (telinit (argc - (optind - 1), argv + (optind - 1))); |
120 | END | 120 | END |
121 | 121 | ||
122 | GROUP(Preprocessor) | 122 | GROUP(Preprocessor) |
@@ -535,7 +535,7 @@ void sysvinit_begin (void); | |||
535 | int is_comp_wait (struct component *comp); | 535 | int is_comp_wait (struct component *comp); |
536 | int is_valid_runlevel (int c); | 536 | int is_valid_runlevel (int c); |
537 | int console_open (int mode); | 537 | int console_open (int mode); |
538 | int telinit (const char *arg); | 538 | int telinit (int argc, char **argv); |
539 | int inittab_parse (const char *file); | 539 | int inittab_parse (const char *file); |
540 | int sysvinit_sigtrans (int sig, int *pact); | 540 | int sysvinit_sigtrans (int sig, int *pact); |
541 | void sysvinit_runlevel_setup (int mask); | 541 | 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) | |||
529 | { | 529 | { |
530 | debug (1, ("INITREQ: cmd=%d, runlevel=%d, sleeptime=%d", | 530 | debug (1, ("INITREQ: cmd=%d, runlevel=%d, sleeptime=%d", |
531 | buf.req.cmd, buf.req.runlevel, buf.req.sleeptime)); | 531 | buf.req.cmd, buf.req.runlevel, buf.req.sleeptime)); |
532 | if (buf.req.sleeptime > 0) | ||
533 | shutdown_timeout = buf.req.sleeptime; | ||
532 | switch (buf.req.cmd) | 534 | switch (buf.req.cmd) |
533 | { | 535 | { |
534 | case INIT_CMD_RUNLVL: | 536 | case INIT_CMD_RUNLVL: |
@@ -907,25 +909,19 @@ is_comp_wait (struct component *comp) | |||
907 | } | 909 | } |
908 | return 0; | 910 | return 0; |
909 | } | 911 | } |
910 | 912 | ||
913 | #include "telinit.h" | ||
914 | |||
911 | int | 915 | int |
912 | telinit (const char *arg) | 916 | telinit (int argc, char **argv) |
913 | { | 917 | { |
914 | int fd; | 918 | int fd; |
915 | struct sysvinit_request req; | 919 | struct sysvinit_request req; |
916 | 920 | ||
917 | if (arg[1] || !is_valid_runlevel (*arg)) | ||
918 | { | ||
919 | logmsg (LOG_CRIT, "invalid argument"); | ||
920 | exit (EX_USAGE); | ||
921 | } | ||
922 | memset (&req, 0, sizeof (req)); | 921 | memset (&req, 0, sizeof (req)); |
923 | req.magic = INIT_MAGIC; | 922 | req.magic = INIT_MAGIC; |
924 | req.cmd = INIT_CMD_RUNLVL; | 923 | |
925 | req.runlevel = *arg; | 924 | telinit_parser (&req, argc, argv); |
926 | #if 0 | ||
927 | req.sleeptime = sltime; | ||
928 | #endif | ||
929 | 925 | ||
930 | signal (SIGALRM, SIG_DFL); | 926 | signal (SIGALRM, SIG_DFL); |
931 | alarm (5); | 927 | alarm (5); |
@@ -933,17 +929,17 @@ telinit (const char *arg) | |||
933 | if (fd < 0) | 929 | if (fd < 0) |
934 | { | 930 | { |
935 | logmsg (LOG_ERR, _("cannot open %s: %s"), init_fifo, strerror (errno)); | 931 | logmsg (LOG_ERR, _("cannot open %s: %s"), init_fifo, strerror (errno)); |
936 | exit (EX_UNAVAILABLE); | 932 | return EX_UNAVAILABLE; |
937 | } | 933 | } |
938 | if (write (fd, &req, sizeof (req)) != sizeof (req)) | 934 | if (write (fd, &req, sizeof (req)) != sizeof (req)) |
939 | { | 935 | { |
940 | logmsg (LOG_ERR, _("error writing to %s: %s"), | 936 | logmsg (LOG_ERR, _("error writing to %s: %s"), |
941 | init_fifo, strerror (errno)); | 937 | init_fifo, strerror (errno)); |
942 | exit (EX_UNAVAILABLE); | 938 | return EX_UNAVAILABLE; |
943 | } | 939 | } |
944 | alarm (0); | 940 | alarm (0); |
945 | close (fd); | 941 | close (fd); |
946 | exit (0); | 942 | return 0; |
947 | } | 943 | } |
948 | 944 | ||
949 | static char * | 945 | 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 @@ | |||
1 | /* This file is part of GNU Pies. -*- c -*- | ||
2 | Copyright (C) 2016 Sergey Poznyakoff | ||
3 | |||
4 | GNU Pies is free software; you can redistribute it and/or modify | ||
5 | it under the terms of the GNU General Public License as published by | ||
6 | the Free Software Foundation; either version 3, or (at your option) | ||
7 | any later version. | ||
8 | |||
9 | GNU Pies is distributed in the hope that it will be useful, | ||
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | GNU General Public License for more details. | ||
13 | |||
14 | You should have received a copy of the GNU General Public License | ||
15 | along with GNU Pies. If not, see <http://www.gnu.org/licenses/>. */ | ||
16 | |||
17 | OPTIONS_COMMAND_BEGIN("pies", | ||
18 | [<>], | ||
19 | [<send command to init process via the legacy interface>], | ||
20 | [<[RUNLEVEL]>], | ||
21 | [<gnu>], | ||
22 | [<noversion>]) | ||
23 | |||
24 | OPTION(timeout,t,[<SECONDS>], | ||
25 | [<set interval between sending TERM and KILL signals>]) | ||
26 | BEGIN | ||
27 | char *p; | ||
28 | errno = 0; | ||
29 | shutdown_timeout = strtoul (optarg, &p, 0); | ||
30 | if (*p || errno) | ||
31 | { | ||
32 | logmsg (LOG_ERR, _("invalid number: %s"), optarg); | ||
33 | exit (EX_USAGE); | ||
34 | } | ||
35 | END | ||
36 | |||
37 | OPTION(environment,e,[<VAR=[VAL]>],[<change environment>]) | ||
38 | BEGIN | ||
39 | size_t len = strlen (optarg); | ||
40 | if (envsize + len + 2 > sizeof(req->data)) | ||
41 | { | ||
42 | logmsg (LOG_ERR, _("-e argument too long")); | ||
43 | exit (EX_USAGE); | ||
44 | } | ||
45 | memcpy (req->data + envsize, optarg, len); | ||
46 | envsize += len; | ||
47 | req->data[envsize++] = 0; | ||
48 | END | ||
49 | |||
50 | OPTIONS_END | ||
51 | |||
52 | static void | ||
53 | telinit_parser (struct sysvinit_request *req, int argc, char *argv[]) | ||
54 | { | ||
55 | int i; | ||
56 | char *cmds[] = { "-T", NULL }; | ||
57 | size_t envsize = 0; | ||
58 | |||
59 | proginfo.subcmd = cmds; | ||
60 | GETOPT(argc, argv, i); | ||
61 | argc -= i; | ||
62 | argv += i; | ||
63 | if (envsize) | ||
64 | { | ||
65 | req->data[envsize++] = 0; | ||
66 | req->cmd = INIT_CMD_SETENV; | ||
67 | if (argc) | ||
68 | { | ||
69 | logmsg (LOG_ERR, _("too many arguments")); | ||
70 | exit (EX_USAGE); | ||
71 | } | ||
72 | } | ||
73 | else | ||
74 | { | ||
75 | if (argc != 1) | ||
76 | { | ||
77 | logmsg (LOG_ERR, _("bad number of arguments")); | ||
78 | exit (EX_USAGE); | ||
79 | } | ||
80 | if (argv[0][1] || !is_valid_runlevel (argv[0][0])) | ||
81 | { | ||
82 | logmsg (LOG_ERR, _("invalid runlevel: %s"), argv[0]); | ||
83 | exit (EX_USAGE); | ||
84 | } | ||
85 | req->cmd = INIT_CMD_RUNLVL; | ||
86 | req->runlevel = argv[0][0]; | ||