+++ /dev/null
-/*
-** Copyright 2000-2006 Double Precision, Inc. See COPYING for
-** distribution information.
-*/
-
-#include "config.h"
-#include "liblock.h"
-#include <stdio.h>
-#include <signal.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <ctype.h>
-#include <errno.h>
-#if HAVE_FCNTL_H
-#include <fcntl.h>
-#endif
-#include <sys/types.h>
-#include "../numlib/numlib.h"
-#if HAVE_SYS_WAIT_H
-#include <sys/wait.h>
-#endif
-#ifndef WEXITSTATUS
-#define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8)
-#endif
-#ifndef WIFEXITED
-#define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
-#endif
-#if HAVE_SYS_IOCTL_H
-#include <sys/ioctl.h>
-#endif
-
-#define exit(_a_) _exit(_a_)
-
-static const char rcsid[]="$Id: lockdaemon.c,v 1.10 2006/05/28 15:29:52 mrsam Exp $";
-
-static int start1(const char *, int);
-
-#define CONSOLE "/dev/null"
-
-int ll_daemon_start(const char *lockfile)
-{
-pid_t p;
-int pipefd[2];
-char c;
-int i;
-
- /*
- ** Close any open file descriptors.
- */
-
- for (i=3; i < 256; i++)
- close(i);
-
- /*
- ** We fork, and set up a pipe from the child process. If we read
- ** a single 0 byte from the pipe, it means that the child has
- ** succesfully initialized, and will return to main, so we exit(0).
- ** If we do not read a single 0 byte from the pipe, it means that
- ** there was an initialization error, so we return -1 to main.
- */
-
- if (pipe(pipefd) < 0)
- {
- perror("pipe");
- return (-1);
- }
-
- if ((p=fork()) == -1)
- {
- close(pipefd[0]);
- close(pipefd[1]);
- perror("fork");
- return (-1);
- }
-
- if (p == 0)
- {
- close(pipefd[0]);
-
- /*
- ** We fork once more, so that the daemon process will not
- ** be the child process of anyone.
- */
-
- p=fork();
- if (p == -1)
- {
- perror("fork");
- exit(0);
- }
- if (p)
- exit(0);
-
- /*
- ** Continue initialization in start1()
- */
- return (start1(lockfile, pipefd[1]));
- }
-
- close(pipefd[1]);
- if (read(pipefd[0], &c, 1) <= 0)
- c=1;
- close(pipefd[0]);
- if (c == 0)
- exit (0); /* Successful start of daemon */
- errno=EAGAIN;
- return (-1);
-}
-
-static int start1(const char *lockfile, int fd)
-{
-int lockfd;
-
-#if HAVE_SETPGRP
-#if SETPGRP_VOID
- setpgrp();
-#else
- setpgrp(0, 0);
-#endif
-#endif
-#ifdef TIOCNOTTY
-
- {
- int fd=open("/dev/tty", O_RDWR);
-
- if (fd >= 0)
- {
- ioctl(fd, TIOCNOTTY, 0);
- close(fd);
- }
- }
-#endif
-
-
- /* Attempt to obtain a lock */
-
- lockfd=open(lockfile, O_RDWR|O_CREAT, 0600);
-
- if (lockfd < 0)
- {
- /* Perhaps an upgraded daemon runs under new uid? */
-
- unlink(lockfile);
- lockfd=open(lockfile, O_RDWR|O_CREAT, 0600);
- }
-
- if (lockfd < 0)
- {
- perror(lockfile);
- exit(1);
- }
-
-#ifdef FD_CLOEXEC
- if (fcntl(lockfd, F_SETFD, FD_CLOEXEC) < 0)
- {
- perror("fcntl");
- close(lockfd);
- exit(1);
- }
-#endif
-
- if (ll_lock_ex_test(lockfd))
- {
- if (write(fd, "", 1) != 1)
- exit(1); /* Shouldn't happen */
-
- close(fd);
- exit (0); /* Already running, pretend success */
- }
-
- /*
- ** Return >0 to main, so it can continue main's setup.
- */
-
- return (fd);
-}
-
-int ll_daemon_resetio()
-{
-int i;
-
- close(0);
- if (open("/dev/null", O_RDONLY) != 0)
- return (-1);
-
- close(1);
- i=open(CONSOLE, O_WRONLY);
- if (i < 0) i=open("/dev/null", O_WRONLY);
- if (i != 1) return (-1);
-
- close(2);
- i=open(CONSOLE, O_WRONLY);
- if (i < 0) i=open("/dev/null", O_WRONLY);
- if (i != 2) return (-1);
- return (0);
-}
-
-void ll_daemon_started(const char *pidfile, int fd)
-{
-char buf[NUMBUFSIZE+1];
-char *p=strcat(libmail_str_pid_t(getpid(), buf), "\n");
-FILE *fp;
-
- unlink(pidfile);
- if ((fp=fopen(pidfile, "w")) == NULL ||
- fprintf(fp, "%s", p) < 0 || fflush(fp) < 0 || fclose(fp))
- {
- perror(pidfile);
- exit(1);
- }
-
- if (write(fd, "", 1) != 1) /* Signal waiting parent */
- exit(1); /* Shouldn't happen */
- close(fd);
-}
-
-static void stop1(const char *, const char *);
-
-int ll_daemon_stop(const char *lockfile, const char *pidfile)
-{
-pid_t p, p2;
-int waitstat;
-
- /*
- ** We fork, and the child process attempts to stop the daemon,
- ** then communicates the success to us, via its exit code.
- */
-
- signal(SIGCHLD, SIG_DFL);
- if ((p=fork()) == -1)
- {
- perror("fork");
- return (1);
- }
- if (p == 0) stop1(lockfile, pidfile);
-
- while ((p2=wait(&waitstat)) != p)
- ;
-
- if (WIFEXITED(waitstat))
- return (WEXITSTATUS(waitstat));
- return (0);
-}
-
-/*
-** The child process forks too. The parent process goes in a loop,
-** trying to kill the daemon process.
-**
-** The child process attempts to lock the lock file. When it
-** succeeds, it exits. When the child process exits, the parent
-** process kills itself.
-*/
-
-static RETSIGTYPE sigexit(int signum)
-{
- kill(getpid(), SIGKILL);
-#if RETSIGTYPE != void
- return (0);
-#endif
-}
-
-static void stop1(const char *lockfile, const char *pidfile)
-{
-int lockfd;
-pid_t p;
-
- if ((lockfd=open(lockfile, O_RDWR|O_CREAT, 0600)) < 0)
- {
- perror(lockfile);
- exit(1);
- }
-
- if ( ll_lock_ex_test(lockfd) == 0) /* No daemon process running */
- {
- close(lockfd);
- exit (0); /* That was easy! */
- }
-
- signal(SIGCHLD, sigexit);
-
- if ((p=fork()) == -1)
- {
- perror("fork");
- exit(1);
- }
-
- if (p) /* Parent - first sends a SIGTERM, then a SIGKILL */
- {
- int signum=SIGTERM;
-
- close(lockfd);
- for (;; sleep(10))
- {
- FILE *fp;
- int c;
-
- if ((fp=fopen(pidfile, "r")) == NULL)
- continue;
-
- p=0;
-
- while ((c=getc(fp)) != EOF && c != '\n')
- {
- if (isdigit(c))
- p=p*10+(c-'0');
- }
-
- fclose(fp);
- if (p)
- kill(p, signum);
- signum=SIGKILL;
- }
- }
-
- if (ll_lock_ex(lockfd))
- perror("lock");
- close(lockfd);
- exit(0);
-}
-
-int ll_daemon_restart(const char *lockfile, const char *pidfile)
-{
-int lockfd;
-pid_t p;
-FILE *fp;
-int c;
-
- if ((lockfd=open(lockfile, O_RDWR|O_CREAT, 0600)) < 0)
- {
- perror(lockfile);
- return (1);
- }
-
- if ( ll_lock_ex_test(lockfd) == 0) /* No daemon process running */
- {
- close(lockfd);
- return (0); /* That was easy! */
- }
- close(lockfd);
-
- if ((fp=fopen(pidfile, "r")) == NULL)
- return (0);
-
- p=0;
-
- while ((c=getc(fp)) != EOF && c != '\n')
- {
- if (isdigit(c))
- p=p*10+(c-'0');
- }
-
- fclose(fp);
- if (p)
- kill(p, SIGHUP);
- return (0);
-}
-