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.c192
1 files changed, 192 insertions, 0 deletions
diff --git a/urunlevel/runlevel/pidofproc.c b/urunlevel/runlevel/pidofproc.c
new file mode 100644
index 0000000..6d03ae8
--- /dev/null
+++ b/urunlevel/runlevel/pidofproc.c
@@ -0,0 +1,192 @@
1/*
2 * Mini pidofproc implementation for busybox.
3 *
4 * Copyright (C) 2005 by David Seikel won_fang@yahoo.com.au
5 *
6 * 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
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 * 02111-1307 USA
20 *
21 */
22
23#include <getopt.h>
24#include <string.h>
25#include <unistd.h>
26
27#include "busybox.h"
28#include "lib_init_d.h"
29
30
31int checkpid(char *pid)
32{
33 int found = 0;
34 char proc[132];
35
36 sprintf(proc, "/proc/%s", pid);
37 if (stat(proc, &path_stat) == 0)
38 {
39 char *state = NULL;
40
41 sprintf(proc, "/proc/%s/stat", pid);
42 state = quick_read(proc);
43 if (state != NULL)
44 {
45 /* Read and interpret the third space seperated field (State - DRSW = OK - ZX = DEAD_PID - T = STOPPED) */
46 if (state[0] != '\0')
47 {
48 while (*state != ' ') state++;
49 while (*state == ' ') state++;
50 while (*state != ' ') state++
51// Should compare the name while scanning this.
52 ;
53 while (*state == ' ') state++;
54 switch (*state)
55 {
56 case 'D' :
57 case 'R' :
58 case 'S' :
59 case 'W' :
60 case 'T' : /* Until proven otherwise, I'm assuming this means OK. */
61 found = 1;
62 }
63 }
64 }
65 else /* Paranoid fallbacks. */
66 {
67 sprintf(proc, "/proc/%s/exe", pid);
68 if (stat(proc, &path_stat) == 0)
69 {
70// Should check that it is a link to our executable.
71 found = 1;
72 }
73 else
74 {
75 sprintf(proc, "/proc/%s/cmdline", pid);
76 if (stat(proc, &path_stat) == 0)
77 {
78// Should compare the name.
79 found = 1;
80 }
81 }
82 }
83
84 }
85
86 return found;
87}
88
89
90int pidofproc(char *pidfile, char *pathname, char **pids)
91{
92 int status = INIT_D_STATUS_UNKNOWN;
93 char *our_pidfile = pidfile;
94 char *our_pids = NULL;
95
96 if (our_pidfile == NULL)
97 bb_xasprintf(&our_pidfile, "/var/run/%s.pid", bb_get_last_path_component(pathname));
98
99 our_pids = quick_read(our_pidfile);
100
101 if (our_pids != NULL)
102 {
103 int i;
104 char *pid;
105 char *strtok_temp;
106
107 status = INIT_D_STATUS_DEAD_PID;
108 if (pids != NULL)
109 {
110 (*pids) = (char *) xmalloc(sizeof (char) * strlen(our_pids) + 1);
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 }
124 status = INIT_D_STATUS_OK;
125 }
126
127 pid = strtok_r(NULL, " \n\r", &strtok_temp);
128 }
129
130 free(our_pids);
131 }
132 else
133 status = INIT_D_STATUS_NOT_RUNNING;
134
135 if (pidfile == NULL)
136 free(our_pidfile);
137
138 return status;
139}
140
141
142/*
143pidofproc [-p pidfile] pathname
144 This function returns one or more pid(s) for a particular
145 daemon using the algorithm given above. Only pids of running processes
146 should be returned.
147
148 Multiple pid(s) shall be separated by a single space in the pidfile
149 and in the output of pidofproc.
150
151 Compliant applications may use the basename instead of the pathname.
152 pidofproc should return the LSB defined exit status
153 codes for "status". It shall return 0 if the program is
154 running and not 0 otherwise.
155*/
156
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)
164{
165 int result = EXIT_FAILURE;
166 char *pidfile = NULL;
167 char *pids = NULL;
168 int opt;
169
170 while ((opt = getopt_long (argc, argv, "p:", long_options, NULL)) > 0)
171 {
172 switch (opt)
173 {
174 case 'p':
175 pidfile = optarg;
176 break;
177
178 default:
179 bb_show_usage();
180 }
181 }
182
183 /* We require exactly one argument: the path name */
184 if (optind != (argc - 1))
185 bb_show_usage();
186
187 result = pidofproc(pidfile, argv[optind], &pids);
188 if (pids != NULL)
189 bb_printf("%s\n", pids);
190
191 return result;
192}