summaryrefslogtreecommitdiffstats
path: root/urunlevel/runlevel/pidofproc.c
diff options
context:
space:
mode:
Diffstat (limited to 'urunlevel/runlevel/pidofproc.c')
-rw-r--r--urunlevel/runlevel/pidofproc.c217
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
31int checkpid(char *pid) 34int 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
90int pidofproc(char *pidfile, char *pathname, char **pids) 90int 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
157static const struct option long_options[] =
158{
159 { "pidfile", 1, NULL, 'p' },
160 { 0, 0, 0, 0 }
161};
162
163int pidofproc_main(int argc, char **argv) 152int 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}