#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif
#ifdef HAVE_SIGNAL_H
#include <signal.h>
#endif
#ifdef HAVE_STDIO_H
#include <stdio.h>
#endif
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#ifdef HAVE_STRING_H
#include <string.h>
#endif
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif

#include "version.h"
#include "gensig.h"
#include "pidfile.h"

char pidfile_name[BUFSIZ] = "";

int make_pidfile(const char *filename_hint)
{
   int myuid;		/* This user's UID */
   int mypid;		/* This process's PID */
   int otherpid;
   int pidfile_fd;		/* File descriptor for pidfile */
   static char buf[10];	/* 10 chars should be enough for a pid */
   int n;
   char pid_buffer[BUFSIZ];

   myuid = getuid();
   mypid = getpid();

   if (filename_hint)
   {
      sprintf(pidfile_name, "%s-lock", filename_hint);
   }
   else
   {
      sprintf(pidfile_name, "/tmp/.gensig-%d-%d", myuid, myuid);
   }

   while ((pidfile_fd = open(pidfile_name, O_EXCL|O_CREAT|O_WRONLY, 0644)) < 0)
   {
      if (errno == EEXIST && (pidfile_fd = open(pidfile_name, O_RDONLY, 0)) >= 0)
      {
         /* Read the lock file to find out who has the device locked */
         n = read(pidfile_fd, pid_buffer, BUFSIZ);

         if (n <= 0)
         {
            perror((const char*)sprintf(buf, "Can't read pid from pidfile %s", pidfile_name));
            close(pidfile_fd);
            return -1;
         }
         else
         {
            pid_buffer[n] = 0;
            otherpid = atoi(pid_buffer);

            if (kill(otherpid, 0) == -1 && errno == ESRCH)
            {
                /* pid no longer exists - remove the lock file */
                if (unlink(pidfile_name) == 0)
                {
                   fprintf(stderr, "Removed stale pidfile\n");
                }
                else
                {
                   perror((const char*)sprintf(buf,
			"Couldn't remove stale pidfile %s", pidfile_name));
                   close(pidfile_fd);
                   return -1;
                }
            }
            else
            {
               /* process already exists */
               close(pidfile_fd);
               return otherpid;
            }
         }
         close(pidfile_fd);
      }
      else
      {
         perror((const char*)sprintf(buf, "Can't create pidfile %s", pidfile_name));
         return -1;
      }
   }

   /* Write this process's PID to the pidfile */
   sprintf(buf, "%d\n", mypid);
   if (write(pidfile_fd, buf, strlen(buf)) != strlen(buf))
   {
      unlink(pidfile_name);
      close(pidfile_fd);
      return -1;
   }

   close(pidfile_fd);

   return mypid;
}

int clean_pidfile()
{
   if ( strlen(pidfile_name) > 0 ) unlink(pidfile_name);
   return 0;
}




syntax highlighted by Code2HTML, v. 0.9.1