Mercurial > trustbridge
comparison common/linuxlockfile.c @ 1332:8362e30f7b55
(issue139) Check that pid is not running if the lock can be aquired
If the lock on the lockfile can be aquired it might still be
possible that another process is running. So we read the
pid from the lockfile and check if another process with the
same installation prefix as us is running.
author | Andre Heinecke <andre.heinecke@intevation.de> |
---|---|
date | Wed, 15 Oct 2014 14:19:46 +0200 |
parents | 7ea3a4c0e2ae |
children | 5d7b1650de1f |
comparison
equal
deleted
inserted
replaced
1331:8897c90b8166 | 1332:8362e30f7b55 |
---|---|
10 | 10 |
11 #include <fcntl.h> | 11 #include <fcntl.h> |
12 #include <stdio.h> | 12 #include <stdio.h> |
13 #include <sys/types.h> | 13 #include <sys/types.h> |
14 #include <unistd.h> | 14 #include <unistd.h> |
15 #include <string.h> | |
15 | 16 |
16 #include "logging.h" | 17 #include "logging.h" |
18 #include "util.h" | |
19 #include "strhelp.h" | |
17 | 20 |
18 int | 21 int |
19 open_lockfile(char *path) | 22 open_lockfile(char *path) |
20 { | 23 { |
21 int fd; | 24 int fd; |
28 /* Get an exclusive lock on the whole file. */ | 31 /* Get an exclusive lock on the whole file. */ |
29 lk.l_type = F_WRLCK; | 32 lk.l_type = F_WRLCK; |
30 lk.l_whence = SEEK_SET; | 33 lk.l_whence = SEEK_SET; |
31 lk.l_start = 0; | 34 lk.l_start = 0; |
32 lk.l_len = 0; | 35 lk.l_len = 0; |
36 fcntl(fd, F_SETLK, &lk); | |
33 if (fcntl(fd, F_SETLK, &lk) != -1) | 37 if (fcntl(fd, F_SETLK, &lk) != -1) |
34 { | 38 { |
35 /* FIXME (issue139): For extra security we should check if there is | 39 char oldpid[20]; |
36 already a pid in the file. If so we should check in | 40 FILE *f = fopen(path, "r"); |
37 /proc/$PID if there is still a process of the same name | 41 size_t bytes_read; |
38 as ours running... */ | 42 if (f) |
39 ftruncate(fd, 0); | 43 { |
40 pidstrlen = (size_t)snprintf(pidstr, sizeof(pidstr), "%d", getpid()); | 44 bytes_read = fread(oldpid, 1, sizeof(oldpid), f); |
41 write(fd, pidstr, pidstrlen); | 45 if (bytes_read) |
42 } | 46 { |
43 else | 47 char *oldPath, |
44 { | 48 *newPath; |
45 /* Lock can not be acquired. Bail out... */ | 49 if (bytes_read == sizeof(oldpid)) |
46 close(fd); | 50 { |
47 DEBUGPRINTF("Could not get an exclusive lock on %s.\n", path); | 51 ERRORPRINTF ("Bad information in pidfile\n"); |
48 return -1; | 52 } |
49 } | 53 else |
54 { | |
55 oldpid[bytes_read] = '\0'; | |
56 oldPath = get_proc_install_dir(oldpid); | |
57 newPath = get_install_dir(); | |
58 if (oldPath && newPath && strcmp(oldPath, newPath) == 0) | |
59 { | |
60 DEBUGPRINTF("Got lock but process from %s is still" | |
61 "running.\n", oldPath); | |
62 xfree(oldPath); | |
63 xfree(newPath); | |
64 return -1; | |
65 } | |
66 xfree(oldPath); | |
67 xfree(newPath); | |
68 } | |
69 } | |
70 fclose(f); | |
71 } | |
72 | |
73 ftruncate(fd, 0); | |
74 pidstrlen = (size_t)snprintf(pidstr, sizeof(pidstr), "%d", | |
75 getpid()); | |
76 write(fd, pidstr, pidstrlen); | |
77 } | |
78 else | |
79 { | |
80 /* Lock can not be acquired. Bail out... */ | |
81 close(fd); | |
82 DEBUGPRINTF("Could not get an exclusive lock on %s.\n", path); | |
83 return -1; | |
84 } | |
50 } | 85 } |
51 else | 86 else |
52 { | 87 { |
53 DEBUGPRINTF("Failed to open lock file: %s.\n", path); | 88 DEBUGPRINTF("Failed to open lock file: %s.\n", path); |
54 } | 89 } |