GRASS Programmer's Manual
6.4.2(2012)
|
00001 #include <stdlib.h> 00002 #include <stdio.h> 00003 #include <fcntl.h> 00004 #include <unistd.h> 00005 #include <sys/types.h> 00006 #include <sys/stat.h> 00007 #include <signal.h> 00008 #include "local_proto.h" 00009 #include <grass/gis.h> 00010 #include <grass/glocale.h> 00011 00012 /****************************************************************** 00013 *lock file pid 00014 * 00015 * this programs "locks" the file for process pid: 00016 * 00017 * 1. if file exists, the pid is read out of the file. if this 00018 * process is still running, the file is considered locked. 00019 * exit(2). 00020 * 2. something weird happened. G_fatal_error() aka exit(1) 00021 * 3. if file does not exist, or if file exists but process is not 00022 * running (ie, lock was not removed), the file is locked for 00023 * process pid by writing pid into the file. 00024 * exit(0). 00025 ******************************************************************/ 00026 00027 #include <errno.h> 00028 extern int errno; 00029 00030 int main(int argc, char *argv[]) 00031 { 00032 int pid; 00033 int lockpid; 00034 int lock; 00035 int locked; 00036 00037 if (argc != 3 || sscanf(argv[2], "%d", &lockpid) != 1) 00038 G_fatal_error(_("Usage: %s file pid"), argv[0]); 00039 #define file argv[1] 00040 00041 #ifdef __MINGW32__ 00042 G_warning(_("Concurrent mapset locking is not supported on Windows")); 00043 exit(0); 00044 #else 00045 locked = 0; 00046 if ((lock = open(file, 0)) >= 0) { /* file exists */ 00047 G_sleep(1); /* allow time for file creator to write its pid */ 00048 if (read(lock, &pid, sizeof pid) == sizeof pid) 00049 locked = find_process(pid); 00050 close(lock); 00051 } 00052 if (locked) 00053 exit(2); 00054 00055 if ((lock = creat(file, 0666)) < 0) { 00056 perror(file); 00057 G_fatal_error("%s: ", argv[0]); 00058 } 00059 if (write(lock, &lockpid, sizeof lockpid) != sizeof lockpid) 00060 G_fatal_error(_("Unable to write lockfile %s (disk full? Permissions?)"), 00061 file); 00062 close(lock); 00063 exit(0); 00064 #endif 00065 } 00066 00067 int find_process(int pid) 00068 { 00069 /* attempt to kill pid with NULL signal. if success, then 00070 process pid is still running. otherwise, must check if 00071 kill failed because no such process, or because user is 00072 not owner of process 00073 */ 00074 #ifdef __MINGW32__ 00075 return 0; 00076 #else 00077 if (kill(pid, 0) == 0) 00078 return 1; 00079 return errno != ESRCH; 00080 #endif 00081 }