1 /*
2  * dopid.c - This file is part of ncidd.
3  *
4  * Copyright (c) 2017-2018
5  * by John L. Chmielewski <jlc@users.sourceforge.net>
6  *
7  * dopid is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * dopid is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with ncidd.  If not, see <http://www.gnu.org/licenses/>.
19  */
20 
21 #include "dopid.h"
22 
23 /*
24  * if PID file exists and PID in process table, ERROR
25  * if PID file exists and PID not in process table, replace PID file
26  * if no PID file, write one
27  * if write a pidfile failed, OK
28  * If pidfile == 0, do not write PID file
29  */
doPID(pid_t * pid,const char * pidfile)30 int doPID(pid_t *pid, const char * pidfile)
31 {
32     struct stat statbuf;
33     FILE *pidptr;
34     pid_t curpid, foundpid = 0;
35     int ret;
36 
37     /* if pidfile == 0, no pid file is wanted */
38     if (pidfile == 0)
39     {
40         logMsg(LEVEL1, "Not using PID file, there was no '-P' option.\n");
41         return 0;
42     }
43 
44     /* check PID file */
45     curpid = getpid();
46     if (stat(pidfile, &statbuf) == 0)
47     {
48         if ((pidptr = fopen(pidfile, "r")) == NULL) return 1;
49         ret = fscanf(pidptr, "%u", &foundpid);
50         fclose(pidptr);
51         if (foundpid) ret = kill(foundpid, 0);
52         if (ret == 0 || (ret == -1 && errno != ESRCH)) return 1;
53         logMsg(LEVEL1, "Found stale pidfile: %s\n", pidfile);
54     }
55 
56     /* create pidfile */
57     if ((pidptr = fopen(pidfile, "w")) == NULL)
58     {
59         logMsg(LEVEL1, "Cannot write %s: %s\n", pidfile, strerror(errno));
60     }
61     else
62     {
63         *pid = curpid;
64         fprintf(pidptr, "%d\n", *pid);
65         fclose(pidptr);
66         logMsg(LEVEL1, "Wrote pid %d in pidfile: %s\n", *pid, pidfile);
67     }
68 
69     return 0;
70 }
71