andre@1160: /* Copyright (C) 2014 by Bundesamt für Sicherheit in der Informationstechnik andre@1160: * Software engineering by Intevation GmbH andre@1160: * andre@1160: * This file is Free Software under the GNU GPL (v>=2) andre@1160: * and comes with ABSOLUTELY NO WARRANTY! andre@1160: * See LICENSE.txt for details. andre@1160: */ andre@1160: wilde@782: #ifndef WIN32 wilde@782: wilde@782: #include wilde@782: #include wilde@782: #include wilde@782: #include andre@1332: #include wilde@782: wilde@782: #include "logging.h" andre@1332: #include "util.h" andre@1332: #include "strhelp.h" wilde@782: wilde@782: int wilde@782: open_lockfile(char *path) wilde@782: { wilde@782: int fd; wilde@782: char pidstr[20]; wilde@782: size_t pidstrlen; wilde@782: struct flock lk; wilde@782: fd = open(path, O_RDWR | O_CREAT, 0600); wilde@782: if (fd != -1) wilde@782: { wilde@782: /* Get an exclusive lock on the whole file. */ wilde@782: lk.l_type = F_WRLCK; wilde@782: lk.l_whence = SEEK_SET; wilde@782: lk.l_start = 0; wilde@782: lk.l_len = 0; andre@1332: fcntl(fd, F_SETLK, &lk); wilde@782: if (fcntl(fd, F_SETLK, &lk) != -1) andre@1332: { andre@1332: char oldpid[20]; andre@1332: FILE *f = fopen(path, "r"); andre@1332: size_t bytes_read; andre@1332: if (f) andre@1332: { andre@1332: bytes_read = fread(oldpid, 1, sizeof(oldpid), f); andre@1332: if (bytes_read) andre@1332: { andre@1332: char *oldPath, andre@1332: *newPath; andre@1332: if (bytes_read == sizeof(oldpid)) andre@1332: { andre@1332: ERRORPRINTF ("Bad information in pidfile\n"); andre@1332: } andre@1332: else andre@1332: { andre@1332: oldpid[bytes_read] = '\0'; andre@1332: oldPath = get_proc_install_dir(oldpid); andre@1332: newPath = get_install_dir(); andre@1332: if (oldPath && newPath && strcmp(oldPath, newPath) == 0) andre@1332: { andre@1332: DEBUGPRINTF("Got lock but process from %s is still" andre@1332: "running.\n", oldPath); andre@1332: xfree(oldPath); andre@1332: xfree(newPath); andre@1332: return -1; andre@1332: } andre@1332: xfree(oldPath); andre@1332: xfree(newPath); andre@1332: } andre@1332: } andre@1332: fclose(f); andre@1332: } andre@1332: andre@1332: ftruncate(fd, 0); andre@1332: pidstrlen = (size_t)snprintf(pidstr, sizeof(pidstr), "%d", andre@1332: getpid()); andre@1332: write(fd, pidstr, pidstrlen); andre@1332: } andre@1332: else andre@1332: { andre@1332: /* Lock can not be acquired. Bail out... */ andre@1332: close(fd); andre@1332: DEBUGPRINTF("Could not get an exclusive lock on %s.\n", path); andre@1332: return -1; andre@1332: } wilde@782: } wilde@782: else wilde@782: { wilde@782: DEBUGPRINTF("Failed to open lock file: %s.\n", path); wilde@782: } wilde@782: return fd; wilde@782: } wilde@782: wilde@782: void wilde@782: close_lockfile(int fd) wilde@782: { wilde@782: struct flock lk; wilde@782: wilde@782: /* Delete the PID from file. */ wilde@782: /* We do this instead of trying to unlink the file. */ wilde@782: ftruncate(fd, 0); wilde@782: wilde@782: /* Remove lock from the file. */ wilde@782: lk.l_type = F_UNLCK; wilde@782: lk.l_whence = SEEK_SET; wilde@782: lk.l_start = 0; wilde@782: lk.l_len = 0; wilde@782: if (fcntl(fd, F_SETLK, &lk) == -1) wilde@782: { andre@1250: /* Lock can not be removed */ andre@1250: DEBUGPRINTF("Could not remove lock from pid file.\n"); wilde@782: } wilde@782: close(fd); wilde@782: } wilde@782: wilde@782: #endif /* Not WIN32 */