This is a security audit change of the main source.
[ira/wip.git] / source3 / lib / pidfile.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 1.9.
4    pidfile handling
5    Copyright (C) Andrew Tridgell 1998
6    
7    This program 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 2 of the License, or
10    (at your option) any later version.
11    
12    This program 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 this program; if not, write to the Free Software
19    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22 #include "includes.h"
23
24
25 extern int DEBUGLEVEL;
26
27 #ifndef O_NONBLOCK
28 #define O_NONBLOCK
29 #endif
30
31
32 /* create a pid file in the lock directory. open it and leave it locked */
33 void pidfile_create(char *name)
34 {
35         int     fd;
36         char    buf[20];
37         pstring pidFile;
38         int pid;
39
40         slprintf(pidFile, sizeof(pidFile)-1, "%s/%s.pid", lp_lockdir(), name);
41
42         pid = pidfile_pid(name);
43         if (pid > 0 && process_exists(pid)) {
44                 DEBUG(0,("ERROR: %s is already running\n", name));
45                 exit(1);
46         }
47
48         fd = open(pidFile, O_NONBLOCK | O_CREAT | O_WRONLY, 0644);
49         if (fd < 0) {
50                 DEBUG(0,("ERROR: can't open %s: %s\n", pidFile, 
51                          strerror(errno)));
52                 exit(1);
53         }
54
55         if (fcntl_lock(fd,F_SETLK,0,1,F_WRLCK)==False) {
56                 DEBUG(0,("ERROR: %s is already running\n", name));
57                 exit(1);
58         }
59
60         memset(buf, 0, sizeof(buf));
61         slprintf(buf, sizeof(buf) - 1, "%u\n", (unsigned int) getpid());
62         if (write(fd, buf, sizeof(buf)) != sizeof(buf)) {
63                 DEBUG(0,("ERROR: can't write to %s: %s\n", 
64                          pidFile, strerror(errno)));
65                 exit(1);
66         }
67         /* Leave pid file open & locked for the duration... */
68 }
69
70
71 /* return the pid in a pidfile. return 0 if the process (or pidfile)
72    does not exist */
73 int pidfile_pid(char *name)
74 {
75         FILE *f;
76         pstring pidFile;
77         unsigned ret;
78
79         slprintf(pidFile, sizeof(pidFile)-1, "%s/%s.pid", lp_lockdir(), name);
80
81         f = fopen(pidFile, "r");
82         if (!f) {
83                 return 0;
84         }
85
86         if (fscanf(f,"%u", &ret) != 1) {
87                 fclose(f);
88                 return 0;
89         }
90         fclose(f);
91         
92         if (!process_exists(ret)) return 0;
93
94         return ret;
95 }
96