Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <errno.h>
- #include <fcntl.h>
- #include <signal.h>
- #include <stdarg.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <syslog.h> // syslog, openlog
- #include <sys/stat.h> // umask
- #include <unistd.h>
- #include <pthread.h>
- #include <time.h> // time, ctime
- #include <stdarg.h>
- #include <sys/time.h>
- #include <sys/resource.h>
- #define LOCKFILE "/var/run/daemon.pid"
- #define LOCKMODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)
- #define MAXLINE 4096
- sigset_t mask;
- int lockfile(int fd)
- {
- struct flock fl;
- fl.l_type = F_WRLCK;
- fl.l_start = 0;
- fl.l_whence = SEEK_SET;
- fl.l_len = 0;
- return (fcntl(fd, F_SETLK, &fl));
- }
- int already_running(void)
- {
- int fd;
- char buf[16];
- fd = open(LOCKFILE, O_RDWR | O_CREAT, LOCKMODE);
- if (fd < 0)
- {
- syslog(LOG_ERR, "невозможно открыть %s: %s", LOCKFILE, strerror(errno));
- exit(1);
- }
- if (lockfile(fd) < 0)
- {
- if (errno == EACCES || errno == EAGAIN)
- {
- close(fd);
- return (1);
- }
- syslog(LOG_ERR, "невозможно установить блокировку на %s: %s", LOCKFILE, strerror(errno));
- exit(1);
- }
- ftruncate(fd, 0);
- sprintf(buf, "%ld", (long)getpid());
- write(fd, buf, strlen(buf) + 1);
- return (0);
- }
- static void err_doit(int errnoflag, int error, const char *fmt, va_list ap)
- {
- char buf[MAXLINE];
- vsnprintf(buf, MAXLINE - 1, fmt, ap);
- if (errnoflag)
- snprintf(buf + strlen(buf), MAXLINE - strlen(buf) - 1, ": %s",
- strerror(error));
- strcat(buf, "\n");
- fflush(stdout);
- fputs(buf, stderr);
- fflush(NULL);
- }
- void err_quit(const char *fmt, ...)
- {
- va_list ap;
- va_start(ap, fmt);
- err_doit(0, 0, fmt, ap);
- va_end(ap);
- exit(1);
- }
- void err_exit(int error, const char *fmt, ...)
- {
- va_list ap;
- va_start(ap, fmt);
- err_doit(1, error, fmt, ap);
- va_end(ap);
- exit(1);
- }
- void daemonize(const char *cmd)
- {
- int i, fd0, fd1, fd2;
- pid_t pid;
- struct rlimit rl;
- struct sigaction sa;
- umask(0);
- if (getrlimit(RLIMIT_NOFILE, &rl) < 0)
- err_quit("%s: невозможно получить максимальный номер дескриптора ", cmd);
- if ((pid = fork()) < 0)
- err_quit("%s: ошибка вызова функции fork", cmd);
- else if (pid != 0)
- exit(0);
- setsid();
- sa.sa_handler = SIG_IGN;
- sigemptyset(&sa.sa_mask);
- sa.sa_flags = 0;
- if (sigaction(SIGHUP, &sa, NULL) < 0)
- err_quit("%s: невозможно игнорировать сигнал SIGHUP", cmd);
- if (chdir("/") < 0)
- err_quit("%s: невозможно сделать текущим рабочим каталогом /", cmd);
- if (rl.rlim_max == RLIM_INFINITY)
- rl.rlim_max = 1024;
- for (int i = 0; i < rl.rlim_max; i++)
- close(i);
- fd0 = open("/dev/null", O_RDWR);
- fd1 = dup(0);
- fd2 = dup(0);
- openlog(cmd, LOG_CONS, LOG_DAEMON);
- if (fd0 != 0 || fd1 != 1 || fd2 != 2)
- {
- syslog(LOG_ERR, "ошибочные файловые дескрипторы %d %d %d",
- fd0, fd1, fd2);
- exit(1);
- }
- }
- void *thr_fn(void *arg)
- {
- int err, signo;
- for (;;)
- {
- err = sigwait(&mask, &signo);
- if (err != 0)
- {
- syslog(LOG_ERR, "ошибка вызва функции sigwait");
- exit(1);
- }
- switch (signo)
- {
- case SIGHUP:
- syslog(LOG_INFO, "Получен сигнал SIGHUP getlogin = %s", getlogin());
- break;
- case SIGTERM:
- syslog(LOG_INFO, "Получен сигнал SIGTERM; выход");
- exit(0);
- default:
- syslog(LOG_INFO, "получен нпредвденный синал %d\n", signo);
- }
- }
- return (0);
- }
- int main(int argc, char *argv[])
- {
- int err;
- pthread_t tid;
- char *cmd;
- struct sigaction sa;
- daemonize("my_daemon");
- if (already_running() != 0)
- {
- syslog(LOG_ERR, "Демон уже запущен!\n");
- exit(1);
- }
- sa.sa_handler = SIG_DFL;
- sigemptyset(&sa.sa_mask);
- sa.sa_flags = 0;
- if (sigaction(SIGHUP, &sa, NULL) < 0)
- err_quit("%s: невозмоно вотанвить дествие SIG_DFL для SIGHUP");
- sigfillset(&mask);
- if ((err = pthread_sigmask(SIG_BLOCK, &mask, NULL)) != 0)
- err_exit(err, "ошибка выполнeия опеaции SIG_BLOCK");
- err = pthread_create(&tid, NULL, thr_fn, 0);
- if (err != 0)
- err_exit(err, "невозмоно содать поток");
- syslog(LOG_WARNING, "Проверка пройдена!");
- long int ttime;
- ttime = time(NULL);
- while (1)
- {
- syslog(LOG_WARNING, "Демон! Время: %s", ctime(&ttime));
- sleep(3);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement