[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Chicken-hackers] Fixing the "process" procedure to be safe against
From: |
Lassi Kortela |
Subject: |
Re: [Chicken-hackers] Fixing the "process" procedure to be safe against execve() errors |
Date: |
Thu, 25 Jul 2019 21:26:51 +0300 |
User-agent: |
Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:60.0) Gecko/20100101 Thunderbird/60.8.0 |
I think so, but must confess I don't fully understand the issue.
No problem. The outline of the problem and its solution is this:
// This code runs in the parent process.
pipe_read_fd, pipe_write_fd = pipe();
child = fork();
if (!child) {
// This code runs in the child process.
execve(exefile, argv, envp);
// A successful execve() does not return. But a failed one
// does! E.g. when "exefile" does not exist. The errno
// variable gives the cause of the failure. But since we are
// in the child process, how do we return the errno value to
// the parent process?
//
// We could use something like exit(errno) but that's unwise
// since the parent has no way to distinguish between the exit
// code from the "exefile" process in case of a successful
// execve(), and the errno value from exit(errno) in the case
// of a failed execve.
//
// What we can do, is to use a pipe between parent and child.
// If we set the close-on-exec flag on the pipe's file
// descriptors, then the pipe will be automatically closed by
// the Unix kernel on a successful execve(). But on a failed
// exec the pipe will remain open, and the child process can
// write the errno value to the pipe. (The value can be
// encoded as a 32-bit integer, for example.)
write(pipe_write_fd, (int32_t)errno, sizeof(int32_t));
exit(1); // any nonzero exit code is fine
}
// This runs in the parent process.
poll(pipe_read_fd);
// Read from pipe_read_fd here if poll says it's readable. If
// read() returns zero bytes then the pipe was closed by the
// kernel due to a successful execve().
waitpid(child, &status); // Wait for the child to finish.
If you want me to clarify any details, just ask :)
Very good! You could call poll() directly, but that would block other
threads from executing. So what you typically do is call
##sys#thread-block-for-i/o! on the fd followed by ##sys#thread-yield!
to actually suspend the thread.
Awesome, thanks a lot! I knew you guys had a solution ready.