posix: osiSpawnDetachedProcess() find out if exec() errors.
Presently, success just means fork()
This commit is contained in:
@@ -24,7 +24,9 @@
|
||||
#include <unistd.h>
|
||||
#include <sched.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <pwd.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "osiProcess.h"
|
||||
#include "errlog.h"
|
||||
@@ -61,12 +63,18 @@ LIBCOM_API osiSpawnDetachedProcessReturn epicsStdCall osiSpawnDetachedProcess
|
||||
(const char *pProcessName, const char *pBaseExecutableName)
|
||||
{
|
||||
int status;
|
||||
int fds[2]; /* [reader, writer] */
|
||||
|
||||
if(pipe(fds))
|
||||
return osiSpawnDetachedProcessFail;
|
||||
|
||||
/*
|
||||
* create a duplicate process
|
||||
*/
|
||||
status = fork ();
|
||||
if (status < 0) {
|
||||
close(fds[0]);
|
||||
close(fds[1]);
|
||||
return osiSpawnDetachedProcessFail;
|
||||
}
|
||||
|
||||
@@ -75,11 +83,29 @@ LIBCOM_API osiSpawnDetachedProcessReturn epicsStdCall osiSpawnDetachedProcess
|
||||
* in the initiating (parent) process
|
||||
*/
|
||||
if (status) {
|
||||
return osiSpawnDetachedProcessSuccess;
|
||||
}
|
||||
osiSpawnDetachedProcessReturn ret = osiSpawnDetachedProcessSuccess;
|
||||
char buf;
|
||||
ssize_t n;
|
||||
close(fds[1]);
|
||||
|
||||
/*
|
||||
* This is executed only by the new child process.
|
||||
n = read(fds[0], &buf, 1);
|
||||
/* Success if child exec'd without sending a '!'.
|
||||
* Of course child may crash soon after, but can't
|
||||
* wait around for this to happen.
|
||||
*/
|
||||
if(n!=0) {
|
||||
ret = osiSpawnDetachedProcessFail;
|
||||
}
|
||||
|
||||
close(fds[0]);
|
||||
return ret;
|
||||
}
|
||||
close(fds[0]);
|
||||
(void)fcntl ( fds[1], F_SETFD, FD_CLOEXEC );
|
||||
|
||||
/* This is executed only by the new child process.
|
||||
* Since we may be called from a library, we don't assume that
|
||||
* all other code has set properly set FD_CLOEXEC.
|
||||
* Close all open files except for STDIO, so they will not
|
||||
* be inherited by the new program.
|
||||
*/
|
||||
@@ -89,6 +115,8 @@ LIBCOM_API osiSpawnDetachedProcessReturn epicsStdCall osiSpawnDetachedProcess
|
||||
if (fd==STDIN_FILENO) continue;
|
||||
if (fd==STDOUT_FILENO) continue;
|
||||
if (fd==STDERR_FILENO) continue;
|
||||
/* pipe to our parent will be closed automatically via FD_CLOEXEC */
|
||||
if (fd==fds[1]) continue;
|
||||
close (fd);
|
||||
}
|
||||
}
|
||||
@@ -115,6 +143,10 @@ LIBCOM_API osiSpawnDetachedProcessReturn epicsStdCall osiSpawnDetachedProcess
|
||||
fprintf ( stderr, "**** You may need to modify your PATH environment variable.\n" );
|
||||
fprintf ( stderr, "**** Unable to start \"%s\" process.\n", pProcessName);
|
||||
}
|
||||
/* signal error to parent */
|
||||
ssize_t ret = write(fds[1], "!", 1);
|
||||
(void)ret; /* not much we could do about this */
|
||||
close(fds[1]);
|
||||
/* Don't run our parent's atexit() handlers */
|
||||
_exit ( -1 );
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user