#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <sys/wait.h>
#include <sys/errno.h>
extern char **environ;
int main() {
int status;
int exec_result;
int pipe_fds[2];
// We'll create a pipe (a one-way communication channel) to send any
// exec errors from the child to the parent. If nothing is sent, the
// exec was successful.
if (pipe(pipe_fds) == -1) {
perror("pipe failed");
return 1;
}
pid_t pid = fork();
if (pid == 0) { // Child process
close(pipe_fds[0]); // Close the read end of the pipe in the child
char *argv[] = {"echo", "hello", "world", NULL};
int fd = open("hello.txt", O_WRONLY | O_CREAT | O_TRUNC, 0644);
if (fd != -1) {
dup2(fd, STDOUT_FILENO); // Redirect stdout to the file
close(fd);
}
// Set the pipe to close on exec
fcntl(pipe_fds[1], F_SETFD, FD_CLOEXEC);
execve("/bin/doesntexist", argv, environ); // Never returns if successful
exec_result = errno;
write(pipe_fds[1], (char *)&exec_result, sizeof(exec_result));
_exit(1); // In case exec fails
}
// Parent process
if (pid == -1) {
perror("fork failed");
return 1;
}
close(pipe_fds[1]); // Close the write end of the pipe in the parent
printf("Created child process ID: %d\n", pid);
status = read(pipe_fds[0], (char *)&exec_result, sizeof(exec_result));
if (status > 0) {
printf("Child failed to exec: %s\n", strerror(exec_result));
return 2;
} else {
printf("Child ran exec successfully!\n");
}
waitpid(pid, &status, 0);
if (WIFEXITED(status)) {
printf("Child exited with status: %d\n", WEXITSTATUS(status));
} else {
printf("Child exited abnormally\n");
}
return 0;
}