I want to send exit status 0 from the execve process to the process which started it. Because on Success execve never returns, So I am not able to do anything after that. But I want if execve ran successful.
You can verify that exec succeeded using FD_CLOEXEC
:
create a pipe.
fork.
in the child, close the read end of the pipe and set the FD_CLOEXEC
flag on the write end of the pipe. Then proceed with exec
. If exec
succeeds, the pipe will be automatically closed due to FD_CLOEXEC
. If exec
fails, write a byte to the pipe and exit.
in the parent, close the write end of the pipe and read from the read end. If you read 0 bytes (EOF), it means that exec
succeeded. If you read a byte in the pipe, it means that exec
failed.
The data written over the pipe in case of failure can be used to transmit error information, such as value of errno
after exec
.
The code, with error checking omitted for brevity, would look like this:
int pipe_fds[2];
pipe(pipe_fds);
if (!fork()) {
close(pipe_fds[0]);
fcntl(pipe_fds[1], F_SETFD, F_CLOEXEC);
execve(...);
write(pipe_fds[1], "", 1);
_exit(1);
}
else {
int n;
char out;
close(pipe_fds[1]);
n = read(pipe_fds[0], &out, 1);
if (n == 0)
printf("exec successful\n");
else
printf("exec failed\n");
close(pipe_fds[0]);
}
Note that this technique can be unsafe if other threads may exec their own processes in parallel. The issue is that there is a delay between when the pipe is created and when the close-on-exec flag gets set. If an unrelated thread forks and execs during that critical window, the child will inherit pipe_fds[1]
and won't close it, causing the parent to hang. This can be fixed using the Linux-specific pipe2
call which allows atomically creating the pipe with the close-on-exec flag set.
to wait you process launched by fork()
finish, you can use wait()
:
/* parent */
int status;
while (wait(&status) != uproc.pid) {
printf("waiting for child to exit");
}
and based on this question
The exit status of the child is provided by the wait
function, in the status
variable.
You get the exit status by using the WEXITSTATUS
macro, but only if the program exited normally (i.e. called exit
or returned from its main
function):
if (WIFEXITED(status))
printf("Child exit status: %d\n", WEXITSTATUS(status));
else
printf("Child exited abnormally\n");
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With