lock.c 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include <fcntl.h>
  5. #include <unistd.h>
  6. #include <sys/types.h>
  7. #include <sys/stat.h>
  8. #include <signal.h>
  9. #include "local_proto.h"
  10. #include <grass/gis.h>
  11. #include <grass/glocale.h>
  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. #include <errno.h>
  27. int main(int argc, char *argv[])
  28. {
  29. int pid;
  30. int lockpid;
  31. int lock;
  32. int locked;
  33. if (argc != 3 || sscanf(argv[2], "%d", &lockpid) != 1)
  34. G_fatal_error(_("Usage: %s file pid"), argv[0]);
  35. #define file argv[1]
  36. #ifdef __MINGW32__
  37. G_warning(_("Concurrent mapset locking is not supported on Windows"));
  38. exit(0);
  39. #else
  40. locked = 0;
  41. if ((lock = open(file, 0)) >= 0) { /* file exists */
  42. G_sleep(1); /* allow time for file creator to write its pid */
  43. if (read(lock, &pid, sizeof pid) == sizeof pid)
  44. locked = find_process(pid);
  45. close(lock);
  46. }
  47. if (locked)
  48. exit(2);
  49. if ((lock = creat(file, 0666)) < 0) {
  50. perror(file);
  51. G_fatal_error("%s: ", argv[0]);
  52. }
  53. if (write(lock, &lockpid, sizeof lockpid) != sizeof lockpid)
  54. G_fatal_error(_("Unable to write lockfile %s (%s)"),
  55. file, strerror(errno));
  56. close(lock);
  57. exit(0);
  58. #endif
  59. }
  60. int find_process(int pid)
  61. {
  62. /* attempt to kill pid with NULL signal. if success, then
  63. process pid is still running. otherwise, must check if
  64. kill failed because no such process, or because user is
  65. not owner of process
  66. */
  67. #ifdef __MINGW32__
  68. return 0;
  69. #else
  70. if (kill(pid, 0) == 0)
  71. return 1;
  72. return errno != ESRCH;
  73. #endif
  74. }