chicken-hackers
[Top][All Lists]
Advanced

[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.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]