-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathProcess.cpp
More file actions
135 lines (121 loc) · 3.21 KB
/
Process.cpp
File metadata and controls
135 lines (121 loc) · 3.21 KB
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
124
125
126
127
128
129
130
131
132
133
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <unistd.h>
#include <sys/wait.h>
#include "Process.hpp"
#include <algorithm>
Process::Process(const std::vector<std::string>& argss, bool verbose) :
verbose(verbose),
m_name(argss[0]),
m_pid((pid_t)NULL),
m_writepipe {-1,-1},
m_readpipe {-1,-1},
m_pwrite((FILE*)NULL),
m_pread((FILE*)NULL)
{
if (pipe(m_writepipe) < 0 || pipe(m_readpipe) < 0)
{
perror("pipe");
throw std::string("Pipe");
}
if ((m_pid = fork()) < 0)
{
perror("Process fork");
throw std::string("Process fork");
} else if ( m_pid == 0 ) {
/* child process */
close(PARENT_READ);
close(PARENT_WRITE);
//Add error checking for dup2(CHILD_WRITE,1)
if ((dup2(CHILD_WRITE,1)) < 0)
{
perror("Process dup2 child write");
throw std::string("Process dup2 child write");
} else {
dup2(CHILD_WRITE,1);
close(CHILD_WRITE);
}
//Add error checking for dup2(CHILD_READ,1)
if ((dup2(CHILD_READ,1)) < 0)
{
perror("Process dup2 child read");
throw std::string("Process dup2 child read");
} else {
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[1], const_cast<char**>(&args[1]));
perror("Process execvp");
throw std::string("Process execvp");
} else {
/* parent process */
if (verbose)
std::cerr << "Process " << m_name << ": forked PID " << m_pid << std::endl;
close(CHILD_READ);
close(CHILD_WRITE);
//Add error checking for fdopen for PARENT_READ..null is return if open fails
if ( fdopen(PARENT_READ, "r") == NULL)
{
perror("Process fdopen failed");
throw std::string("Process fdopen failed");
} else {
m_pread = fdopen(PARENT_READ, "r");
}
//Add error checking for fdopen for PARENT_WRITE..null is retruned if open fails
if (fdopen(PARENT_WRITE, "w") == NULL)
{
perror("Process fdopen failed");
throw std::string("Process fdopen failed");
} else {
m_pwrite = fdopen(PARENT_WRITE, "w");
}
}
}
Process::~Process()
{
if (verbose)
std::cerr << "Process " << m_name << ": Entering ~Process()" << std::endl;
fclose(m_pwrite);
int status;
pid_t pid = waitpid(m_pid, &status, 0);
if (pid < 0)
perror("~Process waitpid");
fclose(m_pread);
if (verbose)
std::cerr << "Process " << m_name << ": Leaving ~Process()" << std::endl;
}
void Process::write(const std::string& line)
{
//Add error checking for fputs...returns negative value if failure
if (fputs(line.c_str(), m_pwrite) < 0)
{
perror("Process fputs failed");
throw std::string("Process fputs failed");
} else {
fputs(line.c_str(), m_pwrite);
}
//Add error checking for fflush...returns 0 when success otherwise EOF and erno is set
if (fflush(m_pwrite) !=0)
{
perror("Process fflush failed");
throw std::string("Process fflush failed");
} else {
fflush(m_pwrite);
}
}
std::string Process::read()
{
std::string line;
char* mystring = NULL;
size_t num_bytes;
getline(&mystring, &num_bytes, m_pread);
line = mystring;
return line;
}