diff options
author | Sergey Poznyakoff <gray@gnu.org> | 2014-06-09 21:19:09 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org> | 2014-06-09 21:26:20 +0300 |
commit | cf4ab27d35038a7e4b1d5db119729c142b15abb7 (patch) | |
tree | 2f5df3d4fdac6aa0b7af32e87d24585327aabae2 /src/sysvinit.c | |
parent | 17c44ea5af850bd03d4eeb245bb8fb35e7d07d90 (diff) | |
download | pies-cf4ab27d35038a7e4b1d5db119729c142b15abb7.tar.gz pies-cf4ab27d35038a7e4b1d5db119729c142b15abb7.tar.bz2 |
Implement ctrlaltdel and kbrequest processes.
* src/sysdep.c: New file.
* src/Makefile.am (pies_SOURCES): Add sysdep.c
* src/pies.c (ACTION_*): Move to pies.h
(sig_handler): Call sysvinit_sigtrans, return immediately
if it handles the signal.
(setsigvhan): New function.
(add_extra_sigv): New function.
(signal_setup): Rewrite.
(main): Handle ACTION_CTRLALTDEL and ACTION_KBREQUEST.
* src/pies.h (PIES_COMP_DEFAULT)
(PIES_COMP_WAIT,PIES_COMP_MASK): New defines.
(pies_action): New enum, add new actions: ACTION_CTRLALTDEL
and ACTION_KBREQUEST.
(setsigvhan, add_extra_sigv)
(sysvinit_sigtrans,sysvinit_runlevel_setup)
(sysvinit_sysdep_begin): New protos.
(sysvinit_request) <pad>: Rename to data.
* src/sysvinit.c (enablecomp): Change meaning of the data pointer.
(sysvinit_runlevel_setup): Change signature. Remove static qualifier.
All uses changed.
(sysvinit_setenv): New static.
(sysvinit_fifo_handler): Handle INIT_CMD_SETENV.
(sysvinit_sigtrans): New function.
(sysvinit_begin): Set up new signals.
Call sysvinit_sysdep_begin.
Diffstat (limited to 'src/sysvinit.c')
-rw-r--r-- | src/sysvinit.c | 114 |
1 files changed, 100 insertions, 14 deletions
diff --git a/src/sysvinit.c b/src/sysvinit.c index ca980b2..b2975d3 100644 --- a/src/sysvinit.c +++ b/src/sysvinit.c @@ -210,9 +210,18 @@ runlevel_index (int n) static int enablecomp (struct prog *prog, void *data) { - int *wait = data; + int *mask = data; + int wait; int rc; struct component *comp = prog->v.p.comp; + + if (mask) + { + wait = *mask & PIES_COMP_WAIT; + *mask &= ~PIES_COMP_WAIT; + } + else + wait = 0; switch (boot_state) { @@ -237,8 +246,7 @@ enablecomp (struct prog *prog, void *data) case pies_comp_ondemand: case pies_comp_powerfailnow: case pies_comp_kbrequest: - /* FIXME */ - return 0; + return mask && (*mask & PIES_COMP_MASK (comp->mode)); default: break; } @@ -252,7 +260,7 @@ enablecomp (struct prog *prog, void *data) { if (comp->mode == pies_comp_wait) { - *wait = 1; + *mask |= PIES_COMP_WAIT; return 1; } return 0; @@ -279,10 +287,14 @@ runlevel_setup_prog (struct prog *prog, void *data) return 0; } -static void -sysvinit_runlevel_setup (int *wait) +void +sysvinit_runlevel_setup (int mask, int *wait) { - progman_foreach (runlevel_setup_prog, wait); + if (wait) + mask |= PIES_COMP_WAIT; + progman_foreach (runlevel_setup_prog, &mask); + if (wait) + *wait = mask & PIES_COMP_WAIT; } static const char valid_runlevel_arg[] = "0123456789SsQqAaBbCcUu"; @@ -300,7 +312,9 @@ static char env_prevlevel[] = "PREVLEVEL=x"; static char env_runlevel[] = "RUNLEVEL=x"; static char env_console[] = ENVAR_CONSOLE ENVTMPL_CONSOLE; -char *sysvinit_environ_hint[] = { +#define NR_ENVHINT 32 + +char *sysvinit_environ_hint[NR_ENVHINT] = { env_prevlevel, env_runlevel, env_console, @@ -314,13 +328,14 @@ char *sysvinit_environ_hint[] = { #define ENVI_CONSOLE 2 #define ENVI_VERSION 3 #define ENVI_PATH 4 +#define ENVI_AVAIL 5 static void envsetup () { int i; - for (i = 0; sysvinit_environ_hint[i]; i++) + for (i = 0; i < ENVI_AVAIL; i++) { char *str = sysvinit_environ_hint[i]; switch (i) @@ -344,6 +359,43 @@ envsetup () } } +static void +sysvinit_setenv (char const *data, int size) +{ + char const *end; + int i, j; + + while (size) { + char const *var = data; + size_t len = strlen (var) + 1; + size -= len; + if (size < 0) + break; + data += len; + if (strncmp (var, "INIT_", 5) != 0) + continue; + len = strcspn (var, "="); + for (i = ENVI_AVAIL; i < NR_ENVHINT; i++) { + char *s = sysvinit_environ_hint[i]; + if (s) { + for (j = 0; *s && j < len; j++, s++) + if (var[j] != *s) break; + if (*s != '=' || j != len) + continue; + free (sysvinit_environ_hint[i]); + } + + if (var[len] == '=') + sysvinit_environ_hint[i] = xstrdup (var); + else + for (j = i + 1; j < NR_ENVHINT; j++, i++) + sysvinit_environ_hint[i] = + sysvinit_environ_hint[j]; + break; + } + } +} + static void create_fifo (void); static int @@ -412,7 +464,11 @@ sysvinit_fifo_handler (int fd, void *data) inittrans (); } break; - + + case INIT_CMD_SETENV: + sysvinit_setenv (buf.req.data, sizeof (buf.req.data)); + break; + /* FIXME: react on other commands */ } } @@ -502,10 +558,39 @@ set_console_dev () /* provide default */ console_device = "/dev/null"; } + +int +sysvinit_sigtrans (int sig, int *pact) +{ + switch (sig) + { + case SIGINT: + *pact = ACTION_CTRLALTDEL; + break; + case SIGWINCH: + *pact = ACTION_KBREQUEST; + break; + case SIGTERM: + case SIGQUIT: + case SIGHUP: + /* Ignore these signals. */ + *pact = ACTION_CONT; + break; + default: + return 0; + } + return 1; +} void sysvinit_begin () { + int sigv[] = { + SIGINT, + SIGPWR, + SIGWINCH, + }; + close (0); close (1); close (2); @@ -513,7 +598,9 @@ sysvinit_begin () console_stty (); setsid (); envsetup (); - sysvinit_runlevel_setup (NULL); + sysvinit_runlevel_setup (PIES_COMP_DEFAULT, NULL); + add_extra_sigv (sigv, ARRAY_SIZE (sigv)); + sysvinit_sysdep_begin (); } int @@ -579,11 +666,11 @@ inittrans () envsetup (); if (wait == 0) { - sysvinit_runlevel_setup (&wait); + sysvinit_runlevel_setup (PIES_COMP_DEFAULT, &wait); if (wait) return 1; } - sysvinit_runlevel_setup (NULL); + sysvinit_runlevel_setup (PIES_COMP_DEFAULT, NULL); wait = 0; } return trans; @@ -862,4 +949,3 @@ inittab_parse (const char *file) fclose (fp); return err; } - |