diff --git a/api.c b/api.c index 042ea422..55b6138a 100644 --- a/api.c +++ b/api.c @@ -316,6 +316,11 @@ static void cb(uev_t *w, void *UNUSED(arg), int UNUSED(events)) result = do_handle_emit(rq.data, sizeof(rq.data)); break; + case INIT_CMD_GET_RUNLEVEL: + rq.runlevel = runlevel; + result = 0; + break; + case INIT_CMD_ACK: _d("Client failed reading ACK."); goto leave; diff --git a/finit.h b/finit.h index 512b8b11..21df1b65 100644 --- a/finit.h +++ b/finit.h @@ -53,6 +53,7 @@ #define INIT_CMD_RESTART_SVC 7 /* STOP + START service */ #define INIT_CMD_QUERY_INETD 8 #define INIT_CMD_EMIT 9 +#define INIT_CMD_GET_RUNLEVEL 10 #define INIT_CMD_NACK 254 #define INIT_CMD_ACK 255 diff --git a/helpers.c b/helpers.c index 6bae592f..4eeeed50 100644 --- a/helpers.c +++ b/helpers.c @@ -58,23 +58,6 @@ void runlevel_set(int pre, int now) endutent(); } -int runlevel_get(void) -{ - int lvl = '?'; /* Non-existing runlevel */ - struct utmp *utent; - - setutent(); - while ((utent = getutent())) { - if (utent->ut_type == RUN_LVL) { - lvl = utent->ut_pid & 0xFF; - break; - } - } - endutent(); - - return lvl - '0'; -} - /** * runlevel_string - Convert a bit encoded runlevel to .conf syntax * @levels: Bit encoded runlevels diff --git a/helpers.h b/helpers.h index 616ad77e..82cac7d5 100644 --- a/helpers.h +++ b/helpers.h @@ -62,7 +62,6 @@ do { \ #define _pe(fmt, args...) do { fprintf(stderr, "finit:%s:%s() - " fmt ". Error %d: %s\n", __FILE__, __func__, ##args, errno, strerror(errno)); } while (0) void runlevel_set (int pre, int now); -int runlevel_get (void); char *runlevel_string (int levels); int pid_alive (pid_t pid); diff --git a/initctl.c b/initctl.c index 160fe7f2..c45343a8 100644 --- a/initctl.c +++ b/initctl.c @@ -75,6 +75,42 @@ exit: return result; } +static int runlevel_get(void) +{ + struct init_request rq; + int sd, result = 255; + + rq.cmd = INIT_CMD_GET_RUNLEVEL; + rq.magic = INIT_MAGIC; + + struct sockaddr_un sun = { + .sun_family = AF_UNIX, + .sun_path = INIT_SOCKET, + }; + + sd = socket(AF_UNIX, SOCK_STREAM, 0); + if (-1 == sd) + return -1; + + if (connect(sd, (struct sockaddr*)&sun, sizeof(sun)) == -1) + goto error; + + if (write(sd, &rq, sizeof(rq)) != sizeof(rq)) + goto error; + + if (read(sd, &rq, sizeof(rq)) != sizeof(rq)) + goto error; + + result = rq.runlevel; + goto exit; +error: + perror("Failed communicating with finit"); + result = -1; +exit: + close(sd); + return result; +} + static int toggle_debug(char *UNUSED(arg)) { struct init_request rq = {