GRASS Programmer's Manual  6.5.svn(2014)-r66266
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
lock.c
Go to the documentation of this file.
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <fcntl.h>
4 #include <unistd.h>
5 #include <sys/types.h>
6 #include <sys/stat.h>
7 #include <signal.h>
8 #include "local_proto.h"
9 #include <grass/gis.h>
10 #include <grass/glocale.h>
11 
12 /******************************************************************
13 *lock file pid
14 *
15 * this programs "locks" the file for process pid:
16 *
17 * 1. if file exists, the pid is read out of the file. if this
18 * process is still running, the file is considered locked.
19 * exit(2).
20 * 2. something weird happened. G_fatal_error() aka exit(1)
21 * 3. if file does not exist, or if file exists but process is not
22 * running (ie, lock was not removed), the file is locked for
23 * process pid by writing pid into the file.
24 * exit(0).
25 ******************************************************************/
26 
27 #include <errno.h>
28 extern int errno;
29 
30 int main(int argc, char *argv[])
31 {
32  int pid;
33  int lockpid;
34  int lock;
35  int locked;
36 
37  if (argc != 3 || sscanf(argv[2], "%d", &lockpid) != 1)
38  G_fatal_error(_("Usage: %s file pid"), argv[0]);
39 #define file argv[1]
40 
41 #ifdef __MINGW32__
42  G_warning(_("Concurrent mapset locking is not supported on Windows"));
43  exit(0);
44 #else
45  locked = 0;
46  if ((lock = open(file, 0)) >= 0) { /* file exists */
47  G_sleep(1); /* allow time for file creator to write its pid */
48  if (read(lock, &pid, sizeof pid) == sizeof pid)
49  locked = find_process(pid);
50  close(lock);
51  }
52  if (locked)
53  exit(2);
54 
55  if ((lock = creat(file, 0666)) < 0) {
56  perror(file);
57  G_fatal_error("%s: ", argv[0]);
58  }
59  if (write(lock, &lockpid, sizeof lockpid) != sizeof lockpid)
60  G_fatal_error(_("Unable to write lockfile %s (disk full? Permissions?)"),
61  file);
62  close(lock);
63  exit(0);
64 #endif
65 }
66 
67 int find_process(int pid)
68 {
69  /* attempt to kill pid with NULL signal. if success, then
70  process pid is still running. otherwise, must check if
71  kill failed because no such process, or because user is
72  not owner of process
73  */
74 #ifdef __MINGW32__
75  return 0;
76 #else
77  if (kill(pid, 0) == 0)
78  return 1;
79  return errno != ESRCH;
80 #endif
81 }
int find_process(int pid)
Definition: clean_temp.c:172
int main(int argc, char *argv[])
Definition: gem/main.c:302
void G_sleep(unsigned int seconds)
Definition: sleep.c:11
G_warning("category support for [%s] in mapset [%s] %s", name, mapset, type)
#define file
int errno
int G_fatal_error(const char *msg,...)
Print a fatal error message to stderr.