You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

unitfork.pas 2.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. { Copyright (C) 2005 Bas Steendijk and Peter Green
  2. For conditions of distribution and use, see copyright notice in zlib_license.txt
  3. which is included in the package
  4. ----------------------------------------------------------------------------- }
  5. unit unitfork;
  6. interface
  7. procedure dofork(const programname:string);
  8. procedure writepid;
  9. function checkpid(const filename:string):boolean;
  10. procedure deletepid;
  11. implementation
  12. uses
  13. {$ifdef VER1_0}
  14. linux,
  15. {$else}
  16. baseunix,unix,unixutil,
  17. {$endif}
  18. sysutils;
  19. {$include unixstuff.inc}
  20. const
  21. F_WRLCK=2;
  22. var
  23. pidfilename:string;
  24. pidfile:text;
  25. procedure dofork(const programname:string);
  26. var
  27. a:integer;
  28. begin
  29. //writeln('dofork entered');
  30. //if (paramstr(1) = 'foreground') or (paramstr(1)='debug') then exit; {no fork}
  31. a := fork;
  32. if a = 0 then exit; {i'm the child}
  33. if a < 0 then begin
  34. writeln('failed to run in background, try "'+programname+' foreground" if it doesnt work otherwise');
  35. halt; {failed}
  36. end;
  37. halt; {i'm the parent}
  38. end;
  39. function checkpid;
  40. var
  41. handle:thandle;
  42. begin
  43. result := false;
  44. pidfilename := '';
  45. //debugout(filename);
  46. assignfile(pidfile,filename);
  47. filemode := 2;
  48. {opening file to get a fd for it. can't rewrite because a lock appears to allow the rewrite}
  49. {$i-}reset(pidfile);{$i+}
  50. if ioresult <> 0 then begin
  51. {$i-}rewrite(pidfile);{$i+}
  52. if ioresult <> 0 then exit;
  53. end;
  54. handle := getfs(pidfile);
  55. //debugout('got handle');
  56. {check if locking is possible: it's not if other process still runs}
  57. {$ifdef VER1_0}
  58. if not flock(handle,LOCK_EX or LOCK_NB)
  59. {$else}
  60. if flock(handle,LOCK_EX or LOCK_NB) <> 0
  61. {$endif}
  62. then begin
  63. //debugout('failed to lock pid file');
  64. close(pidfile);
  65. exit;
  66. end;
  67. rewrite(pidfile);
  68. {lock again because the rewrite removes the lock}
  69. {$ifdef VER1_0}
  70. if not flock(handle,LOCK_EX or LOCK_NB)
  71. {$else}
  72. if flock(handle,LOCK_EX or LOCK_NB) <> 0
  73. {$endif}
  74. then raise exception.create('flock failed '+inttostr(linuxerror));
  75. pidfilename := filename;
  76. result := true;
  77. end;
  78. procedure writepid;
  79. begin
  80. writeln(pidfile,getpid);
  81. flush(pidfile);
  82. end;
  83. procedure deletepid;
  84. begin
  85. if pidfilename = '' then exit;
  86. try
  87. {$i-}
  88. closefile(pidfile);
  89. erase(pidfile);
  90. {$i+}
  91. ioresult;
  92. except
  93. {}
  94. end;
  95. pidfilename := '';
  96. end;
  97. end.