/*
pipe-locking routines
*/
#include <signal.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <stdlib.h>
#include "config.h"
#define LOCK_MODE 0600
int check_lock(void)
{
int fh; int res; struct stat st;
/* check for lock_file exist and it is pipe */
if(stat(lock_file,&st)) return 0;
if( !(st.st_mode & S_IFIFO) ) return 0;
/* ignores SIGPIPE signal and try to write to pipe */
signal(SIGPIPE,SIG_IGN);
fh=open(lock_file,O_WRONLY|O_NDELAY|O_BINARY);
signal(SIGPIPE,SIG_DFL);
if(fh==-1) return 0;
signal(SIGPIPE,SIG_IGN);
res=write(fh,"z",1);
close(fh);
signal(SIGPIPE,SIG_DFL);
if(res!=1) return 0;
return 1;
}
void sig_handler(int par)
{
int status,wait_res;
/*printf("DEBUG: sig_handler()\n");*/
remove(lock_file);
wait_res=wait(&status);
/*printf("DEBUG: %d,%d\n",wait_res,status);*/
if(status)
e_printf("gtic ABORTED by signal %d",
WIFSIGNALED(status)?WTERMSIG(status):-1);
exit(0);
}
int touch_lock(void)
{
struct stat st;
FILE *fp; char buff[1];
/* first check lock_file for existing */
if(stat(lock_file,&st))
{
if(mkfifo(lock_file,LOCK_MODE)) return 1;
}
if( !(st.st_mode & S_IFIFO) )
{
remove(lock_file);
if(mkfifo(lock_file,LOCK_MODE)) return 1;
}
/* handle lock_file and wait for SIGCHLD */
signal(SIGCHLD,sig_handler);
while(1)
{
/*printf("DEBUG: touch_lock()\n");*/
fp=fopen(lock_file,"rb");
if(fp==NULL)
{
e_printf("touch_lock: unable to open %s for read",lock_file);
sleep(1);
}
else
{
fread(buff,1,1,fp);
fclose(fp);
}
}
return 0;
}
syntax highlighted by Code2HTML, v. 0.9.1