ztd/src/shell.cpp
2019-11-05 09:08:57 +01:00

100 lines
2.2 KiB
C++

#include "shell.hpp"
#include <unistd.h>
#include <stdlib.h>
#include <strings.h>
#include <sys/wait.h>
#include <errno.h>
#include <signal.h>
std::string ztd::sh(const std::string& command, bool to_console)
{
return ztd::shp(command, to_console).first;
}
std::pair<std::string, int> ztd::shp(const std::string& command, bool to_console)
{
std::string ret;
FILE *stream = popen(command.c_str(), "r");
char* buff = NULL;
size_t buff_size = 0;
while (getline(&buff, &buff_size, stream) > 0)
{
if(to_console)
{
printf("%s", buff);
}
ret += buff;
}
return std::make_pair(ret, pclose(stream));
}
FILE* ztd::popen2(const char* command, const char* type, int* pid)
{
const int READ=0, WRITE=1;
pid_t child_pid;
int fd[2];
pipe(fd);
if((child_pid = fork()) == -1)
{
perror("fork");
exit(1);
}
/* child process */
if (child_pid == 0)
{
if ( index(type, 'r') != NULL )
{
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
execl("/bin/sh", "/bin/sh", "-c", command, NULL);
exit(0);
}
else
{
if ( index(type, 'r') != NULL )
{
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
}
}
if(pid != NULL)
*pid = child_pid;
if ( index(type, 'r') != NULL )
{
return fdopen(fd[READ], "r");
}
return fdopen(fd[WRITE], "w");
}
int ztd::pclose2(FILE* fp, pid_t pid)
{
int stat;
fclose(fp);
while (waitpid(pid, &stat, 0) == -1)
{
if (errno != EINTR)
{
stat = -1;
break;
}
}
return stat;
}