@@ -4,3 +4,4 @@ alix-usv | |||
alix-usvd | |||
alix-usvd.sock | |||
alix-usvd.log | |||
alix-usvd.pid |
@@ -6,7 +6,7 @@ CFLAGS = -Wall -O2 -MD -MP -MF $(*F).d | |||
# ------ | |||
SRC1 := alix-usv.c logging.c unixsocket.c | |||
SRC2 := alix-usvd.c configfile.c event.c logging.c unixsocket.c | |||
SRC2 := alix-usvd.c configfile.c event.c logging.c pidfile.c unixsocket.c | |||
all: $(TARGET1) $(TARGET2) | |||
@@ -23,6 +23,6 @@ $(TARGET2): $(SRC2:.c=.o) | |||
@$(CC) -c $(CFLAGS) $< -o $@ | |||
clean: | |||
rm -rf $(TARGET1) $(TARGET2) *.o *.d *.log *.sock | |||
rm -rf $(TARGET1) $(TARGET2) *.o *.d *.log *.sock *.pid | |||
-include $(shell find . -name \*.d 2> /dev/null) |
@@ -34,6 +34,7 @@ | |||
#include "configfile.h" | |||
#include "event.h" | |||
#include "logging.h" | |||
#include "pidfile.h" | |||
#include "unixsocket.h" | |||
/* eeprom parameters / thresholds & defaults */ | |||
@@ -41,6 +42,7 @@ | |||
#define DEFAULT_CONFIG "alix-usvd.conf" | |||
#define DEFAULT_LOGFILE "alix-usvd.log" | |||
#define DEFAULT_PIDFILE "alix-usvd.pid" | |||
#define DEFAULT_SOCKET "alix-usvd.sock" | |||
enum { | |||
@@ -370,7 +372,12 @@ int main(int argc, char *argv[]) | |||
exit(1); | |||
if (debug == 0) { | |||
/* TODO: check PID-file */ | |||
/* check pidfile */ | |||
const char *pidfile = config_get_string("global", "pidfile", DEFAULT_PIDFILE); | |||
if (pidfile_check(pidfile, 1) != 0) { | |||
log_print(LOG_ERROR, "alix-usvd already running"); | |||
exit(1); | |||
} | |||
/* start logging */ | |||
const char *logfile = config_get_string("global", "logfile", DEFAULT_LOGFILE); | |||
@@ -380,7 +387,11 @@ int main(int argc, char *argv[]) | |||
/* zum daemon mutieren */ | |||
daemon(-1, 0); | |||
/* TODO: write PID-file */ | |||
/* create pidfile */ | |||
if (pidfile_create(pidfile) < 0) { | |||
log_print(LOG_ERROR, "failed to create pidfile %s", pidfile); | |||
exit(1); | |||
} | |||
} | |||
log_print(LOG_INFO, "alix-usvd started (pid: %d)", getpid()); |
@@ -0,0 +1,71 @@ | |||
#include <stdio.h> | |||
#include <stdlib.h> | |||
#include <unistd.h> | |||
#include <sys/types.h> | |||
#include <sys/stat.h> | |||
#include <fcntl.h> | |||
#include <errno.h> | |||
#include <signal.h> | |||
#include "logging.h" | |||
int pidfile_create(const char *filename) | |||
{ | |||
int fd = open(filename, O_CREAT | O_EXCL | O_RDWR, 0644); | |||
if (fd < 0) | |||
return -1; | |||
char buf[8]; | |||
int len = snprintf(buf, sizeof(buf), "%d", getpid()); | |||
write(fd, buf, len); | |||
close(fd); | |||
return 0; | |||
} | |||
int pidfile_remove(const char *filename) | |||
{ | |||
return unlink(filename); | |||
} | |||
pid_t pidfile_check(const char *filename, int remove_stale) | |||
{ | |||
int fd = open(filename, O_RDWR); | |||
if (fd < 0) { | |||
if (errno == ENOENT) { | |||
errno = 0; | |||
return 0; | |||
} | |||
return -1; | |||
} | |||
char buf[9]; | |||
int len = read(fd, buf, sizeof(buf) -1); | |||
buf[len] = '\0'; | |||
char *tmp; | |||
pid_t pid = strtol(buf, &tmp, 10); | |||
if (len == 0 || tmp == buf) | |||
pid = -1; | |||
/* just return the pid */ | |||
if (!remove_stale) | |||
return pid; | |||
/* invalid pid, remove stale file */ | |||
if (pid == -1) { | |||
pidfile_remove(filename); | |||
return 0; | |||
} | |||
/* check if pid is still running */ | |||
if (kill(pid, 0) == 0 || errno != ESRCH) { | |||
errno = 0; | |||
return pid; | |||
} | |||
errno = 0; | |||
pidfile_remove(filename); | |||
return 0; | |||
} |
@@ -0,0 +1,11 @@ | |||
#ifndef _PIDFILE_H_ | |||
#define _PIDFILE_H_ | |||
#include <sys/types.h> | |||
int pidfile_create(const char *filename); | |||
int pidfile_remove(const char *filename); | |||
pid_t pidfile_check(const char *filename, int remove_stale); | |||
#endif // _PIDFILE_H_ |