From 69b439a013e03cd1d3eb13da8bbbc20aa5bf5184 Mon Sep 17 00:00:00 2001 From: plugwash Date: Mon, 26 Jan 2009 01:16:13 +0000 Subject: [PATCH] add unitfork.pas relicensed under zlib with bewares permission git-svn-id: file:///svnroot/lcore/trunk@29 b1de8a11-f9be-4011-bde0-cc7ace90066a --- lcoretest.dpr | 5 ++- unitfork.pas | 114 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 118 insertions(+), 1 deletion(-) create mode 100755 unitfork.pas diff --git a/lcoretest.dpr b/lcoretest.dpr index 3770b19..b58e14a 100755 --- a/lcoretest.dpr +++ b/lcoretest.dpr @@ -11,7 +11,10 @@ uses dnsasync, binipstuff, sysutils, - dnssync; + dnssync, + //we don't actually make any use of lmessages in this app, we just + //include it to check if it compiles ok ;) + lmessages; {$ifdef win32} {$R *.RES} {$endif} diff --git a/unitfork.pas b/unitfork.pas new file mode 100755 index 0000000..5239fc0 --- /dev/null +++ b/unitfork.pas @@ -0,0 +1,114 @@ +{ Copyright (C) 2005 Bas Steendijk and Peter Green + For conditions of distribution and use, see copyright notice in zlib_license.txt + which is included in the package + ----------------------------------------------------------------------------- } +unit unitfork; + +interface + +procedure dofork(const programname:string); +procedure writepid; +function checkpid(const filename:string):boolean; +procedure deletepid; + +implementation + +uses + {$ifdef VER1_0} + linux, + {$else} + baseunix,unix,unixutil, + {$endif} + sysutils; + +{$include unixstuff.inc} + +const + F_WRLCK=2; + +var + pidfilename:string; + pidfile:text; + +procedure dofork(const programname:string); +var + a:integer; +begin + //writeln('dofork entered'); + //if (paramstr(1) = 'foreground') or (paramstr(1)='debug') then exit; {no fork} + a := fork; + if a = 0 then exit; {i'm the child} + if a < 0 then begin + writeln('failed to run in background, try "'+programname+' foreground" if it doesnt work otherwise'); + halt; {failed} + end; + + halt; {i'm the parent} +end; + +function checkpid; +var + handle:thandle; + +begin + result := false; + pidfilename := ''; + //debugout(filename); + assignfile(pidfile,filename); + filemode := 2; + {opening file to get a fd for it. can't rewrite because a lock appears to allow the rewrite} + {$i-}reset(pidfile);{$i+} + if ioresult <> 0 then begin + {$i-}rewrite(pidfile);{$i+} + if ioresult <> 0 then exit; + end; + + handle := getfs(pidfile); + + //debugout('got handle'); + {check if locking is possible: it's not if other process still runs} + {$ifdef VER1_0} + if not flock(handle,LOCK_EX or LOCK_NB) + {$else} + if flock(handle,LOCK_EX or LOCK_NB) <> 0 + {$endif} + then begin + //debugout('failed to lock pid file'); + close(pidfile); + exit; + end; + rewrite(pidfile); + {lock again because the rewrite removes the lock} + {$ifdef VER1_0} + if not flock(handle,LOCK_EX or LOCK_NB) + {$else} + if flock(handle,LOCK_EX or LOCK_NB) <> 0 + {$endif} + then raise exception.create('flock failed '+inttostr(linuxerror)); + pidfilename := filename; + result := true; +end; + + +procedure writepid; +begin + writeln(pidfile,getpid); + flush(pidfile); +end; + +procedure deletepid; +begin + if pidfilename = '' then exit; + try + {$i-} + closefile(pidfile); + erase(pidfile); + {$i+} + ioresult; + except + {} + end; + pidfilename := ''; +end; + +end. -- 2.30.2