1/* this code is broken - there is a race condition with the unlink (tridge) */ 2 3/* 4 Unix SMB/CIFS implementation. 5 pidfile handling 6 Copyright (C) Andrew Tridgell 1998 7 8 This program is free software; you can redistribute it and/or modify 9 it under the terms of the GNU General Public License as published by 10 the Free Software Foundation; either version 3 of the License, or 11 (at your option) any later version. 12 13 This program is distributed in the hope that it will be useful, 14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 GNU General Public License for more details. 17 18 You should have received a copy of the GNU General Public License 19 along with this program. If not, see <http://www.gnu.org/licenses/>. 20*/ 21 22#include "includes.h" 23#include "system/filesys.h" 24 25/** 26 * @file 27 * @brief Pid file handling 28 */ 29 30/** 31 * return the pid in a pidfile. return 0 if the process (or pidfile) 32 * does not exist 33 */ 34pid_t pidfile_pid(const char *piddir, const char *name) 35{ 36 int fd; 37 char pidstr[20]; 38 pid_t ret; 39 char *pidFile; 40 41 asprintf(&pidFile, "%s/%s.pid", piddir, name); 42 43 fd = open(pidFile, O_NONBLOCK | O_RDONLY, 0644); 44 45 if (fd == -1) { 46 SAFE_FREE(pidFile); 47 return 0; 48 } 49 50 ZERO_STRUCT(pidstr); 51 52 if (read(fd, pidstr, sizeof(pidstr)-1) <= 0) { 53 goto noproc; 54 } 55 56 ret = (pid_t)atoi(pidstr); 57 58 if (!process_exists_by_pid(ret)) { 59 goto noproc; 60 } 61 62 if (fcntl_lock(fd,F_SETLK,0,1,F_RDLCK)) { 63 /* we could get the lock - it can't be a Samba process */ 64 goto noproc; 65 } 66 67 close(fd); 68 SAFE_FREE(pidFile); 69 return ret; 70 71 noproc: 72 close(fd); 73 unlink(pidFile); 74 SAFE_FREE(pidFile); 75 return 0; 76} 77 78/** 79 * create a pid file in the pid directory. open it and leave it locked 80 */ 81void pidfile_create(const char *piddir, const char *name) 82{ 83 int fd; 84 char buf[20]; 85 char *pidFile; 86 pid_t pid; 87 88 asprintf(&pidFile, "%s/%s.pid", piddir, name); 89 90 pid = pidfile_pid(piddir, name); 91 if (pid != 0) { 92 DEBUG(0,("ERROR: %s is already running. File %s exists and process id %d is running.\n", 93 name, pidFile, (int)pid)); 94 exit(1); 95 } 96 97 fd = open(pidFile, O_NONBLOCK | O_CREAT | O_WRONLY | O_EXCL, 0644); 98 if (fd == -1) { 99 DEBUG(0,("ERROR: can't open %s: Error was %s\n", pidFile, 100 strerror(errno))); 101 exit(1); 102 } 103 104 if (fcntl_lock(fd,F_SETLK,0,1,F_WRLCK)==false) { 105 DEBUG(0,("ERROR: %s : fcntl lock of file %s failed. Error was %s\n", 106 name, pidFile, strerror(errno))); 107 exit(1); 108 } 109 110 memset(buf, 0, sizeof(buf)); 111 slprintf(buf, sizeof(buf) - 1, "%u\n", (unsigned int) getpid()); 112 if (write(fd, buf, strlen(buf)) != (ssize_t)strlen(buf)) { 113 DEBUG(0,("ERROR: can't write to file %s: %s\n", 114 pidFile, strerror(errno))); 115 exit(1); 116 } 117 118 /* Leave pid file open & locked for the duration... */ 119 SAFE_FREE(pidFile); 120} 121