1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
|
/*
pidfile.c - interact with pidfiles
Copyright (c) 1995 Martin Schulze <Martin.Schulze@Linux.DE>
This file is part of the sysklogd package, a kernel and system log daemon.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA
*/
/*
* Sat Aug 19 13:24:33 MET DST 1995: Martin Schulze
* First version (v0.2) released
*/
#include <stdio.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/file.h>
#include <string.h>
#include <errno.h>
#include <signal.h>
/* read_pid
*
* Reads the specified pidfile and returns the read pid.
* 0 is returned if either there's no pidfile, it's empty
* or no pid can be read.
*/
int read_pid (char *pidfile)
{
FILE *f;
int pid;
if (!(f=fopen(pidfile,"r")))
return 0;
fscanf(f,"%d", &pid);
fclose(f);
return pid;
}
/* check_pid
*
* Reads the pid using read_pid and looks up the pid in the process
* table (using /proc) to determine if the process already exists. If
* so 1 is returned, otherwise 0.
*/
int check_pid (char *pidfile)
{
int pid = read_pid(pidfile);
/* Amazing ! _I_ am already holding the pid file... */
if ((!pid) || (pid == getpid ()))
return 0;
/*
* The 'standard' method of doing this is to try and do a 'fake' kill
* of the process. If an ESRCH error is returned the process cannot
* be found -- GW
*/
/* But... errno is usually changed only on error.. */
if (kill(pid, 0) && errno == ESRCH)
return(0);
return pid;
}
/* write_pid
*
* Writes the pid to the specified file. If that fails 0 is
* returned, otherwise the pid.
*/
int write_pid (char *pidfile)
{
FILE *f;
int fd;
int pid;
if ( ((fd = open(pidfile, O_RDWR|O_CREAT, 0644)) == -1)
|| ((f = fdopen(fd, "r+")) == NULL) ) {
fprintf(stderr, "Can't open or create %s.\n", pidfile);
return 0;
}
if (flock(fd, LOCK_EX|LOCK_NB) == -1) {
fscanf(f, "%d", &pid);
fclose(f);
printf("Can't lock, lock is held by pid %d.\n", pid);
return 0;
}
pid = getpid();
if (!fprintf(f,"%d\n", pid)) {
printf("Can't write pid , %s.\n", strerror(errno));
close(fd);
return 0;
}
fflush(f);
if (flock(fd, LOCK_UN) == -1) {
printf("Can't unlock pidfile %s, %s.\n", pidfile, strerror(errno));
close(fd);
return 0;
}
close(fd);
return pid;
}
/* remove_pid
*
* Remove the the specified file. The result from unlink(2)
* is returned
*/
int remove_pid (char *pidfile)
{
return unlink (pidfile);
}
|