/
Process.cpp
123 lines (104 loc) · 2.71 KB
/
Process.cpp
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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
#include "Process.hpp"
using namespace std;
Process::Process(const std::vector<char*>& args, bool verbose) :
m_name(args[0]),
m_pid((pid_t)NULL),
m_writepipe {-1,-1},
m_readpipe {-1,-1}
{
if(args[1]==0)
{
throw "Not enough arguments!";
}
// Pipe used to write from parent to
// child process
// Parent ==> Child
if(pipe(m_writepipe) == -1)
{
perror("pipe");
throw std::string("Pipe");
}
// Pipe used to read from child to
// parent process
// Parent <== Child
if(pipe(m_readpipe) == -1)
{
perror("pipe");
throw std::string("Pipe");
}
m_pid = fork();
if(m_pid < 0)
{
perror("Process fork");
throw std::string("Process fork");
}
else if(m_pid == 0)
{
// Child Process
// Closing the write part of the
// Parent ==> Child pipe
close(PARENT_WRITE);
// Closing the read part of the
// Parent <== Child pipe
close(PARENT_READ);
dup2(CHILD_WRITE,1); close(CHILD_WRITE);
dup2(CHILD_READ,0); close(CHILD_READ);
std::vector<const char*> args;
std::transform(argss.begin(),argss.end(), std::back_inserter(args), [](std::string s)
{
return s.c_str();
} );
args.push_back( NULL );
execvp(args[0], const_cast<char**>(&args[0]));
perror("Process execvp");
throw std::string("Error Process execvp");
}
else
{
// Parent Process
// Closing the write part of the
// Parent <== Child pipe
close(m_readpipe[1]);
// Close the read part of the
// Parent ==> Child pipe
close(m_writepipe[0]);
if (verbose)
{
cout << "Process " <<m_name << ": forked m_pid " <<m_pid << endl;
}
}
};
Process::~Process()
{
if (verbose)
std::cerr << "Process " << m_name << ": Entering ~Process()" << std::endl;
int status;
pid_t pid = waitpid(m_pid, &status, 0);
if (pid < 0)
{
perror("~Process waitpid");
throw std::string("Error ~Process waitpid");
}
if (verbose)
std::cerr << "Process " << m_name << ": Leaving ~Process()" << std::endl;
// Close the two pipes between the
// parent and child process
// (from the parent process prespective)
close(PARENT_READ );
close(PARENT_WRITE);
// Kill the child process
kill(m_pid, SIGTERM);
}
void Process::write(const std::string& str)
{
write(m_writepipe[0], str.c_str(), str.length());
}
std::string Process::read(void)
{
string buffer = "test";
while(read(m_readpipe[1], buffer.c_str(), 1) > 0);
return buffer;
//For further error handling, we could check if the buffer size is less than the allocated space and returnt he errro code EFAULT
//We could check for bad file descriptors
//If its an unsuitable file, we could return an EINVAL
}