Thanks, I made it a bit more simple:
use POSIX;
if (! fork) { # child
setsid;
POSIX::close(0);
POSIX::close(1);
exec("restart-apache-command");
}
Works great!
Thanks,
Dirk
Torsten Foertsch writes:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> On Tuesday 12 August 2003 11:50, Dirk Lutzebaeck wrote:
> > Dennis Stout writes:
> > > On a whim, I would try writing a second script to do the actual shutdown
> > > and restart of Apache.
> > >
> > > Then have your mod_perl program either run it in the background (with a
> > > &) or fork it into another process.
> >
> > Did exactly that but is has the effect that when the parent (root)
> > apache is killed it kills all children including the script itself. So
> > the server wont start again.
>
> I have done something like this several times. My code (it works since 1998 on
> a highly used WEB Server with perl5.005_3) looks like that:
>
> ...
>
> sub sysclose {
> require 'syscall.ph';
> syscall &SYS_close, shift()+0;
> }
>
> sub RLIMIT_NOFILE {7;} # this is for LINUX
> sub getrlimit {
> require 'syscall.ph';
> my $x="x"x8; # result
> syscall &SYS_getrlimit, shift()+0, $x;
> unpack "ii", $x;
> }
>
> sub close_fd {
> my @l=getrlimit( RLIMIT_NOFILE );
> my $l;
>
> for( $l=0; $l<$l[0]; $l++ ) {
> next if( $l==2 ); # close all file descriptors except of STDERR
> sysclose $l;
> }
> }
>
> sub disconnect_from_apache {
> use POSIX qw/setsid/;
>
> setsid;
> close_fd;
> }
>
> ...
>
> my $child=fork;
> unless( defined $child ) {
> ...
> return OK;
> }
> if( $child ) {
> my $child_status=0;
> if( waitpid( $child, 0 )==$child ) {
> $child_status=$?;
> }
>
> if( $child_status==0 ) {
> ...
> return OK;
> } else {
> # The first fork succeeded but the second failed
> ...
> return OK;
> }
> } else {
> # Child process: fork again to detach from parent process
> $child=fork;
> CORE::exit( 0 ) if( $child ); # parent exits
> unless( defined $child ) {
> ...
> CORE::exit( 1 );
> }
> # Now we are the 2nd child process.
> $self->disconnect_from_apache;
> $self->doit( ... ); # <== here comes the real code
> CORE::exit( 0 );
> }
>
> ...
>
> $self->doit() is called in a separate process group and is not killed by a
> signal sent to the apache process group. Further, all files save STDERR are
> closed. This is needed since the code runs under mod_perl and the long
> running child process inherits the open connection to the browser. If this
> connection is not closed the browser shows an endless spinning globe or
> something like that in the upper right corner.
>
> Torsten
> -----BEGIN PGP SIGNATURE-----
> Version: GnuPG v1.0.7 (GNU/Linux)
>
> iD8DBQE/OSIAwicyCTir8T4RAv3RAKCXdpbHLQepeOZFCyXt1KkMVGnwPgCeNu7X
> hlC1NSEv0NsA7LlM7lol7wI=
> =xId6
> -----END PGP SIGNATURE-----
>