/*
  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