Board index » kylix » service start/stop

service start/stop


2005-09-19 07:05:39 PM
kylix0
Hi all
I have a daemon in Kylix and I am aware of the /etc/init.d - /etc/rcX.d
system of red hat .. but I am not sure what is the proper way to stop the
daemon.
For example Apache stops with a "stop" parameter when you call
/etc/init.d/httpd. How can I do something like this in a daemon build in
Kylix?
I have thought of a way to run a `ps ax | grep mydaemon`, capture the
process id and then send a `kill -TERM pid` instead of forking. But what is
the proper way for stopping a daemon?
TIA
Alex
 
 

Re:service start/stop

Hello Alex,
A daemon starts and stops based on the
runlevel. On my SUSE distribution I think
there is a skeleton.rc file that shows the
general structure and you plug your app
into that skeleton structure. Commands
are start/status/stop. Hope this help. I
have done this with for a Kylix based
web services app - it took a day or
two to figure out.
-- Mike Gallets, Giant Systems
 

Re:service start/stop

Yes I know about the run levels; when the machine shuts down it calls
`/etc/init.d/myapp stop` .. my question is how do I program my daemon to
respond gently to the "stop" parameter of that call.
Until now the program starts, forks and halts. What is the correct approach
to halt the forked process?
 

{smallsort}

Re:service start/stop

alex wrote:
Quote
Yes I know about the run levels; when the machine shuts down it calls
`/etc/init.d/myapp stop` .. my question is how do I program my daemon to
respond gently to the "stop" parameter of that call.

Until now the program starts, forks and halts. What is the correct approach
to halt the forked process?

Generally your process should be able to catch SIGTERM
and in response clean up and terminate in good order.
Under SuSE the standard scripts use 'startproc' and
'killproc' to handle process start and stop. killproc
is normally configured to send a SIGTERM.
Alternatively you may have to create your own command
sequences to start and stop your daemon. The simplest
way to deal with this is to have the daemon save it's
main process ID in a file (eg. /var/run/yourproc.pid').
Then you can arrange to send a SIGTERM to it using
kill -TERM `cat /var/run/yourproc.pid`
When writing a daemon I usually provide a command line
option to pass the name of the file into which the PID
is stored (if not specified then the PID is not stored)
after the daemon has forked itself. It's useful for
writing scripts that control the process during testing.
This is the code I use for the main process in the
daemon after it has forked and then set up its
working threads, leaving the main thread to just
to catch the termination signals. The larger procedure
below is called after initialisation and when
it returns the cleanup and termination is performed.
The default signal handler simply sets a termination
flag. The signal will cause Libc.pause to return which
allows the termination flag to be tested within the
main thread's context. If the signal was caught and
handled but the termination flag was not set the
main thread just goes back to sleep again with
Libc.pause. I catch SIGINT as well as SIGTERM because
this code is also used when the process is run
without being daemonised when being tested from the
command line. (This also means it's useful to ensure
SIGWINCH is ignored).
var
Terminated: Boolean;
procedure OkDefaultSignal(SigNum: Integer); cdecl;
begin
Terminated := True;
end;
procedure OkApplicationRun;
var
oldsigint: TSignalHandler;
oldsigterm: TSignalHandler;
oldsigwinch: TSignalHandler;
begin
Terminated := False;
// Unhook SigInt. This allows it to be caught here otherwise
// the Kylix runtime will catch it and our signal handler
// will not be called. (This appears to be a Kylix 2 or 3
// change as Kylix 1 appeared to allow our SigInt handler
// to be run.
UnhookSignal(RTL_SIGINT);
oldsigint := Libc.signal(SIGINT, OkDefaultSignal);
oldsigterm := Libc.signal(SIGTERM, OkDefaultSignal);
// Ignore this as it tends to cause hassle when running
// from the command line in a window if the window is
// resized.
oldsigwinch := Libc.signal(SIGWINCH, TSignalHandler(SIG_IGN));
try
while not Terminated do
begin
Libc.pause;
end;
finally
Libc.signal(SIGINT, oldsigint);
Libc.signal(SIGTERM, oldsigterm);
Libc.signal(SIGWINCH, oldsigwinch);
end;
end;
Note the call to UnhookSignal to stop the run time library
processing SIGINT.
------------
Andrew.
 

Re:service start/stop

thank you Andrew