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 }

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