#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main() {
pid_t childpid;
int fd[2];
if ((pipe(fd) == -1) || ((childpid = fork()) == -1)) {
perror("Failed to setup pipeline");
return 1;
}
if (childpid == 0) {
if (dup2(fd[1], STDOUT_FILENO) == -1)
perror("Failed to redirect stdout of ls");
if ((close(fd[0]) == -1) || (close(fd[1])) == -1)
perror("Failed to close extra pipe descriptors on ls");
else {
execl("/bin/ls", "ls", "-l", NULL);
perror("Failed to exec ls");
}
return 1;
}
if (dup2(fd[0], STDIN_FILENO) == -1)
perror("Failed to redirect stdin of sort");
if ((close(fd[0]) == -1) || (close(fd[1]) == -1))
perror("Failed to close extra pipe descriptors on sort");
else {
execl("/usr/bin/sort", "sort", "-n", "+4", NULL);
perror("Failed to exec sort");
}
return 1;
}
➜ ./simpleredirect
total 104
drwxr-xr-x 3 tonghui staff 96 7 23 15:24 simpleredirect.dSYM
-rw-r--r--@ 1 tonghui staff 747 7 22 11:32 parentwritepipe.c
-rw-r--r--@ 1 tonghui staff 989 7 23 16:28 simpleredirect.c
-rw-r--r--@ 1 tonghui staff 999 7 22 13:17 synchronizefan_pipe.c
-rw-r--r--@ 1 tonghui staff 1033 7 23 13:14 simpleredirect_1.c
-rwxr-xr-x 1 tonghui staff 34059 7 23 16:28 simpleredirect
➜ lldb simpleredirect
(lldb) target create "simpleredirect"
Current executable set to '/Users/specialfile/simpleredirect' (arm64).
(lldb) r
Process 49076 launched: '/Users/workspace/code-container/c/unix/specialfile/simpleredirect' (arm64)
Process 49076 exited with status = 5 (0x00000005) Terminated due to signal 5
(lldb) n
error: Command requires a process which is currently stopped.
lldb terminated Process 49190 exited with status = 5 (0x00000005) Terminated due to signal 5
darwin systems don't allow binaries to be debugged by default. They either have to be ad hoc codesigned, or signed with the get-task-allow
entitlement set to "true". System binaries are always codesigned by Apple and generally don't have that entitlement, and so can't be debugged. If you really need to debug a system binary you have to turn off SIP.
The way you've written your code, you execl
/usr/bin/ls
in the forked child (which would be fine) AND /usr/bin/sort
on the parent side of the fork at line 27.
When you are running under the debugger and try to exec as opposed to fork/exec a system binary, your program will get killed in exec, otherwise that would provide a backhand way to debug a system binary that didn't opt into being debugged. Your program gets killed in a not very helpful way, because the system doesn't want the give the debugger any leeway to try to make the debug session work somehow, so it terminates it with "extreme prejudice".