(file) Return to pidfile.c CVS log (file) (dir) Up to [OMI] / omi / base

  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) */

ViewCVS 0.9.2