mirror of
https://github.com/troglobit/finit.git
synced 2026-10-01 05:22:48 +07:00
Make the 'init <CMD | RUNLEVEL>' commands synchronous.
When a user changes runlevel, or wants to reload the config, we want the command to return only when the operation has completed. For instance, rolling in a new system configuration in runlevel 1 requires that we are sure we've actually entered that runlevel before rolling it in. Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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 */
|
||||
|
||||
+22
-4
@@ -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();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user