-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added PID lock file
- Loading branch information
Showing
1 changed file
with
124 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,8 @@ | ||
/* | ||
* 2019-03-14 | ||
* Copyright (C) 西门吹雪 | ||
* [email protected] | ||
*/ | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <ctype.h> | ||
|
@@ -6,16 +11,18 @@ | |
#include <signal.h> | ||
#include <sys/types.h> | ||
#include <sys/wait.h> | ||
#include <sys/stat.h> | ||
#include <hiredis.h> | ||
#include <fcntl.h> | ||
#include <time.h> | ||
#include <arpa/inet.h> | ||
char *__progname; | ||
/* | ||
* 2019-03-14 | ||
* Copyright (C) 西门吹雪 | ||
* [email protected] | ||
*/ | ||
#include <errno.h> | ||
#include <limits.h> | ||
#include <sys/file.h> | ||
|
||
char *__progname; | ||
static volatile sig_atomic_t got_sighup, got_sigchld; | ||
#define _PATH_TTL_IPTABLES_PID "/var/run/ttl_iptables.pid" | ||
|
||
char *get_progname(char *argv0) { | ||
char *p, *q; | ||
|
@@ -86,7 +93,106 @@ int check_ipaddr(char *str) { | |
return 1; | ||
} | ||
|
||
static void sighup_handler(int x) { | ||
got_sighup = 1; | ||
} | ||
|
||
static void sigchld_handler(int x) { | ||
got_sigchld = 1; | ||
} | ||
|
||
static void quit(int x) { | ||
(void) unlink(_PATH_TTL_IPTABLES_PID); | ||
_exit(0); | ||
} | ||
|
||
static void sigchld_reaper(void) { | ||
int waiter; | ||
pid_t pid; | ||
|
||
do { | ||
pid = waitpid(-1, &waiter, WNOHANG); | ||
switch (pid) { | ||
case -1: | ||
if (errno == EINTR) | ||
break; | ||
case 0: | ||
break; | ||
default: | ||
break; | ||
} | ||
} while (pid > 0); | ||
} | ||
|
||
static void acquire_daemonlock(int closeflag) { | ||
static int fd = -1; | ||
char buf[3 * 100]; | ||
const char *pidfile; | ||
char *ep; | ||
long otherpid; | ||
ssize_t num; | ||
|
||
if (closeflag) { | ||
/* close stashed fd for child so we don't leak it. */ | ||
if (fd != -1) { | ||
close(fd); | ||
fd = -1; | ||
} | ||
return; | ||
} | ||
|
||
if (fd == -1) { | ||
pidfile = _PATH_TTL_IPTABLES_PID; | ||
/* Initial mode is 0600 to prevent flock() race/DoS. */ | ||
if ((fd = open(pidfile, O_RDWR | O_CREAT, 0600)) == -1) { | ||
sprintf(buf, "can't open or create %s: %s", pidfile, | ||
strerror(errno)); | ||
fprintf(stderr, "%s\n", buf); | ||
exit(1); | ||
} | ||
|
||
if (flock(fd, LOCK_EX | LOCK_NB) < 0) { | ||
int save_errno = errno; | ||
|
||
bzero(buf, sizeof(buf)); | ||
if ((num = read(fd, buf, sizeof(buf) - 1)) > 0&& | ||
(otherpid = strtol(buf, &ep, 10)) > 0 && | ||
ep != buf && *ep == '\n' && otherpid != LONG_MAX) { | ||
sprintf(buf, "can't lock %s, otherpid may be %ld: %s", pidfile, | ||
otherpid, strerror(save_errno)); | ||
} else { | ||
sprintf(buf, "can't lock %s, otherpid unknown: %s", pidfile, | ||
strerror(save_errno)); | ||
} | ||
sprintf(buf, "can't lock %s, otherpid may be %ld: %s", pidfile, | ||
otherpid, strerror(save_errno)); | ||
fprintf(stderr, "%s\n", buf); | ||
exit(1); | ||
} | ||
(void) fchmod(fd, 0644); | ||
(void) fcntl(fd, F_SETFD, 1); | ||
} | ||
|
||
sprintf(buf, "%ld\n", (long) getpid()); | ||
(void) lseek(fd, (off_t) 0, SEEK_SET); | ||
num = write(fd, buf, strlen(buf)); | ||
(void) ftruncate(fd, num); | ||
} | ||
int main(int argc, char **argv) { | ||
struct sigaction sact; | ||
bzero((char * )&sact, sizeof sact); | ||
sigemptyset(&sact.sa_mask); | ||
sact.sa_flags = 0; | ||
sact.sa_flags |= SA_RESTART; | ||
sact.sa_handler = sigchld_handler; | ||
(void) sigaction(SIGCHLD, &sact, NULL); | ||
sact.sa_handler = sighup_handler; | ||
(void) sigaction(SIGHUP, &sact, NULL); | ||
sact.sa_handler = quit; | ||
(void) sigaction(SIGINT, &sact, NULL); | ||
(void) sigaction(SIGTERM, &sact, NULL); | ||
acquire_daemonlock(0); | ||
|
||
redisContext *c; | ||
redisReply *reply; | ||
const char *hostname = (argc > 1) ? argv[1] : "127.0.0.1"; | ||
|
@@ -110,6 +216,7 @@ int main(int argc, char **argv) { | |
exit(1); | ||
} | ||
daemon(0, 0); | ||
acquire_daemonlock(0); | ||
static char insert_command[256]; | ||
static char msg[1024]; | ||
pid_t pid; | ||
|
@@ -134,8 +241,17 @@ int main(int argc, char **argv) { | |
close(fd); | ||
} | ||
freeReplyObject(reply); | ||
/* Check to see if we received a signal while running jobs. */ | ||
if (got_sighup) { | ||
got_sighup = 0; | ||
redisFree(c); | ||
close(logfd); | ||
} | ||
if (got_sigchld) { | ||
got_sigchld = 0; | ||
sigchld_reaper(); | ||
} | ||
} | ||
redisFree(c); | ||
close(logfd); | ||
return 0; | ||
} | ||
|