Boost logo

Boost :

From: Oliver.Kowalke_at_[hidden]
Date: 2006-08-17 08:33:14


Hello,
for posix_start I would suggest following in order to pass the error of
::execve to the parrent:

int fd[2];
if ( ::pipe( fd) < 0) // create a pipe
        throw sys::system_error( errno, sys::errno_ec);
        
if ( ( pid = ::fork() ) < 0) // fork new process
        throw sys::system_error( errno, sys::errno_ec);

if ( pid == 0) // child
{
        ::close( fd[0]); // close one end of the pipe
        ::fcntl( fd[1], F_SETFD, FD_CLOEXEC); // close other end of pipe
if this process is replaced by ::execve

        struct sigaction act; // clear all signal handlers
        ::sigemptyset( & act.sa_mask);
        act.sa_handler = SIG_DFL;
        act.sa_flags = 0;
        for ( int sig = 1; sig < NSIG; sig++)
                ::sigaction( sig, & act, 0);

        ...

        ::execve( cl.get_executable().c_str(), args.second, envp); //
replace by new application

        int msg = errno; // reached only if ::execve failed
        ::write( fd[1], & msg, sizeof msg); // write error number to
pipe
        ::_exit( errno); // exit
}

// parent
::close( fd[1]); // close one end of pipe
while( true)
{
        int msg; // error number passed from child process
        int n = ::read( fd[0], & msg, sizeof msg);
        if ( n == sizeof( int) )
        {
                // child has written something to pipe
                ::close( fd[0]);
                throw sys::system_error( msg, sys::errno_ec) );
        }
        else if (n == -1)
        { if ( errno == EINTR) continue; } // interrupted
        break; // EOF of pipe
}

::close( fd[0]);
return child( pid);

regards,
Oliver


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk