Advertisement
PaulPaulAga

Untitled

Feb 17th, 2022
317
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.57 KB | None | 0 0
  1. #include <errno.h>
  2. #include <fcntl.h>
  3. #include <signal.h>
  4. #include <stdarg.h>
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <string.h>
  8. #include <syslog.h> // syslog, openlog
  9. #include <sys/stat.h> // umask
  10. #include <unistd.h>
  11. #include <pthread.h>
  12. #include <time.h> // time, ctime
  13. #include <stdarg.h>
  14.  
  15. #include <sys/time.h>
  16. #include <sys/resource.h>
  17.  
  18. #define LOCKFILE "/var/run/daemon.pid"
  19. #define LOCKMODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)
  20. #define MAXLINE 4096
  21.  
  22. sigset_t mask;
  23.  
  24. int lockfile(int fd)
  25. {
  26. struct flock fl;
  27.  
  28. fl.l_type = F_WRLCK;
  29. fl.l_start = 0;
  30. fl.l_whence = SEEK_SET;
  31. fl.l_len = 0;
  32.  
  33. return (fcntl(fd, F_SETLK, &fl));
  34. }
  35.  
  36. int already_running(void)
  37. {
  38. int fd;
  39. char buf[16];
  40.  
  41. fd = open(LOCKFILE, O_RDWR | O_CREAT, LOCKMODE);
  42. if (fd < 0)
  43. {
  44. syslog(LOG_ERR, "невозможно открыть %s: %s", LOCKFILE, strerror(errno));
  45. exit(1);
  46. }
  47. if (lockfile(fd) < 0)
  48. {
  49. if (errno == EACCES || errno == EAGAIN)
  50. {
  51. close(fd);
  52. return (1);
  53. }
  54. syslog(LOG_ERR, "невозможно установить блокировку на %s: %s", LOCKFILE, strerror(errno));
  55. exit(1);
  56. }
  57.  
  58. ftruncate(fd, 0);
  59.  
  60. sprintf(buf, "%ld", (long)getpid());
  61. write(fd, buf, strlen(buf) + 1);
  62. return (0);
  63. }
  64.  
  65. static void err_doit(int errnoflag, int error, const char *fmt, va_list ap)
  66. {
  67. char buf[MAXLINE];
  68.  
  69. vsnprintf(buf, MAXLINE - 1, fmt, ap);
  70. if (errnoflag)
  71. snprintf(buf + strlen(buf), MAXLINE - strlen(buf) - 1, ": %s",
  72. strerror(error));
  73. strcat(buf, "\n");
  74. fflush(stdout);
  75. fputs(buf, stderr);
  76. fflush(NULL);
  77. }
  78.  
  79. void err_quit(const char *fmt, ...)
  80. {
  81. va_list ap;
  82.  
  83. va_start(ap, fmt);
  84. err_doit(0, 0, fmt, ap);
  85. va_end(ap);
  86. exit(1);
  87. }
  88.  
  89. void err_exit(int error, const char *fmt, ...)
  90. {
  91. va_list ap;
  92. va_start(ap, fmt);
  93. err_doit(1, error, fmt, ap);
  94. va_end(ap);
  95. exit(1);
  96. }
  97.  
  98. void daemonize(const char *cmd)
  99. {
  100. int i, fd0, fd1, fd2;
  101. pid_t pid;
  102. struct rlimit rl;
  103. struct sigaction sa;
  104.  
  105. umask(0);
  106.  
  107. if (getrlimit(RLIMIT_NOFILE, &rl) < 0)
  108. err_quit("%s: невозможно получить максимальный номер дескриптора ", cmd);
  109.  
  110. if ((pid = fork()) < 0)
  111. err_quit("%s: ошибка вызова функции fork", cmd);
  112. else if (pid != 0)
  113. exit(0);
  114. setsid();
  115.  
  116. sa.sa_handler = SIG_IGN;
  117.  
  118. sigemptyset(&sa.sa_mask);
  119. sa.sa_flags = 0;
  120.  
  121. if (sigaction(SIGHUP, &sa, NULL) < 0)
  122. err_quit("%s: невозможно игнорировать сигнал SIGHUP", cmd);
  123.  
  124. if (chdir("/") < 0)
  125. err_quit("%s: невозможно сделать текущим рабочим каталогом /", cmd);
  126.  
  127. if (rl.rlim_max == RLIM_INFINITY)
  128. rl.rlim_max = 1024;
  129. for (int i = 0; i < rl.rlim_max; i++)
  130. close(i);
  131.  
  132. fd0 = open("/dev/null", O_RDWR);
  133.  
  134. fd1 = dup(0);
  135. fd2 = dup(0);
  136.  
  137.  
  138. openlog(cmd, LOG_CONS, LOG_DAEMON);
  139. if (fd0 != 0 || fd1 != 1 || fd2 != 2)
  140. {
  141. syslog(LOG_ERR, "ошибочные файловые дескрипторы %d %d %d",
  142. fd0, fd1, fd2);
  143. exit(1);
  144. }
  145. }
  146.  
  147. void *thr_fn(void *arg)
  148. {
  149. int err, signo;
  150. for (;;)
  151. {
  152. err = sigwait(&mask, &signo);
  153. if (err != 0)
  154. {
  155. syslog(LOG_ERR, "ошибка вы­з­ва функ­ции sigwait");
  156. exit(1);
  157. }
  158. switch (signo)
  159. {
  160. case SIGHUP:
  161. syslog(LOG_INFO, "Получен сигнал SIGHUP getlogin = %s", getlogin());
  162. break;
  163. case SIGTERM:
  164. syslog(LOG_INFO, "Получен сигнал SIGTERM; вы­ход");
  165.  
  166. exit(0);
  167. default:
  168. syslog(LOG_INFO, "получен н­предв­денный си­нал %d\n", signo);
  169. }
  170. }
  171. return (0);
  172. }
  173.  
  174. int main(int argc, char *argv[])
  175. {
  176. int err;
  177. pthread_t tid;
  178. char *cmd;
  179.  
  180. struct sigaction sa;
  181.  
  182. daemonize("my_daemon");
  183.  
  184. if (already_running() != 0)
  185. {
  186. syslog(LOG_ERR, "Демон уже запущен!\n");
  187. exit(1);
  188. }
  189.  
  190. sa.sa_handler = SIG_DFL;
  191.  
  192. sigemptyset(&sa.sa_mask);
  193.  
  194. sa.sa_flags = 0;
  195.  
  196. if (sigaction(SIGHUP, &sa, NULL) < 0)
  197. err_quit("%s: невозмо­но во­тан­вить де­ст­вие SIG_DFL для SIGHUP");
  198.  
  199. sigfillset(&mask);
  200.  
  201. if ((err = pthread_sigmask(SIG_BLOCK, &mask, NULL)) != 0)
  202. err_exit(err, "ошибка выполнeия опе­aции SIG_BLOCK");
  203.  
  204. err = pthread_create(&tid, NULL, thr_fn, 0);
  205.  
  206. if (err != 0)
  207. err_exit(err, "невозмо­но со­дать поток");
  208.  
  209. syslog(LOG_WARNING, "Проверка пройдена!");
  210.  
  211. long int ttime;
  212.  
  213. ttime = time(NULL);
  214.  
  215. while (1)
  216. {
  217. syslog(LOG_WARNING, "Демон! Время: %s", ctime(&ttime));
  218. sleep(3);
  219. }
  220. }
  221.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement