summaryrefslogtreecommitdiff
path: root/21sh/mypipe/mypipe.c
blob: c019e42ac0260834fb1a1b3b3ea0474766e85af1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include "mypipe.h"

#include <fcntl.h>
#include <unistd.h>

int exec_pipe(char **argv_left, char **argv_right)
{
    int fds[2];
    if (pipe(fds))
        return 1;
    pid_t pid = fork();
    if (pid == 0)
    {
        // close read end
        close(fds[0]);
        // redirect stdout to write end
        dup2(fds[1], STDOUT_FILENO);
        // tell OS to close write end after exec
        fcntl(fds[1], F_SETFD, FD_CLOEXEC);
        // exec left
        execvp(argv_left[0], argv_left);
        return 0;
    }
    else if (pid > 0)
    {
        // close write end
        close(fds[1]);
        // redirect stdin to read end
        dup2(fds[0], STDIN_FILENO);
        // tell OS to close read end after exec
        fcntl(fds[0], F_SETFD, FD_CLOEXEC);
        // exec right
        execvp(argv_right[0], argv_right);
        // return 1
        return 1;
    }
    else
    {
        close(fds[0]);
        close(fds[1]);
        return 1;
    }
}