Help with piping in c++

I am currently trying to make a functional shell within c++ using pipes, forks, and execvp. Currently the forking and execvp functions work, but I am having a bit of trouble piping processes together. Any idea where to implement pipes?
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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <vector>
#include <sstream>
#include <unistd.h>

using namespace std;

string command = "";
vector<string> tokens;
vector<vector<string> > commands;


void multInputs(vector<vector<string> > &commands){
    for(int i = 0; i < commands.size(); i++){
        char * args[commands[i].size()];
        
            for(int j = 0; j < tokens.size(); j++){
                args[j] =  (char *)commands[i][j].c_str();
            }
        
        args[commands[i].size()] = NULL;
        execvp(args[0],args);
    }
    
    
    
    tokens.clear();
}

void singleInput(vector<vector<string> > &commands){
    char * args[commands[0].size()];
    for(int j = 0; j < commands[0].size(); j++){
        args[j] =  (char *)commands[0][j].c_str();
    }
    args[commands[0].size()] = NULL;
    execvp(args[0], args);
}


void split(const string &s) {
    stringstream ss(s);
    string item = "";
    while (ss >> item) {
        if(item == "|"){
            commands.push_back(tokens);
            tokens.clear();
        }else{
            tokens.push_back(item);
        }
    }
    commands.push_back(tokens);
    tokens.clear();
    
    
}



int main() {
    while(true){                 //continuosly ask for user input
        cout << "$ ";
        command = "";
        getline(cin, command);
        if(command == "logout"){     //exit loop if user logs out
            cout << "Logging off" << endl;
            break;
        }
        
        split(command);
        
        
        if(fork() == 0){
            if(commands.size() == 1){    //only run if single command
                singleInput(commands);
            }else{
                multInputs(commands);
            }
        }else{
            wait(0);
        }
        commands.clear();
    }
    
    return 0;
}
Last edited on
Unix: pipe() https://www.freebsd.org/cgi/man.cgi?query=pipe&apropos=0&sektion=2&manpath=FreeBSD+11.1-RELEASE+and+Ports&arch=default&format=html

Windows: _pipe() https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/pipe


Walkthrough: http://tldp.org/LDP/lpg/node11.html
See the last part: "Often, the descriptors in the child are duplicated onto standard input or output. The child can then exec() another program, which inherits the standard streams."
Topic archived. No new replies allowed.