//
// unix.c
//
//
//
//-UserX
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/file.h>
#include <dirent.h>
#include <signal.h>
#include <unistd.h>
/*
#if !defined(LOCK_EX) && !defined(LOCK_NB)
#include <fcntl.h>
#endif
*/
#include <string.h>
#include <stdio.h>
#include "misc/unix.h"
#include "base/logger.h"
#include "base/str.h"
#include "misc/global.h"
/**
@author UserX
@name unix
*/
//@{
/**
@return The number of processes SIGHUPped.
*/
int fdlock = 0;
char *lockfilename = NULL;
int unixSignalKin(int signum, char *lockfilepath, char *lockfileprefix) {
//char *s;
DIR *dir;
struct dirent *de;
int pid;
int i = 0;
if(lockfilepath == NULL) {
return -1;
}
if(lockfileprefix == NULL) {
return -1;
}
//todo: add checks for valid pathname
//s = stringCopyMany(lockfilepath, lockfileprefix, NULL);
dir = opendir(lockfilepath);
//stringFree(s);
if(dir == NULL) {
LOGERROR(stringCopyMany("unixSighupKin: failed opendir(", lockfilepath, ")",
_("Unable to open lockfile directory!"), NULL));
return -1;
}
//todo: revisit readdir might break if files are deleted while in use
for(de = readdir(dir); de != NULL; de = readdir(dir)) {
if(strncmp(lockfileprefix, de->d_name, strlen(lockfileprefix)) == 0) {
/*
s = stringCopyMany(lockfilepath, de->d_name, NULL);
if(unlink(s) != 0) {
*/
sscanf(de->d_name + strlen(lockfileprefix), "%d", &pid);
kill((pid_t) pid, signum);
LOGDEBUG(stringCopyMany("unixSighupKin: signal pidlock(",de->d_name,")",
_("Sent signal to existing process."), NULL));
i++;
/*
} else {
LOGDEBUG(stringCopyMany("unixSighupKin: released pidlock(",de->d_name,")",
_("Released old lockfile."), NULL));
}
stringFree(s);
*/
}
}
closedir(dir);
//todo: logging on error
return i;
}
int unixAddLockFile(char *lockfilepath, char *lockfileprefix) {
char *s;
int fd;
int i = 0;
/*
#if !defined(LOCK_EX) && !defined(LOCK_NB)
struct flock fl;
#endif
*/
if(lockfilepath == NULL) {
return -1;
}
if(lockfileprefix == NULL) {
return -1;
}
s = stringCopyMany(lockfilepath, lockfileprefix, NULL);
s = stringJoinMany(s, intToString((int) getpid()), NULL);
fd = open(s, O_CREAT | O_EXCL | S_IWUSR);
if(fd == -1) {
LOGERROR(stringCopyMany("unixAddLockFile: open lock file failed (", s, ")",
_("Error opening lockfile."), NULL))
stringFree(s);
return -1;
}
fdlock = fd;
lockfilename = s;
signal(SIGTERM, unixSignalTERM);
signal(SIGINT, unixSignalTERM);
#if defined(LOCK_EX) && defined(LOCK_NB)
i = flock(fd, LOCK_EX | LOCK_NB);
/*
#elif defined(F_WRLCK) && defined(F_SETLK)
fl.l_type = F_WRLCK;
i = fcntl(fd, F_SETLK, &fl);
*/
#else
i = 0;
#endif
if(i == -1) {
LOGERROR(stringCopyMany("unixAddLockFile: locking of lock file failed (", s, ")",
_("Error locking lockfile."), NULL))
//stringFree(s);
return -1;
}
LOGMINOR(stringCopyMany("unixAddLockFile: locked lock file (", s, ")",
_("Successfully established a lockfile."), NULL))
//stringFree(s);
return fd;
}
void unixSignalHUP(int i) {
reloadsettings = 1;
}
void unixSignalTERM(int i) {
if(fdlock != 0) {
close(fdlock);
}
if(lockfilename != NULL) {
unlink(lockfilename);
}
exit(0);
}
//@}
syntax highlighted by Code2HTML, v. 0.9.1