-
Notifications
You must be signed in to change notification settings - Fork 0
/
ExternalCommands.cpp
executable file
·60 lines (55 loc) · 1.56 KB
/
ExternalCommands.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
#include "ExternalCommands.h"
#include "SmallShell.h"
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
ExternalCommand::ExternalCommand(const char *cmd_line, time_t timeout) : Command(cmd_line), cmd_line(cmd_line), timeout(timeout)
{
this->_executeInBackground = CommandUtils::_isBackgroundComamnd(cmd_line);
}
void ExternalCommand::execute()
{
// Create a forked external process
pid = fork();
if (pid == 0)
{
// Prepare input array
char **arg_v = new char *[cmd_v.size() + 1];
for (size_t i = 0; i < cmd_v.size(); i++)
{
arg_v[i] = new char[cmd_v[i].length() + 1];
strcpy(arg_v[i], cmd_v[i].c_str());
}
arg_v[cmd_v.size()] = NULL;
// Child process
setpgrp();
if (execvp(cmd_v[0].c_str(), arg_v) == -1)
{
// TODO: Handle error, check required message
perror("smash error: execvp");
exit(1);
}
}
else if (pid < 0)
{
// TODO: Handle error, check required message
perror("smash error: fork");
}
// Parent process
else
{
// add to jobs list
if (!this->_executeInBackground)
{
// wait for child process to finish
pid_t pidr = waitpid(pid, NULL, 0);
if (pidr == -1)
{
perror("smash error: waitpid");
}
return;
}
auto jobEntry = SmallShell::getInstance().getJobsList().addJob(pid, this->cmd_line, this->timeout);
this->job_id = jobEntry;
}
}