#ifdef WITH_LTTNG
#include <lttng/ust.h>
#endif
+#include <sstream>
+#include <string>
+
#include "include/assert.h"
#include "common/safe_io.h"
#include "common/errno.h"
forked(false)
{}
- void prefork() {
+ int prefork(std::string &err) {
assert(!forked);
int r = socketpair(AF_UNIX, SOCK_STREAM, 0, fd);
if (r < 0) {
- cerr << "[" << getpid() << "]: unable to create socketpair: " << cpp_strerror(errno) << std::endl;
- exit(errno);
+ std::ostringstream oss;
+ oss << "[" << getpid() << "]: unable to create socketpair: " << cpp_strerror(errno);
+ err = oss.str();
+ return r;
}
#ifdef WITH_LTTNG
forked = true;
childpid = fork();
+ if (childpid < 0) {
+ r = -errno;
+ oss << "[" << getpid() << "]: unable to fork: " << cpp_strerror(errno);
+ err = oss.str();
+ return r;
+ }
if (childpid == 0) {
child_after_fork();
} else {
parent_after_fork();
}
+ return 0;
}
bool is_child() {
return childpid != 0;
}
- int parent_wait() {
+ int parent_wait(std::string &err) {
assert(forked);
int r = -1;
+ std::ostringstream oss;
int err = safe_read_exact(fd[0], &r, sizeof(r));
if (err == 0 && r == -1) {
// daemonize
::close(2);
r = 0;
} else if (err) {
- cerr << "[" << getpid() << "]: " << cpp_strerror(err) << std::endl;
+ oss << "[" << getpid() << "]: " << cpp_strerror(err);
} else {
// wait for child to exit
- r = waitpid(childpid, NULL, 0);
+ int status;
+ err = waitpid(childpid, &status, 0);
+ if (err < 0) {
+ oss << "[" << getpid() << "]" << " waitpid error: " << cpp_strerror(err);
+ } else if (WIFSIGNALED(status)) {
+ oss << "[" << getpid() << "]" << " exited with a signal";
+ } else if (!WIFEXITED(status)) {
+ oss << "[" << getpid() << "]" << " did not exit normally";
+ } else {
+ err = WEXITSTATUS(status);
+ if (err != 0)
+ oss << "[" << getpid() << "]" << " returned exit_status " << cpp_strerror(err);
+ }
}
- return r;
+ err = oss.str();
+ return err;
}
int signal_exit(int r) {