aboutsummaryrefslogtreecommitdiff
path: root/src/sysvinit.c
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org>2014-06-09 21:19:09 +0300
committerSergey Poznyakoff <gray@gnu.org>2014-06-09 21:26:20 +0300
commitcf4ab27d35038a7e4b1d5db119729c142b15abb7 (patch)
tree2f5df3d4fdac6aa0b7af32e87d24585327aabae2 /src/sysvinit.c
parent17c44ea5af850bd03d4eeb245bb8fb35e7d07d90 (diff)
downloadpies-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.c114
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;
}
-

Return to:

Send suggestions and report system problems to the System administrator.