Add client side pidfile functions: pidfile_read(), pidfile_signal().

Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This commit is contained in:
Joachim Nilsson committed 2015-07-09 01:36:58 +02:00
1 parent 9ed00baa94
commit 5a50a6add1
4 files changed
+147 -3

No files matched your search

+2 -1
View File
@@ -56,7 +56,8 @@ endif
DISTFILES = README LICENSE
HEADERS = lite.h
OBJS := chomp.o copyfile.o dir.o fexist.o fisdir.o fmode.o fsendfile.o
OBJS += makepath.o pidfile.o rsync.o strlcpy.o strlcat.o strtonum.o tempfile.o
OBJS += makepath.o pidfile.o pidfilefn.o rsync.o
OBJS += strlcpy.o strlcat.o strtonum.o tempfile.o
DEPS := $(OBJS:.o=.d)
JUNK = *~ *.bak *.map .*.d *.d DEADJOE semantic.cache *.gdb *.elf core core.*
+8
View File
@@ -116,6 +116,14 @@ Generic Functions
may still exist even though the program is no longer running. This
is only a problem for clients.
- `pidfile_read(pidfile)`
Read PID from pid file created by `pidfile()`.
- `pidfile_signal(pidfile, signal)`
Send signal to PID found in pid file created by `pidfile()`.
- `rsync(src, dst, delete, *filter())`
Very simple `rsync()` to copy files files and directories
+6 -2
View File
@@ -51,7 +51,9 @@ int makepath (char *dir);
int dir (const char *dir, const char *type, int (*filter) (const char *file), char ***list, int strip);
int rsync (char *src, char *dst, int delete, int (*filter) (const char *file));
int pidfile (const char *basename);
int pidfile (const char *basename);
int pidfile_signal(const char *pidfile, int signal);
int pidfile_read (const char *pidfile);
#ifndef strlcpy
size_t strlcpy (char *dst, const char *src, size_t siz);
@@ -126,7 +128,9 @@ static inline int string_case_compare (const char *a, const char *b)
}
/* Compat */
#define copy_filep(src, dst) fcopyfile(src,dst);
#define copy_filep(src, dst) fcopyfile(src,dst)
#define pidfile_read_pid(file) pifile_read(file)
#define signal_pidfile(file, signo) pidfile_signal(file,signo)
#endif /* FINIT_LITE_H_ */
+131
View File
@@ -0,0 +1,131 @@
/* Functions for dealing with PID files (client side)
*
* Copyright (c) 2009-2015 Joachim Nilsson <troglobit@gmail.com>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
extern char *chomp(char *str);
/**
* pidfile_read - Reads a PID value from a pidfile.
* @pidfile: File containing PID, usually in /var/run/<PROC>.pid
*
* This function takes a @pidfile and returns the PID found therein.
*
* Returns:
* On invalid @pidfile -1 and errno set to %EINVAL, when @pidfile does not exist -1
* and errno set to %ENOENT. When the pidfile is empty or when its contents cannot
* be translated this function returns zero (0), on success this function returns
* a PID value greater than one. PID 1 is reserved for the system init process.
*/
int pidfile_read(const char *pidfile)
{
int pid = 0;
char buf[16];
FILE *fp;
if (!pidfile) {
errno = EINVAL;
return -1;
}
if (access(pidfile, F_OK) < 0)
return -1;
fp = fopen(pidfile, "r");
if (!fp)
return -1;
if (fgets(buf, sizeof(buf), fp)) {
char *ptr = chomp(buf);
if (ptr) {
errno = 0;
pid = strtoul(ptr, NULL, 0);
if (errno)
pid = 0; /* Failed conversion. */
}
}
fclose(fp);
return pid;
}
/**
* pidfile_signal - Send signal to a PID and cleanup pidfile afterwards
* @pidfile: File containing PID, usually in /var/run/<PROC>.pid
* @signal: Signal to send to PID found in @pidfile.
*
* If @signal is any of %SIGTERM, %SIGKILL, or if kill() returns -1 the
* @pidfile is removed.
*
* Returns:
* POSIX OK(0) on success, non-zero otherwise.
*/
int pidfile_signal(const char *pidfile, int signal)
{
int pid = -1, ret = -1;
pid = pidfile_read(pidfile);
if (pid <= 0)
return 1;
ret = kill(pid, signal);
if ((ret == -1) || (signal == SIGTERM) || (signal == SIGKILL))
remove(pidfile);
return 0;
}
/********************************* UNIT TESTS ************************************/
#ifdef UTEST_PIDFN
#define PIDFILE "/var/run/unittest.pid"
static void sig_handler(int signo)
{
fprintf(stderr, "Exiting ...\n");
}
int main(void)
{
signal(SIGTERM, sig_handler);
fprintf(stderr, "Testing pidfile() ...\n");
pidfile(NULL);
system("ls -ld " PIDFILE);
fprintf(stderr, "Reading pid file, should be %d ...\n", getpid());
fprintf(stderr, "=> %d\n", pidfile_read(PIDFILE));
fprintf(stderr, "Signalling ourselves ...\n");
return pidfile_signal(PIDFILE, SIGTERM);
}
#endif /* UTEST_PIDFN */
/**
* Local Variables:
* compile-command: "gcc -g -o unittest -DUTEST_PIDFN pidfile.c chomp.c pidfilefn.c && ./unittest"
* version-control: t
* indent-tabs-mode: t
* c-file-style: "linux"
* End:
*/