diff options
Diffstat (limited to 'urunlevel/runlevel/pidofproc.c')
-rw-r--r-- | urunlevel/runlevel/pidofproc.c | 217 |
1 files changed, 102 insertions, 115 deletions
diff --git a/urunlevel/runlevel/pidofproc.c b/urunlevel/runlevel/pidofproc.c index 6d03ae8..dfb3c91 100644 --- a/urunlevel/runlevel/pidofproc.c +++ b/urunlevel/runlevel/pidofproc.c | |||
@@ -3,6 +3,9 @@ | |||
3 | * | 3 | * |
4 | * Copyright (C) 2005 by David Seikel won_fang@yahoo.com.au | 4 | * Copyright (C) 2005 by David Seikel won_fang@yahoo.com.au |
5 | * | 5 | * |
6 | * Clean room implementation of LSB init.d specs. | ||
7 | * I didn't steal any of this, honest B-). | ||
8 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | 9 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by | 10 | * it under the terms of the GNU General Public License as published by |
8 | * the Free Software Foundation; either version 2 of the License, or | 11 | * the Free Software Foundation; either version 2 of the License, or |
@@ -30,112 +33,104 @@ | |||
30 | 33 | ||
31 | int checkpid(char *pid) | 34 | int checkpid(char *pid) |
32 | { | 35 | { |
33 | int found = 0; | 36 | int found = 0; |
34 | char proc[132]; | 37 | |
35 | 38 | RESERVE_CONFIG_BUFFER(proc, PATH_MAX); | |
36 | sprintf(proc, "/proc/%s", pid); | 39 | |
37 | if (stat(proc, &path_stat) == 0) | 40 | snprintf(proc, PATH_MAX, "/proc/%s", pid); |
38 | { | 41 | if (stat(proc, &path_stat) == 0) { |
39 | char *state = NULL; | 42 | char *state = NULL; |
40 | 43 | ||
41 | sprintf(proc, "/proc/%s/stat", pid); | 44 | snprintf(proc, PATH_MAX, "/proc/%s/stat", pid); |
42 | state = quick_read(proc); | 45 | state = quick_read(proc); |
43 | if (state != NULL) | 46 | if (state != NULL) { |
44 | { | 47 | /* Read and interpret the third space seperated field (State - DRSW = OK - ZX = DEAD_PID - T = STOPPED) */ |
45 | /* Read and interpret the third space seperated field (State - DRSW = OK - ZX = DEAD_PID - T = STOPPED) */ | 48 | if (state[0] != '\0') { |
46 | if (state[0] != '\0') | 49 | while ((*state != ' ') && (*state != '\0')) |
47 | { | 50 | state++; |
48 | while (*state != ' ') state++; | 51 | while (*state == ' ') |
49 | while (*state == ' ') state++; | 52 | state++; |
50 | while (*state != ' ') state++ | 53 | while ((*state != ' ') && (*state != '\0')) |
54 | state++ | ||
51 | // Should compare the name while scanning this. | 55 | // Should compare the name while scanning this. |
52 | ; | 56 | ; |
53 | while (*state == ' ') state++; | 57 | while (*state == ' ') |
54 | switch (*state) | 58 | state++; |
55 | { | 59 | switch (*state) { |
56 | case 'D' : | 60 | case 'D': |
57 | case 'R' : | 61 | case 'R': |
58 | case 'S' : | 62 | case 'S': |
59 | case 'W' : | 63 | case 'W': |
60 | case 'T' : /* Until proven otherwise, I'm assuming this means OK. */ | 64 | case 'T': /* Until proven otherwise, I'm assuming this means OK. */ |
61 | found = 1; | 65 | found = 1; |
62 | } | 66 | } |
63 | } | 67 | } |
64 | } | 68 | } else { /* Paranoid fallbacks. */ |
65 | else /* Paranoid fallbacks. */ | 69 | |
66 | { | 70 | snprintf(proc, PATH_MAX, "/proc/%s/exe", pid); |
67 | sprintf(proc, "/proc/%s/exe", pid); | 71 | if (stat(proc, &path_stat) == 0) { |
68 | if (stat(proc, &path_stat) == 0) | ||
69 | { | ||
70 | // Should check that it is a link to our executable. | 72 | // Should check that it is a link to our executable. |
71 | found = 1; | 73 | found = 1; |
72 | } | 74 | } else { |
73 | else | 75 | snprintf(proc, PATH_MAX, "/proc/%s/cmdline", pid); |
74 | { | 76 | if (stat(proc, &path_stat) == 0) { |
75 | sprintf(proc, "/proc/%s/cmdline", pid); | ||
76 | if (stat(proc, &path_stat) == 0) | ||
77 | { | ||
78 | // Should compare the name. | 77 | // Should compare the name. |
79 | found = 1; | 78 | found = 1; |
79 | } | ||
80 | } | ||
80 | } | 81 | } |
81 | } | 82 | |
82 | } | 83 | } |
83 | |||
84 | } | ||
85 | 84 | ||
86 | return found; | 85 | RELEASE_CONFIG_BUFFER(proc); |
86 | return found; | ||
87 | } | 87 | } |
88 | 88 | ||
89 | 89 | ||
90 | int pidofproc(char *pidfile, char *pathname, char **pids) | 90 | int pidofproc(char *pidfile, char *pathname, char **pids) |
91 | { | 91 | { |
92 | int status = INIT_D_STATUS_UNKNOWN; | 92 | int status = INIT_D_STATUS_UNKNOWN; |
93 | char *our_pidfile = pidfile; | 93 | char *our_pidfile = pidfile; |
94 | char *our_pids = NULL; | 94 | char *our_pids = NULL; |
95 | 95 | ||
96 | if (our_pidfile == NULL) | 96 | if (our_pidfile == NULL) |
97 | bb_xasprintf(&our_pidfile, "/var/run/%s.pid", bb_get_last_path_component(pathname)); | 97 | bb_xasprintf(&our_pidfile, "/var/run/%s.pid", |
98 | bb_get_last_path_component(pathname)); | ||
98 | 99 | ||
99 | our_pids = quick_read(our_pidfile); | 100 | our_pids = quick_read(our_pidfile); |
100 | 101 | ||
101 | if (our_pids != NULL) | 102 | if (our_pids != NULL) { |
102 | { | 103 | int i; |
103 | int i; | 104 | char *pid; |
104 | char *pid; | 105 | char *strtok_temp; |
105 | char *strtok_temp; | ||
106 | 106 | ||
107 | status = INIT_D_STATUS_DEAD_PID; | 107 | status = INIT_D_STATUS_DEAD_PID; |
108 | if (pids != NULL) | 108 | if (pids != NULL) { |
109 | { | 109 | (*pids) = (char *) xmalloc(sizeof(char) * strlen(our_pids) + 1); |
110 | (*pids) = (char *) xmalloc(sizeof (char) * strlen(our_pids) + 1); | 110 | (*pids)[0] = '\0'; |
111 | (*pids)[0] = '\0'; | ||
112 | } | ||
113 | |||
114 | pid = strtok_r(our_pids, " \n\r", &strtok_temp); | ||
115 | for (i = 0; pid != NULL; i++) | ||
116 | { | ||
117 | if (checkpid(pid)) | ||
118 | { | ||
119 | if (pids != NULL) | ||
120 | { | ||
121 | strcat(*pids, pid); | ||
122 | strcat(*pids, " "); | ||
123 | } | 111 | } |
124 | status = INIT_D_STATUS_OK; | ||
125 | } | ||
126 | 112 | ||
127 | pid = strtok_r(NULL, " \n\r", &strtok_temp); | 113 | pid = strtok_r(our_pids, " \n\r", &strtok_temp); |
128 | } | 114 | for (i = 0; pid != NULL; i++) { |
115 | if (checkpid(pid)) { | ||
116 | if (pids != NULL) { | ||
117 | strcat(*pids, pid); | ||
118 | strcat(*pids, " "); | ||
119 | } | ||
120 | status = INIT_D_STATUS_OK; | ||
121 | } | ||
122 | |||
123 | pid = strtok_r(NULL, " \n\r", &strtok_temp); | ||
124 | } | ||
129 | 125 | ||
130 | free(our_pids); | 126 | free(our_pids); |
131 | } | 127 | } else |
132 | else | 128 | status = INIT_D_STATUS_NOT_RUNNING; |
133 | status = INIT_D_STATUS_NOT_RUNNING; | ||
134 | 129 | ||
135 | if (pidfile == NULL) | 130 | if (pidfile == NULL) |
136 | free(our_pidfile); | 131 | free(our_pidfile); |
137 | 132 | ||
138 | return status; | 133 | return status; |
139 | } | 134 | } |
140 | 135 | ||
141 | 136 | ||
@@ -154,39 +149,31 @@ pidofproc [-p pidfile] pathname | |||
154 | running and not 0 otherwise. | 149 | running and not 0 otherwise. |
155 | */ | 150 | */ |
156 | 151 | ||
157 | static const struct option long_options[] = | ||
158 | { | ||
159 | { "pidfile", 1, NULL, 'p' }, | ||
160 | { 0, 0, 0, 0 } | ||
161 | }; | ||
162 | |||
163 | int pidofproc_main(int argc, char **argv) | 152 | int pidofproc_main(int argc, char **argv) |
164 | { | 153 | { |
165 | int result = EXIT_FAILURE; | 154 | int result = EXIT_FAILURE; |
166 | char *pidfile = NULL; | 155 | char *pidfile = NULL; |
167 | char *pids = NULL; | 156 | char *pids = NULL; |
168 | int opt; | 157 | int opt; |
169 | 158 | ||
170 | while ((opt = getopt_long (argc, argv, "p:", long_options, NULL)) > 0) | 159 | while ((opt = getopt(argc, argv, "p:")) > 0) { |
171 | { | 160 | switch (opt) { |
172 | switch (opt) | 161 | case 'p': |
173 | { | 162 | pidfile = optarg; |
174 | case 'p': | 163 | break; |
175 | pidfile = optarg; | 164 | |
176 | break; | 165 | default: |
177 | 166 | bb_show_usage(); | |
178 | default: | 167 | } |
179 | bb_show_usage(); | ||
180 | } | 168 | } |
181 | } | ||
182 | 169 | ||
183 | /* We require exactly one argument: the path name */ | 170 | /* We require exactly one argument: the path name */ |
184 | if (optind != (argc - 1)) | 171 | if (optind != (argc - 1)) |
185 | bb_show_usage(); | 172 | bb_show_usage(); |
186 | 173 | ||
187 | result = pidofproc(pidfile, argv[optind], &pids); | 174 | result = pidofproc(pidfile, argv[optind], &pids); |
188 | if (pids != NULL) | 175 | if (pids != NULL) |
189 | bb_printf("%s\n", pids); | 176 | bb_printf("%s\n", pids); |
190 | 177 | ||
191 | return result; | 178 | return result; |
192 | } | 179 | } |