Mercurial > trustbridge
annotate 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 |
rev | line source |
---|---|
1160
a974b61a5cce
(issue108) Add missing license headers
Andre Heinecke <andre.heinecke@intevation.de>
parents:
782
diff
changeset
|
1 /* Copyright (C) 2014 by Bundesamt für Sicherheit in der Informationstechnik |
a974b61a5cce
(issue108) Add missing license headers
Andre Heinecke <andre.heinecke@intevation.de>
parents:
782
diff
changeset
|
2 * Software engineering by Intevation GmbH |
a974b61a5cce
(issue108) Add missing license headers
Andre Heinecke <andre.heinecke@intevation.de>
parents:
782
diff
changeset
|
3 * |
a974b61a5cce
(issue108) Add missing license headers
Andre Heinecke <andre.heinecke@intevation.de>
parents:
782
diff
changeset
|
4 * This file is Free Software under the GNU GPL (v>=2) |
a974b61a5cce
(issue108) Add missing license headers
Andre Heinecke <andre.heinecke@intevation.de>
parents:
782
diff
changeset
|
5 * and comes with ABSOLUTELY NO WARRANTY! |
a974b61a5cce
(issue108) Add missing license headers
Andre Heinecke <andre.heinecke@intevation.de>
parents:
782
diff
changeset
|
6 * See LICENSE.txt for details. |
a974b61a5cce
(issue108) Add missing license headers
Andre Heinecke <andre.heinecke@intevation.de>
parents:
782
diff
changeset
|
7 */ |
a974b61a5cce
(issue108) Add missing license headers
Andre Heinecke <andre.heinecke@intevation.de>
parents:
782
diff
changeset
|
8 |
782
20ca94680003
Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff
changeset
|
9 #ifndef WIN32 |
20ca94680003
Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff
changeset
|
10 |
20ca94680003
Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff
changeset
|
11 #include <fcntl.h> |
20ca94680003
Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff
changeset
|
12 #include <stdio.h> |
20ca94680003
Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff
changeset
|
13 #include <sys/types.h> |
20ca94680003
Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff
changeset
|
14 #include <unistd.h> |
1332
8362e30f7b55
(issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents:
1250
diff
changeset
|
15 #include <string.h> |
782
20ca94680003
Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff
changeset
|
16 |
20ca94680003
Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff
changeset
|
17 #include "logging.h" |
1332
8362e30f7b55
(issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents:
1250
diff
changeset
|
18 #include "util.h" |
8362e30f7b55
(issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents:
1250
diff
changeset
|
19 #include "strhelp.h" |
782
20ca94680003
Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff
changeset
|
20 |
20ca94680003
Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff
changeset
|
21 int |
20ca94680003
Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff
changeset
|
22 open_lockfile(char *path) |
20ca94680003
Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff
changeset
|
23 { |
20ca94680003
Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff
changeset
|
24 int fd; |
20ca94680003
Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff
changeset
|
25 char pidstr[20]; |
20ca94680003
Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff
changeset
|
26 size_t pidstrlen; |
20ca94680003
Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff
changeset
|
27 struct flock lk; |
20ca94680003
Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff
changeset
|
28 fd = open(path, O_RDWR | O_CREAT, 0600); |
20ca94680003
Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff
changeset
|
29 if (fd != -1) |
20ca94680003
Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff
changeset
|
30 { |
20ca94680003
Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff
changeset
|
31 /* Get an exclusive lock on the whole file. */ |
20ca94680003
Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff
changeset
|
32 lk.l_type = F_WRLCK; |
20ca94680003
Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff
changeset
|
33 lk.l_whence = SEEK_SET; |
20ca94680003
Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff
changeset
|
34 lk.l_start = 0; |
20ca94680003
Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff
changeset
|
35 lk.l_len = 0; |
1332
8362e30f7b55
(issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents:
1250
diff
changeset
|
36 fcntl(fd, F_SETLK, &lk); |
782
20ca94680003
Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff
changeset
|
37 if (fcntl(fd, F_SETLK, &lk) != -1) |
1332
8362e30f7b55
(issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents:
1250
diff
changeset
|
38 { |
8362e30f7b55
(issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents:
1250
diff
changeset
|
39 char oldpid[20]; |
8362e30f7b55
(issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents:
1250
diff
changeset
|
40 FILE *f = fopen(path, "r"); |
8362e30f7b55
(issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents:
1250
diff
changeset
|
41 size_t bytes_read; |
8362e30f7b55
(issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents:
1250
diff
changeset
|
42 if (f) |
8362e30f7b55
(issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents:
1250
diff
changeset
|
43 { |
8362e30f7b55
(issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents:
1250
diff
changeset
|
44 bytes_read = fread(oldpid, 1, sizeof(oldpid), f); |
8362e30f7b55
(issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents:
1250
diff
changeset
|
45 if (bytes_read) |
8362e30f7b55
(issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents:
1250
diff
changeset
|
46 { |
8362e30f7b55
(issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents:
1250
diff
changeset
|
47 char *oldPath, |
8362e30f7b55
(issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents:
1250
diff
changeset
|
48 *newPath; |
8362e30f7b55
(issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents:
1250
diff
changeset
|
49 if (bytes_read == sizeof(oldpid)) |
8362e30f7b55
(issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents:
1250
diff
changeset
|
50 { |
8362e30f7b55
(issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents:
1250
diff
changeset
|
51 ERRORPRINTF ("Bad information in pidfile\n"); |
8362e30f7b55
(issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents:
1250
diff
changeset
|
52 } |
8362e30f7b55
(issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents:
1250
diff
changeset
|
53 else |
8362e30f7b55
(issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents:
1250
diff
changeset
|
54 { |
8362e30f7b55
(issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents:
1250
diff
changeset
|
55 oldpid[bytes_read] = '\0'; |
8362e30f7b55
(issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents:
1250
diff
changeset
|
56 oldPath = get_proc_install_dir(oldpid); |
8362e30f7b55
(issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents:
1250
diff
changeset
|
57 newPath = get_install_dir(); |
8362e30f7b55
(issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents:
1250
diff
changeset
|
58 if (oldPath && newPath && strcmp(oldPath, newPath) == 0) |
8362e30f7b55
(issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents:
1250
diff
changeset
|
59 { |
8362e30f7b55
(issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents:
1250
diff
changeset
|
60 DEBUGPRINTF("Got lock but process from %s is still" |
8362e30f7b55
(issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents:
1250
diff
changeset
|
61 "running.\n", oldPath); |
8362e30f7b55
(issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents:
1250
diff
changeset
|
62 xfree(oldPath); |
8362e30f7b55
(issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents:
1250
diff
changeset
|
63 xfree(newPath); |
8362e30f7b55
(issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents:
1250
diff
changeset
|
64 return -1; |
8362e30f7b55
(issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents:
1250
diff
changeset
|
65 } |
8362e30f7b55
(issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents:
1250
diff
changeset
|
66 xfree(oldPath); |
8362e30f7b55
(issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents:
1250
diff
changeset
|
67 xfree(newPath); |
8362e30f7b55
(issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents:
1250
diff
changeset
|
68 } |
8362e30f7b55
(issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents:
1250
diff
changeset
|
69 } |
8362e30f7b55
(issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents:
1250
diff
changeset
|
70 fclose(f); |
8362e30f7b55
(issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents:
1250
diff
changeset
|
71 } |
8362e30f7b55
(issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents:
1250
diff
changeset
|
72 |
8362e30f7b55
(issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents:
1250
diff
changeset
|
73 ftruncate(fd, 0); |
8362e30f7b55
(issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents:
1250
diff
changeset
|
74 pidstrlen = (size_t)snprintf(pidstr, sizeof(pidstr), "%d", |
8362e30f7b55
(issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents:
1250
diff
changeset
|
75 getpid()); |
8362e30f7b55
(issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents:
1250
diff
changeset
|
76 write(fd, pidstr, pidstrlen); |
8362e30f7b55
(issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents:
1250
diff
changeset
|
77 } |
8362e30f7b55
(issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents:
1250
diff
changeset
|
78 else |
8362e30f7b55
(issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents:
1250
diff
changeset
|
79 { |
8362e30f7b55
(issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents:
1250
diff
changeset
|
80 /* Lock can not be acquired. Bail out... */ |
8362e30f7b55
(issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents:
1250
diff
changeset
|
81 close(fd); |
8362e30f7b55
(issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents:
1250
diff
changeset
|
82 DEBUGPRINTF("Could not get an exclusive lock on %s.\n", path); |
8362e30f7b55
(issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents:
1250
diff
changeset
|
83 return -1; |
8362e30f7b55
(issue139) Check that pid is not running if the lock can be aquired
Andre Heinecke <andre.heinecke@intevation.de>
parents:
1250
diff
changeset
|
84 } |
782
20ca94680003
Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff
changeset
|
85 } |
20ca94680003
Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff
changeset
|
86 else |
20ca94680003
Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff
changeset
|
87 { |
20ca94680003
Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff
changeset
|
88 DEBUGPRINTF("Failed to open lock file: %s.\n", path); |
20ca94680003
Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff
changeset
|
89 } |
20ca94680003
Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff
changeset
|
90 return fd; |
20ca94680003
Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff
changeset
|
91 } |
20ca94680003
Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff
changeset
|
92 |
20ca94680003
Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff
changeset
|
93 void |
20ca94680003
Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff
changeset
|
94 close_lockfile(int fd) |
20ca94680003
Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff
changeset
|
95 { |
20ca94680003
Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff
changeset
|
96 struct flock lk; |
20ca94680003
Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff
changeset
|
97 |
20ca94680003
Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff
changeset
|
98 /* Delete the PID from file. */ |
20ca94680003
Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff
changeset
|
99 /* We do this instead of trying to unlink the file. */ |
20ca94680003
Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff
changeset
|
100 ftruncate(fd, 0); |
20ca94680003
Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff
changeset
|
101 |
20ca94680003
Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff
changeset
|
102 /* Remove lock from the file. */ |
20ca94680003
Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff
changeset
|
103 lk.l_type = F_UNLCK; |
20ca94680003
Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff
changeset
|
104 lk.l_whence = SEEK_SET; |
20ca94680003
Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff
changeset
|
105 lk.l_start = 0; |
20ca94680003
Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff
changeset
|
106 lk.l_len = 0; |
20ca94680003
Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff
changeset
|
107 if (fcntl(fd, F_SETLK, &lk) == -1) |
20ca94680003
Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff
changeset
|
108 { |
1250
7ea3a4c0e2ae
This should be serious software.
Andre Heinecke <andre.heinecke@intevation.de>
parents:
1162
diff
changeset
|
109 /* Lock can not be removed */ |
7ea3a4c0e2ae
This should be serious software.
Andre Heinecke <andre.heinecke@intevation.de>
parents:
1162
diff
changeset
|
110 DEBUGPRINTF("Could not remove lock from pid file.\n"); |
782
20ca94680003
Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff
changeset
|
111 } |
20ca94680003
Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff
changeset
|
112 close(fd); |
20ca94680003
Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff
changeset
|
113 } |
20ca94680003
Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff
changeset
|
114 |
20ca94680003
Implemented detection of running instance on linux using a lock file.
Sascha Wilde <wilde@intevation.de>
parents:
diff
changeset
|
115 #endif /* Not WIN32 */ |