123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127 |
- #include <stdio.h>
- #include <unistd.h>
- #include <sys/types.h>
- #include <sys/file.h>
- #include <signal.h>
- #include <errno.h>
- #include <stdlib.h>
- #include <fcntl.h>
- #include "skynet_daemon.h"
- static int
- check_pid(const char *pidfile) {
- int pid = 0;
- FILE *f = fopen(pidfile,"r");
- if (f == NULL)
- return 0;
- int n = fscanf(f,"%d", &pid);
- fclose(f);
- if (n !=1 || pid == 0 || pid == getpid()) {
- return 0;
- }
- if (kill(pid, 0) && errno == ESRCH)
- return 0;
- return pid;
- }
- static int
- write_pid(const char *pidfile) {
- FILE *f;
- int pid = 0;
- int fd = open(pidfile, O_RDWR|O_CREAT, 0644);
- if (fd == -1) {
- fprintf(stderr, "Can't create pidfile [%s].\n", pidfile);
- return 0;
- }
- f = fdopen(fd, "w+");
- if (f == NULL) {
- fprintf(stderr, "Can't open pidfile [%s].\n", pidfile);
- return 0;
- }
- if (flock(fd, LOCK_EX|LOCK_NB) == -1) {
- int n = fscanf(f, "%d", &pid);
- fclose(f);
- if (n != 1) {
- fprintf(stderr, "Can't lock and read pidfile.\n");
- } else {
- fprintf(stderr, "Can't lock pidfile, lock is held by pid %d.\n", pid);
- }
- return 0;
- }
- pid = getpid();
- if (!fprintf(f,"%d\n", pid)) {
- fprintf(stderr, "Can't write pid.\n");
- close(fd);
- return 0;
- }
- fflush(f);
- return pid;
- }
- static int
- redirect_fds() {
- int nfd = open("/dev/null", O_RDWR);
- if (nfd == -1) {
- perror("Unable to open /dev/null: ");
- return -1;
- }
- if (dup2(nfd, 0) < 0) {
- perror("Unable to dup2 stdin(0): ");
- return -1;
- }
- if (dup2(nfd, 1) < 0) {
- perror("Unable to dup2 stdout(1): ");
- return -1;
- }
- if (dup2(nfd, 2) < 0) {
- perror("Unable to dup2 stderr(2): ");
- return -1;
- }
- close(nfd);
- return 0;
- }
- int
- daemon_init(const char *pidfile) {
- int pid = check_pid(pidfile);
- if (pid) {
- fprintf(stderr, "Skynet is already running, pid = %d.\n", pid);
- return 1;
- }
- #ifdef __APPLE__
- fprintf(stderr, "'daemon' is deprecated: first deprecated in OS X 10.5 , use launchd instead.\n");
- #else
- if (daemon(1,1)) {
- fprintf(stderr, "Can't daemonize.\n");
- return 1;
- }
- #endif
- pid = write_pid(pidfile);
- if (pid == 0) {
- return 1;
- }
- if (redirect_fds()) {
- return 1;
- }
- return 0;
- }
- int
- daemon_exit(const char *pidfile) {
- return unlink(pidfile);
- }
|