|
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