aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org>2018-05-15 08:50:08 +0300
committerSergey Poznyakoff <gray@gnu.org>2018-05-15 09:05:31 +0300
commitb5f4388a2da1b94ce8c8e45a990fd51b2f52dae4 (patch)
tree28bcf8cf313309636357c470faed4456837db7c8 /src
downloadgenrc-b5f4388a2da1b94ce8c8e45a990fd51b2f52dae4.tar.gz
genrc-b5f4388a2da1b94ce8c8e45a990fd51b2f52dae4.tar.bz2
Initial commit
Diffstat (limited to 'src')
-rw-r--r--src/.gitignore1
-rw-r--r--src/Makefile.am32
-rw-r--r--src/com_reload.c17
-rw-r--r--src/com_restart.c12
-rw-r--r--src/com_start.c121
-rw-r--r--src/com_status.c38
-rw-r--r--src/com_stop.c66
-rw-r--r--src/err.c47
-rw-r--r--src/genrc.c469
-rw-r--r--src/genrc.h137
-rw-r--r--src/match_exact.c20
-rw-r--r--src/match_glob.c22
-rw-r--r--src/match_pcre.c60
-rw-r--r--src/match_regex.c61
-rw-r--r--src/pid_config.c91
-rw-r--r--src/pid_file.c70
-rw-r--r--src/pid_grep.c80
-rw-r--r--src/pid_proc.c335
-rw-r--r--src/pid_ps.c137
-rw-r--r--src/pidfrom.c52
-rw-r--r--src/pidlist.c121
-rw-r--r--src/procscan.c95
-rw-r--r--src/sentinel.c207
-rw-r--r--src/transform.c560
24 files changed, 2851 insertions, 0 deletions
diff --git a/src/.gitignore b/src/.gitignore
new file mode 100644
index 0000000..3d36647
--- /dev/null
+++ b/src/.gitignore
@@ -0,0 +1 @@
genrc
diff --git a/src/Makefile.am b/src/Makefile.am
new file mode 100644
index 0000000..fe24f3e
--- /dev/null
+++ b/src/Makefile.am
@@ -0,0 +1,32 @@
1bin_PROGRAMS = genrc
2genrc_SOURCES = \
3 genrc.c\
4 genrc.h\
5 err.c\
6 pidfrom.c\
7 pid_file.c\
8 pid_config.c\
9 pid_grep.c\
10 pid_proc.c\
11 pid_ps.c\
12 pidlist.c\
13 procscan.c\
14 com_status.c\
15 com_start.c\
16 com_stop.c\
17 com_restart.c\
18 com_reload.c\
19 transform.c\
20 match_exact.c\
21 match_glob.c\
22 match_regex.c\
23 sentinel.c
24
25AM_CPPFLAGS = @GRECS_INCLUDES@
26LDADD = @GRECS_LDADD@
27
28if COND_PCRE
29 genrc_SOURCES += match_pcre.c
30 AM_CPPFLAGS += -DHAVE_PCRE=1
31endif
32
diff --git a/src/com_reload.c b/src/com_reload.c
new file mode 100644
index 0000000..7ff1206
--- /dev/null
+++ b/src/com_reload.c
@@ -0,0 +1,17 @@
1#include "genrc.h"
2
3int
4com_reload(void)
5{
6 PIDLIST pids;
7
8 if (genrc_no_reload)
9 return com_restart();
10 pidlist_init(&pids);
11 if (get_pid_list(genrc_pid_closure, &pids))
12 return 1;
13 pidlist_kill(&pids, genrc_signal_reload);
14 return 0;
15}
16
17
diff --git a/src/com_restart.c b/src/com_restart.c
new file mode 100644
index 0000000..b3588a1
--- /dev/null
+++ b/src/com_restart.c
@@ -0,0 +1,12 @@
1#include "genrc.h"
2
3int
4com_restart(void)
5{
6 int rc;
7 rc = com_stop();
8 if (rc == 0)
9 rc = com_start();
10 return rc;
11}
12
diff --git a/src/com_start.c b/src/com_start.c
new file mode 100644
index 0000000..73bb2ec
--- /dev/null
+++ b/src/com_start.c
@@ -0,0 +1,121 @@
1#include "genrc.h"
2
3void
4report_exec_error(int rc, char const *program)
5{
6 if (WIFEXITED(rc)) {
7 if (WEXITSTATUS(rc)) {
8 genrc_error("%s exited with status %d",
9 program, WEXITSTATUS(rc));
10 }
11 } else if (WIFSIGNALED(rc)) {
12 char const *coremsg = "";
13#ifdef WCOREDUMP
14 if (WCOREDUMP(rc))
15 coremsg = " (core dumped)";
16#endif
17 genrc_error("%s terminated on signal %d%s",
18 program, WTERMSIG(rc), coremsg);
19 } else if (WIFSTOPPED(rc)) {
20 genrc_error("%s stopped on signal %d",
21 program, WSTOPSIG(rc));
22 } else {
23 genrc_error("%s terminated with unrecognized status: %d",
24 program, rc);
25 }
26}
27
28typedef void (*SIGHANDLER)(int);
29
30void
31sigchld(int sig)
32{
33}
34
35int
36timedwaitpid(pid_t pid, int *status)
37{
38 struct timeval now, stoptime, ttw;
39 int rc = -1;
40 SIGHANDLER oldsig;
41
42 oldsig = signal(SIGCHLD, sigchld);
43 gettimeofday(&stoptime, NULL);
44 stoptime.tv_sec += genrc_timeout;
45 while (1) {
46 pid_t p;
47
48 p = waitpid(pid, status, WNOHANG);
49 if (p == pid) {
50 rc = 0;
51 break;
52 }
53 if (p < 0 && errno != EINTR) {
54 system_error(errno, "waitpid");
55 break;
56 }
57
58 gettimeofday(&now, NULL);
59 if (timercmp(&now, &stoptime, >=))
60 break;
61 timersub(&stoptime, &now, &ttw);
62 if (select(0, NULL, NULL, NULL, &ttw) < 0) {
63 if (errno != EINTR) {
64 system_error(errno, "select");
65 break;
66 }
67 }
68
69 }
70 signal(SIGCHLD, oldsig);
71 if (rc) {
72 kill(pid, SIGKILL);
73 }
74 return rc;
75}
76
77int
78com_start(void)
79{
80 pid_t pid;
81 int status;
82 PIDLIST pids;
83 char *p;
84
85 pidlist_init(&pids);
86 if (get_pid_list(genrc_pid_closure, &pids) == 0) {
87 int running = pids.pidc > 0;
88 pidlist_free(&pids);
89 if (running) {
90 genrc_error("%s is already running", genrc_program);
91 return 1;
92 }
93 }
94
95 if ((p = getenv("GENRC_SENTINEL")) && *p == '1')
96 return sentinel();
97
98 pid = fork();
99 if (pid == -1) {
100 system_error(errno, "fork");
101 return 1;
102 }
103 if (pid == 0) {
104 char *argv[] = { SHELL, "-c", NULL, NULL };
105 argv[2] = genrc_command;
106 execvp(SHELL, argv);
107 system_error(errno, "failed to exec %s", genrc_program);
108 exit(127);
109 }
110
111 if (timedwaitpid(pid, &status)) {
112 genrc_error("timed out waiting for %s to return",
113 genrc_program);
114 return 1;
115 }
116 if (!(WIFEXITED(status) && WEXITSTATUS(status) == 0)) {
117 report_exec_error(status, genrc_program);
118 return 1;
119 }
120 return 0;
121}
diff --git a/src/com_status.c b/src/com_status.c
new file mode 100644
index 0000000..f68c6ef
--- /dev/null
+++ b/src/com_status.c
@@ -0,0 +1,38 @@
1#include "genrc.h"
2
3int
4com_status(void)
5{
6 PIDLIST pids;
7 int rc;
8
9 pidlist_init(&pids);
10 rc = get_pid_list(genrc_pid_closure, &pids);
11 if (rc == 0) {
12 if (pids.pidc == 0)
13 printf("%s is not running\n", genrc_program);
14 else {
15 printf("%s is running ", genrc_program);
16 if (pids.pidc == 1) {
17 printf("(pid %lu)",
18 (unsigned long) pids.pidv[0]);
19 } else {