mirror of
https://github.com/troglobit/finit.git
synced 2026-10-02 14:02:52 +07:00
Merge pull request #26 from RFCreations/master
Some fixes, and add logging Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This commit is contained in:
@@ -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));
|
result = do_handle_emit(rq.data, sizeof(rq.data));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case INIT_CMD_GET_RUNLEVEL:
|
||||||
|
rq.runlevel = runlevel;
|
||||||
|
result = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
case INIT_CMD_ACK:
|
case INIT_CMD_ACK:
|
||||||
_d("Client failed reading ACK.");
|
_d("Client failed reading ACK.");
|
||||||
goto leave;
|
goto leave;
|
||||||
|
|||||||
@@ -53,6 +53,7 @@
|
|||||||
#define INIT_CMD_RESTART_SVC 7 /* STOP + START service */
|
#define INIT_CMD_RESTART_SVC 7 /* STOP + START service */
|
||||||
#define INIT_CMD_QUERY_INETD 8
|
#define INIT_CMD_QUERY_INETD 8
|
||||||
#define INIT_CMD_EMIT 9
|
#define INIT_CMD_EMIT 9
|
||||||
|
#define INIT_CMD_GET_RUNLEVEL 10
|
||||||
#define INIT_CMD_NACK 254
|
#define INIT_CMD_NACK 254
|
||||||
#define INIT_CMD_ACK 255
|
#define INIT_CMD_ACK 255
|
||||||
|
|
||||||
|
|||||||
@@ -58,23 +58,6 @@ void runlevel_set(int pre, int now)
|
|||||||
endutent();
|
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
|
* runlevel_string - Convert a bit encoded runlevel to .conf syntax
|
||||||
* @levels: Bit encoded runlevels
|
* @levels: Bit encoded runlevels
|
||||||
|
|||||||
@@ -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)
|
#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);
|
void runlevel_set (int pre, int now);
|
||||||
int runlevel_get (void);
|
|
||||||
char *runlevel_string (int levels);
|
char *runlevel_string (int levels);
|
||||||
|
|
||||||
int pid_alive (pid_t pid);
|
int pid_alive (pid_t pid);
|
||||||
|
|||||||
@@ -167,7 +167,7 @@ static void socket_cb(uev_t *UNUSED(w), void *arg, int UNUSED(events))
|
|||||||
memcpy(task->args, svc->args, sizeof(task->args));
|
memcpy(task->args, svc->args, sizeof(task->args));
|
||||||
snprintf(task->desc, sizeof(task->desc), "%s Connection", svc->desc);
|
snprintf(task->desc, sizeof(task->desc), "%s Connection", svc->desc);
|
||||||
|
|
||||||
task->stdin = stdin;
|
task->stdin_fd = stdin;
|
||||||
service_step(task);
|
service_step(task);
|
||||||
|
|
||||||
if (!svc->inetd.forking) {
|
if (!svc->inetd.forking) {
|
||||||
|
|||||||
@@ -75,6 +75,42 @@ exit:
|
|||||||
return result;
|
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))
|
static int toggle_debug(char *UNUSED(arg))
|
||||||
{
|
{
|
||||||
struct init_request rq = {
|
struct init_request rq = {
|
||||||
|
|||||||
@@ -162,7 +162,6 @@ static int service_start(svc_t *svc)
|
|||||||
sigprocmask(SIG_BLOCK, &nmask, &omask);
|
sigprocmask(SIG_BLOCK, &nmask, &omask);
|
||||||
|
|
||||||
pid = fork();
|
pid = fork();
|
||||||
sigprocmask(SIG_SETMASK, &omask, NULL);
|
|
||||||
if (pid == 0) {
|
if (pid == 0) {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
int status;
|
int status;
|
||||||
@@ -171,17 +170,8 @@ static int service_start(svc_t *svc)
|
|||||||
#else
|
#else
|
||||||
int uid = getuser(svc->username);
|
int uid = getuser(svc->username);
|
||||||
#endif
|
#endif
|
||||||
struct sigaction sa;
|
|
||||||
char *args[MAX_NUM_SVC_ARGS];
|
char *args[MAX_NUM_SVC_ARGS];
|
||||||
|
|
||||||
sigemptyset(&nmask);
|
|
||||||
sigaddset(&nmask, SIGCHLD);
|
|
||||||
sigprocmask(SIG_UNBLOCK, &nmask, NULL);
|
|
||||||
|
|
||||||
/* Reset signal handlers that were set by the parent process */
|
|
||||||
for (i = 1; i < NSIG; i++)
|
|
||||||
DFLSIG(sa, i, 0);
|
|
||||||
|
|
||||||
/* Set desired user */
|
/* Set desired user */
|
||||||
if (uid >= 0) {
|
if (uid >= 0) {
|
||||||
setuid(uid);
|
setuid(uid);
|
||||||
@@ -199,13 +189,34 @@ static int service_start(svc_t *svc)
|
|||||||
/* Redirect inetd socket to stdin for connection */
|
/* Redirect inetd socket to stdin for connection */
|
||||||
#ifndef INETD_DISABLED
|
#ifndef INETD_DISABLED
|
||||||
if (svc_is_inetd_conn(svc)) {
|
if (svc_is_inetd_conn(svc)) {
|
||||||
dup2(svc->stdin, STDIN_FILENO);
|
dup2(svc->stdin_fd, STDIN_FILENO);
|
||||||
close(svc->stdin);
|
close(svc->stdin_fd);
|
||||||
dup2(STDIN_FILENO, STDOUT_FILENO);
|
dup2(STDIN_FILENO, STDOUT_FILENO);
|
||||||
dup2(STDIN_FILENO, STDERR_FILENO);
|
dup2(STDIN_FILENO, STDERR_FILENO);
|
||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
if (debug) {
|
if (svc->log) {
|
||||||
|
/* Open PTY to connect to logger (A pty isn't buffered like a pipe, and it eats newlines so they aren't logged) */
|
||||||
|
int fd = posix_openpt(O_RDWR);
|
||||||
|
/* SIGCHLD is still blocked for grantpt() and fork() */
|
||||||
|
sigprocmask(SIG_BLOCK, &nmask, NULL);
|
||||||
|
if (fd >= 0 && grantpt(fd) == 0 && unlockpt(fd) == 0) {
|
||||||
|
pid = fork();
|
||||||
|
if (pid == 0) {
|
||||||
|
int fds = open(ptsname(fd), O_RDONLY);
|
||||||
|
close(fd);
|
||||||
|
dup2(fds, STDIN_FILENO);
|
||||||
|
|
||||||
|
/* Reset signals */
|
||||||
|
sig_unblock();
|
||||||
|
|
||||||
|
exit(execlp("logger", "logger", "-t", strlen(svc->desc) > 0 ? svc->desc : svc->cmd, (char*)NULL));
|
||||||
|
}
|
||||||
|
dup2(fd, STDOUT_FILENO);
|
||||||
|
dup2(fd, STDERR_FILENO);
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
|
} else if (debug) {
|
||||||
int fd;
|
int fd;
|
||||||
char buf[CMD_SIZE] = "";
|
char buf[CMD_SIZE] = "";
|
||||||
|
|
||||||
@@ -240,15 +251,19 @@ static int service_start(svc_t *svc)
|
|||||||
close(STDOUT_FILENO);
|
close(STDOUT_FILENO);
|
||||||
close(STDERR_FILENO);
|
close(STDERR_FILENO);
|
||||||
}
|
}
|
||||||
}
|
} else
|
||||||
#endif
|
#endif
|
||||||
|
if (svc->log) {
|
||||||
|
waitpid(pid, NULL, 0);
|
||||||
|
}
|
||||||
exit(status);
|
exit(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
svc->pid = pid;
|
svc->pid = pid;
|
||||||
|
|
||||||
#ifndef INETD_DISABLED
|
#ifndef INETD_DISABLED
|
||||||
if (svc_is_inetd_conn(svc) && svc->inetd.type == SOCK_STREAM)
|
if (svc_is_inetd_conn(svc) && svc->inetd.type == SOCK_STREAM)
|
||||||
close(svc->stdin);
|
close(svc->stdin_fd);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
plugin_run_hook(HOOK_SVC_START, (void *)(uintptr_t)pid);
|
plugin_run_hook(HOOK_SVC_START, (void *)(uintptr_t)pid);
|
||||||
@@ -257,6 +272,8 @@ static int service_start(svc_t *svc)
|
|||||||
result = WEXITSTATUS(complete(svc->cmd, pid));
|
result = WEXITSTATUS(complete(svc->cmd, pid));
|
||||||
svc->pid = 0;
|
svc->pid = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sigprocmask(SIG_SETMASK, &omask, NULL);
|
||||||
|
|
||||||
if (!silent)
|
if (!silent)
|
||||||
print_result(result);
|
print_result(result);
|
||||||
@@ -542,6 +559,7 @@ int service_register(int type, char *line, time_t mtime, char *username)
|
|||||||
#ifndef INETD_DISABLED
|
#ifndef INETD_DISABLED
|
||||||
int forking = 0;
|
int forking = 0;
|
||||||
#endif
|
#endif
|
||||||
|
int log = 0;
|
||||||
char *service = NULL, *proto = NULL, *ifaces = NULL;
|
char *service = NULL, *proto = NULL, *ifaces = NULL;
|
||||||
char *cmd, *desc, *runlevels = NULL, *cond = NULL;
|
char *cmd, *desc, *runlevels = NULL, *cond = NULL;
|
||||||
svc_t *svc;
|
svc_t *svc;
|
||||||
@@ -580,6 +598,8 @@ int service_register(int type, char *line, time_t mtime, char *username)
|
|||||||
#endif
|
#endif
|
||||||
else if (cmd[0] != '/' && strchr(cmd, '/'))
|
else if (cmd[0] != '/' && strchr(cmd, '/'))
|
||||||
service = cmd; /* inetd service/proto */
|
service = cmd; /* inetd service/proto */
|
||||||
|
else if (!strncasecmp(cmd, "log", 3))
|
||||||
|
log = 1;
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -640,6 +660,7 @@ int service_register(int type, char *line, time_t mtime, char *username)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
svc->log = log;
|
||||||
if (desc)
|
if (desc)
|
||||||
strlcpy(svc->desc, desc + 3, sizeof(svc->desc));
|
strlcpy(svc->desc, desc + 3, sizeof(svc->desc));
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user