131 lines
3.1 KiB
C++
131 lines
3.1 KiB
C++
#include "mainwindow.h"
|
|
|
|
using namespace std;
|
|
|
|
#define READ 0
|
|
#define WRITE 1
|
|
|
|
//Take a string and explode it in array
|
|
// s => string to explode
|
|
// c => character separator
|
|
// n => number of results in array, the last is the rest of string to end
|
|
const vector<string> explode(const string& s, const char& c, int n = 0)
|
|
{
|
|
string buff;
|
|
vector<string> v;
|
|
size_t pos = 0;
|
|
size_t ppos = 0;
|
|
int i = 0;
|
|
|
|
while (i < n - 1)
|
|
{
|
|
pos = s.find(c, ppos);
|
|
if (pos != string::npos)
|
|
{
|
|
buff = s.substr(ppos, pos - ppos);
|
|
if (buff != "")
|
|
{
|
|
i++;
|
|
v.push_back(s.substr(ppos, pos - ppos));
|
|
}
|
|
ppos = pos + 1;
|
|
}else
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
if (ppos < s.size())
|
|
{
|
|
v.push_back(s.substr(ppos));
|
|
}
|
|
return v;
|
|
}
|
|
|
|
// open a pipe, fork and return pid of child
|
|
// argv => array of string with command in first and parameters following
|
|
FILE * popen2(array<string,8> argv, string type, int & pid)
|
|
{
|
|
pid_t child_pid;
|
|
int fd[2];
|
|
QString message;
|
|
string command;
|
|
|
|
if (pipe(fd) == -1)
|
|
{
|
|
message = "Open pipe failed" + QString::fromStdString(strerror(errno));
|
|
QMessageBox::warning(
|
|
NULL,
|
|
"RsyncUI",
|
|
message);
|
|
exit(-1);
|
|
}else
|
|
{
|
|
if((child_pid = fork()) == -1)
|
|
{
|
|
perror("fork");
|
|
exit(1);
|
|
}
|
|
|
|
/* child process */
|
|
if (child_pid == 0)
|
|
{
|
|
if (type == "r")
|
|
{
|
|
close(fd[READ]); //Close the READ end of the pipe since the child's fd is write-only
|
|
dup2(fd[WRITE], 1); //Redirect stdout to pipe
|
|
}
|
|
else
|
|
{
|
|
close(fd[WRITE]); //Close the WRITE end of the pipe since the child's fd is read-only
|
|
dup2(fd[READ], 0); //Redirect stdin to pipe
|
|
}
|
|
|
|
setpgid(child_pid, child_pid); //Needed so negative PIDs can kill children of /bin/sh
|
|
//TODO : change for execvp
|
|
|
|
if (execlp(argv[0].c_str(), argv[0].c_str(), argv[1].c_str(), argv[2].c_str(), argv[3].c_str(), argv[4].c_str(), argv[5].c_str(), NULL ) == -1)
|
|
exit (0);
|
|
}
|
|
else
|
|
{
|
|
if (type == "r")
|
|
{
|
|
close(fd[WRITE]); //Close the WRITE end of the pipe since parent's fd is read-only
|
|
}
|
|
else
|
|
{
|
|
close(fd[READ]); //Close the READ end of the pipe since parent's fd is write-only
|
|
}
|
|
}
|
|
|
|
pid = child_pid;
|
|
if (type == "r")
|
|
{
|
|
return fdopen(fd[READ], "r");
|
|
}
|
|
return fdopen(fd[WRITE], "w");
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
// close pipe open by popen2 while pid is finished
|
|
// fp => file pointer
|
|
// pid => pid of the processus open bu popen2
|
|
|
|
int pclose2(FILE * fp, pid_t pid)
|
|
{
|
|
int stat;
|
|
|
|
fclose(fp);
|
|
while (waitpid(pid, &stat, 0) == -1)
|
|
{
|
|
if (errno != EINTR)
|
|
{
|
|
stat = -1;
|
|
break;
|
|
}
|
|
}
|
|
return stat;
|
|
}
|
|
|