view common/linuxlockfile.c @ 1338:ba7e36306085

(issue164) README updated.
author Emanuel Schuetze <emanuel@intevation.de>
date Thu, 16 Oct 2014 15:00:52 +0200
parents 5d7b1650de1f
children
line wrap: on
line source
/* Copyright (C) 2014 by Bundesamt für Sicherheit in der Informationstechnik
 * Software engineering by Intevation GmbH
 *
 * This file is Free Software under the GNU GPL (v>=2)
 * and comes with ABSOLUTELY NO WARRANTY!
 * See LICENSE.txt for details.
 */

#ifndef WIN32

#include <fcntl.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>

#include "logging.h"
#include "util.h"
#include "strhelp.h"

int
open_lockfile(char *path)
{
  int fd;
  char pidstr[20];
  size_t pidstrlen;
  struct flock lk;
  fd = open(path, O_RDWR | O_CREAT, 0600);
  if (fd != -1)
    {
      /* Get an exclusive lock on the whole file. */
      lk.l_type = F_WRLCK;
      lk.l_whence = SEEK_SET;
      lk.l_start = 0;
      lk.l_len = 0;
      fcntl(fd, F_SETLK, &lk);
      if (fcntl(fd, F_SETLK, &lk) != -1)
         {
           char oldpid[20];
           FILE *f = fopen(path, "r");
           size_t bytes_read;
           if (f)
             {
               bytes_read = fread(oldpid, 1, sizeof(oldpid), f);
               fclose(f);
               if (bytes_read)
                 {
                   char *oldPath,
                        *newPath;
                   if (bytes_read == sizeof(oldpid))
                     {
                       ERRORPRINTF ("Bad information in pidfile\n");
                     }
                   else
                     {
                       oldpid[bytes_read] = '\0';
                       oldPath = get_proc_install_dir(oldpid);
                       newPath = get_install_dir();
                       if (oldPath && newPath && strcmp(oldPath, newPath) == 0)
                         {
                           DEBUGPRINTF("Got lock but process from %s is still"
                                       "running.\n", oldPath);
                           xfree(oldPath);
                           xfree(newPath);
                           return -1;
                         }
                       xfree(oldPath);
                       xfree(newPath);
                     }
                 }
             }

           ftruncate(fd, 0);
           pidstrlen = (size_t)snprintf(pidstr, sizeof(pidstr), "%d",
                                        getpid());
           write(fd, pidstr, pidstrlen);
         }
       else
         {
           /* Lock can not be acquired.  Bail out... */
           close(fd);
           DEBUGPRINTF("Could not get an exclusive lock on %s.\n", path);
           return -1;
         }
    }
  else
    {
      DEBUGPRINTF("Failed to open lock file: %s.\n", path);
    }
  return fd;
}

void
close_lockfile(int fd)
{
  struct flock lk;

  /* Delete the PID from file. */
  /* We do this instead of trying to unlink the file. */
  ftruncate(fd, 0);

  /* Remove lock from the file. */
  lk.l_type = F_UNLCK;
  lk.l_whence = SEEK_SET;
  lk.l_start = 0;
  lk.l_len = 0;
  if (fcntl(fd, F_SETLK, &lk) == -1)
    {
      /* Lock can not be removed */
      DEBUGPRINTF("Could not remove lock from pid file.\n");
    }
  close(fd);
}

#endif /* Not WIN32 */

http://wald.intevation.org/projects/trustbridge/