1 mike 1.1 /*
2 **==============================================================================
3 **
4 ** Open Management Infrastructure (OMI)
5 **
6 ** Copyright (c) Microsoft Corporation
7 **
8 ** Licensed under the Apache License, Version 2.0 (the "License"); you may not
9 ** use this file except in compliance with the License. You may obtain a copy
10 ** of the License at
11 **
12 ** http://www.apache.org/licenses/LICENSE-2.0
13 **
14 ** THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 ** KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
16 ** WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
17 ** MERCHANTABLITY OR NON-INFRINGEMENT.
18 **
19 ** See the Apache 2 License for the specific language governing permissions
20 ** and limitations under the License.
21 **
22 mike 1.1 **==============================================================================
23 */
24
25 #include "pidfile.h"
26
27 #if defined(CONFIG_POSIX)
28 # include <sys/types.h>
29 # include <unistd.h>
30 # include <signal.h>
31 # include <sys/wait.h>
32 # include <fcntl.h>
33 # include <sys/stat.h>
34 #endif
35
36 #include "paths.h"
37
38 #if defined(CONFIG_POSIX)
39
40 int PIDFile_OpenWrite()
41 {
42 int fd;
43 mike 1.1
44 /* Open the PID file */
45 fd = open(GetPath(ID_PIDFILE), O_WRONLY|O_CREAT|O_TRUNC, 0640);
46 if (fd == -1)
47 {
48 /* Possibly errno=EWOULDBLOCK */
49 return -1;
50 }
51
52 /* Obtain an exclusive write lock */
53 if (lockf(fd, F_LOCK, 0) != 0)
54 {
55 close(fd);
56 return -1;
57 }
58
59 /* Write PID into file */
60 {
61 char buf[16];
62 int n = sprintf(buf, "%d\n", getpid());
63
64 mike 1.1 if (write(fd, buf, n) != n)
65 {
66 close(fd);
67 return -1;
68 }
69 }
70
71 return fd;
72 }
73
74 int PIDFile_Delete()
75 {
76 int pid;
77
78 /* Only process owner can delete the PID file */
79 if (PIDFile_Read(&pid) != 0 || pid != getpid())
80 return -1;
81
82 if (unlink(GetPath(ID_PIDFILE)) != 0)
83 return -1;
84
85 mike 1.1 return 0;
86 }
87
88 int PIDFile_Read(int* pid)
89 {
90 int fd;
91
92 /* Open PID File */
93 fd = open(GetPath(ID_PIDFILE), O_RDONLY);
94 if (fd == -1)
95 return -1;
96
97 /* Read PID from file */
98 {
99 char buf[16];
100 ssize_t n;
101
102 /* Read PID file into buffer */
103 n = read(fd, buf, sizeof(buf));
104 if (n < 1)
105 {
106 mike 1.1 close(fd);
107 return -1;
108 }
109
110 /* Null-terminate buffer */
111 buf[n] = '\0';
112
113 /* Convert buffer to PID */
114 {
115 char* end = 0;
116 unsigned long x = strtoul(buf, &end, 10);
117
118 if (!end || *end != '\n')
119 {
120 close(fd);
121 return -1;
122 }
123
124 if (pid)
125 *pid = (int)x;
126 }
127 mike 1.1 }
128
129 close(fd);
130 return 0;
131 }
132
133 int PIDFile_Signal(int sig)
134 {
135 int pid;
136
137 /* Get PID form PIDFILE */
138 if (PIDFile_Read(&pid) != 0)
139 return -1;
140
141 /* Send a SIGTERM to the server */
142 if (kill(pid, sig) != 0)
143 return -1;
144
145 return 0;
146 }
147
148 mike 1.1 int PIDFile_IsRunning()
149 {
150 int pid;
151 int fd;
152
153 /* Open the PID file for write */
154 if ((fd = open(GetPath(ID_PIDFILE), O_WRONLY | O_NONBLOCK, 0640)) == -1)
155 {
156 return -1;
157 }
158
159 /* If able to obtain exclusive write lock, PID file is stale */
160 {
161 int r = lockf(fd, F_TEST, 0);
162
163 /* Successful exclusive lock (PID file is stale) */
164 if (r == 0)
165 {
166 /* Remove stale PID file */
167 unlink(GetPath(ID_PIDFILE));
168
169 mike 1.1 close(fd);
170 return -1;
171 }
172
173 close(fd);
174 }
175
176 /* Fail if PIDFILE does not exist */
177 if (access(GetPath(ID_PIDFILE), R_OK) != 0)
178 {
179 return -1;
180 }
181
182 /* Read PID form PIDFILE */
183 if (PIDFile_Read(&pid) != 0)
184 return -1;
185
186 /* Test process to see if it is running */
187 if (kill(pid, 0) == 0)
188 return 0;
189
190 mike 1.1 /* Process it not running */
191 return -1;
192 }
193
194 #endif /* defined(CONFIG_POSIX) */
|