diff --git a/finit.c b/finit.c index 857f8c40..58a40927 100644 --- a/finit.c +++ b/finit.c @@ -84,6 +84,8 @@ static int client(int argc, char *argv[]) { int fd; int c; + int result = -1; + ssize_t len; struct option long_options[] = { {"debug", 0, NULL, 'd'}, {"help", 0, NULL, 'h'}, @@ -94,7 +96,7 @@ static int client(int argc, char *argv[]) .cmd = 0 }; - while ((c = getopt_long (argc, argv, "h?d", long_options, NULL)) != EOF) { + while ((c = getopt_long(argc, argv, "h?d", long_options, NULL)) != EOF) { switch(c) { case 'd': rq.cmd = INIT_CMD_DEBUG; @@ -123,15 +125,22 @@ static int client(int argc, char *argv[]) return 1; } - fd = open(FINIT_FIFO, O_WRONLY); + fd = open(FINIT_FIFO, O_RDWR); if (-1 == fd) { perror("Failed opening " FINIT_FIFO); return 1; } - write(fd, &rq, sizeof(rq)); + + len = write(fd, &rq, sizeof(rq)); + if (len == sizeof(rq)) { + len = read(fd, &rq, sizeof(rq)); + if (len == sizeof(rq) && rq.cmd == INIT_CMD_ACK) + result = 0; + } + close(fd); - return 0; + return result; } static void banner(void) diff --git a/finit.h b/finit.h index 3924f4f9..2dbf6c0a 100644 --- a/finit.h +++ b/finit.h @@ -76,6 +76,7 @@ #define INIT_MAGIC 0x03091969 #define INIT_CMD_RUNLVL 1 #define INIT_CMD_DEBUG 2 +#define INIT_CMD_ACK 255 struct init_request { int magic; /* Magic number */ diff --git a/plugins/initctl.c b/plugins/initctl.c index 32ae1db8..f5d5bfd1 100644 --- a/plugins/initctl.c +++ b/plugins/initctl.c @@ -45,7 +45,7 @@ static plugin_t plugin = { static void fifo_open(void) { - plugin.io.fd = open(FINIT_FIFO, O_RDONLY | O_NONBLOCK | O_CLOEXEC); + plugin.io.fd = open(FINIT_FIFO, O_RDWR | O_NONBLOCK | O_CLOEXEC); if (-1 == plugin.io.fd) { _e("Failed opening %s FIFO, error %d: %s", FINIT_FIFO, errno, strerror(errno)); return; @@ -85,7 +85,8 @@ static void parse(void *UNUSED(arg), int fd, int UNUSED(events)) } _d("Magic OK ..."); - if (rq.cmd == INIT_CMD_RUNLVL) { + switch (rq.cmd) { + case INIT_CMD_RUNLVL: switch (rq.runlevel) { case '0': _d("Halting system (SIGUSR2)"); @@ -113,13 +114,30 @@ static void parse(void *UNUSED(arg), int fd, int UNUSED(events)) _d("Unsupported runlevel: %d", rq.runlevel); break; } - } else if (rq.cmd == INIT_CMD_DEBUG) { + break; + + case INIT_CMD_DEBUG: debug = !debug; - } else { + break; + + case INIT_CMD_ACK: + _d("Client failed reading ACK."); + goto leave; + + default: _d("Unsupported cmd: %d", rq.cmd); + break; } + + rq.cmd = INIT_CMD_ACK; + len = write(fd, &rq, sizeof(rq)); + if (len != sizeof(rq)) + _d("Failed sending ACK back to client."); + else + sleep(1); /* Give client time to read FIFO */ } +leave: close(fd); fifo_open(); }