diff options
author | Sergey Poznyakoff <gray@gnu.org> | 2018-05-15 08:50:08 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org> | 2018-05-15 09:05:31 +0300 |
commit | b5f4388a2da1b94ce8c8e45a990fd51b2f52dae4 (patch) | |
tree | 28bcf8cf313309636357c470faed4456837db7c8 /src | |
download | genrc-b5f4388a2da1b94ce8c8e45a990fd51b2f52dae4.tar.gz genrc-b5f4388a2da1b94ce8c8e45a990fd51b2f52dae4.tar.bz2 |
Initial commit
Diffstat (limited to 'src')
-rw-r--r-- | src/.gitignore | 1 | ||||
-rw-r--r-- | src/Makefile.am | 32 | ||||
-rw-r--r-- | src/com_reload.c | 17 | ||||
-rw-r--r-- | src/com_restart.c | 12 | ||||
-rw-r--r-- | src/com_start.c | 121 | ||||
-rw-r--r-- | src/com_status.c | 38 | ||||
-rw-r--r-- | src/com_stop.c | 66 | ||||
-rw-r--r-- | src/err.c | 47 | ||||
-rw-r--r-- | src/genrc.c | 469 | ||||
-rw-r--r-- | src/genrc.h | 137 | ||||
-rw-r--r-- | src/match_exact.c | 20 | ||||
-rw-r--r-- | src/match_glob.c | 22 | ||||
-rw-r--r-- | src/match_pcre.c | 60 | ||||
-rw-r--r-- | src/match_regex.c | 61 | ||||
-rw-r--r-- | src/pid_config.c | 91 | ||||
-rw-r--r-- | src/pid_file.c | 70 | ||||
-rw-r--r-- | src/pid_grep.c | 80 | ||||
-rw-r--r-- | src/pid_proc.c | 335 | ||||
-rw-r--r-- | src/pid_ps.c | 137 | ||||
-rw-r--r-- | src/pidfrom.c | 52 | ||||
-rw-r--r-- | src/pidlist.c | 121 | ||||
-rw-r--r-- | src/procscan.c | 95 | ||||
-rw-r--r-- | src/sentinel.c | 207 | ||||
-rw-r--r-- | src/transform.c | 560 |
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 @@ | |||
1 | bin_PROGRAMS = genrc | ||
2 | genrc_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 | |||
25 | AM_CPPFLAGS = @GRECS_INCLUDES@ | ||
26 | LDADD = @GRECS_LDADD@ | ||
27 | |||
28 | if COND_PCRE | ||
29 | genrc_SOURCES += match_pcre.c | ||
30 | AM_CPPFLAGS += -DHAVE_PCRE=1 | ||
31 | endif | ||
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 | |||
3 | int | ||
4 | com_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 | |||
3 | int | ||
4 | com_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 | |||
3 | void | ||
4 | report_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 | |||
28 | typedef void (*SIGHANDLER)(int); | ||
29 | |||
30 | void | ||
31 | sigchld(int sig) | ||
32 | { | ||
33 | } | ||
34 | |||
35 | int | ||
36 | timedwaitpid(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 | |||
77 | int | ||
78 | com_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 | |||
3 | int | ||
4 | com_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 { | ||