GRASS Programmer's Manual  6.4.2(2012)
lock.c
Go to the documentation of this file.
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 }
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines