From 7522b886602380764ce76f1d2244fad11bd1054f Mon Sep 17 00:00:00 2001 From: Samo Penic <samo.penic@gmail.com> Date: Fri, 08 Mar 2019 19:56:03 +0000 Subject: [PATCH] Full write of constant volume plugin --- src/general.c | 121 +++++++++++++++++++++++++++++++++++++++ 1 files changed, 119 insertions(+), 2 deletions(-) diff --git a/src/general.c b/src/general.c index ed06398..6b8a99c 100644 --- a/src/general.c +++ b/src/general.c @@ -1,12 +1,27 @@ +/* vim: set ts=4 sts=4 sw=4 noet : */ #include<stdio.h> #include<stdlib.h> #include "general.h" #include<stdarg.h> +#include <sys/time.h> +#include <unistd.h> +#include <time.h> + +#include <sys/stat.h> +#include <fcntl.h> +#include <errno.h> +#include <string.h> + ts_uint ts_fprintf(FILE *fd, char *fmt, ...){ if(quiet) return TS_SUCCESS; - va_list ap; - va_start(ap,fmt); + va_list ap; + va_start(ap,fmt); + char tmbuf[255]; + struct timeval now; + gettimeofday(&now, 0); + strftime(tmbuf, sizeof tmbuf, "%Y-%m-%d %H:%M:%S", localtime(&now.tv_sec)); +fprintf(fd, "[%s] ",tmbuf); vfprintf(fd, fmt, ap); /* Call vfprintf */ va_end(ap); /* Cleanup the va_list */ return TS_SUCCESS; @@ -22,3 +37,105 @@ } +/* Open/create the file named in 'pidFile', lock it, optionally set the + close-on-exec flag for the file descriptor, write our PID into the file, + and (in case the caller is interested) return the file descriptor + referring to the locked file. The caller is responsible for deleting + 'pidFile' file (just) before process termination. 'progName' should be the + name of the calling program (i.e., argv[0] or similar), and is used only for + diagnostic messages. If we can't open 'pidFile', or we encounter some other + error, then we print an appropriate diagnostic and terminate. */ + +/* + This is filelock/create_pid_file.c (Listing 55-4, page 1143), an example program file from the book, The Linux Programming Interface. + +The source code file is copyright 2010, Michael Kerrisk, and is licensed under the GNU Lesser General Public License, version 3. +*/ + +#define BUF_SIZE 100 +int createPidFile(const char *progName, const char *pidFile, int flags) +{ + int fd; + char buf[BUF_SIZE]; + + fd = open(pidFile, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR); + if (fd == -1){ + ts_fprintf(stderr,"Could not open PID file %s", pidFile); + fatal("Cannot continue (1)",1); +} + if (flags & CPF_CLOEXEC) { + + /* Set the close-on-exec file descriptor flag */ + + /* Instead of the following steps, we could (on Linux) have opened the + file with O_CLOEXEC flag. However, not all systems support open() + O_CLOEXEC (which was standardized only in SUSv4), so instead we use + fcntl() to set the close-on-exec flag after opening the file */ + + flags = fcntl(fd, F_GETFD); /* Fetch flags */ + if (flags == -1){ + ts_fprintf(stderr,"Could not get flags for PID file %s", pidFile); + fatal("Cannot continue (2)",1); +} + flags |= FD_CLOEXEC; /* Turn on FD_CLOEXEC */ + + if (fcntl(fd, F_SETFD, flags) == -1) /* Update flags */ + ts_fprintf(stderr,"Could not set flags for PID file %s", pidFile); + fatal("Cannot continue (3)",1); + + } + + if (lockRegion(fd, F_WRLCK, SEEK_SET, 0, 0) == -1) { + if (errno == EAGAIN || errno == EACCES){ + ts_fprintf(stderr,"PID file '%s' is locked; probably " + "'%s' is already running", pidFile, progName); + fatal("Cannot continue (4)",1); +} + else{ + ts_fprintf(stderr,"Unable to lock PID file '%s'", pidFile); + fatal("Cannot continue (5)",1); +} + } + + if (ftruncate(fd, 0) == -1){ + ts_fprintf(stderr,"Could not truncate PID file '%s'", pidFile); + fatal("Cannot continue (6)",1); +} + + snprintf(buf, BUF_SIZE, "%ld\n", (long) getpid()); + if (write(fd, buf, strlen(buf)) != strlen(buf)){ + + ts_fprintf(stderr,"Writing to PID file '%s'", pidFile); + fatal("Cannot continue (7)",1); +} + return fd; +} + + + +/* Lock a file region (private; public interfaces below) */ + +static int +lockReg(int fd, int cmd, int type, int whence, int start, off_t len) +{ + struct flock fl; + + fl.l_type = type; + fl.l_whence = whence; + fl.l_start = start; + fl.l_len = len; + + return fcntl(fd, cmd, &fl); +} + + +int /* Lock a file region using nonblocking F_SETLK */ +lockRegion(int fd, int type, int whence, int start, int len) +{ + return lockReg(fd, F_SETLK, type, whence, start, len); +} + + +char *libVersion(){ + return TS_VERSION; +} -- Gitblit v1.9.3