Skip to content

Instantly share code, notes, and snippets.

@itsPG
Created October 7, 2013 06:41
Show Gist options
  • Save itsPG/6863414 to your computer and use it in GitHub Desktop.
Save itsPG/6863414 to your computer and use it in GitHub Desktop.
os hw3 sol ? I'm not sure it is the solution or not.
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
#include <fcntl.h>
using namespace std;
class rika
{
public:
string err_msg_filename;
int err_msg_fd;
rika() { err_msg_filename = "Y_msg"; err_msg_fd = -1;}
int init() { err_msg_fd = open(err_msg_filename.c_str(), O_WRONLY | O_NONBLOCK); }
int overwrite_stderr()
{
dup2(err_msg_fd, 2);
close(err_msg_fd);
}
};
class yozora
{
public:
int fd[1000][2], fd_max;
int err_msg_fd;
int create(int m)
{
fd_max = m;
for (int i = 0; i < fd_max; i++) pipe(fd[i]);
}
int clear()
{
for (int i = 0; i < fd_max; i++)
{
close(fd[i][0]);
close(fd[i][1]);
}
}
int clear_stdio(int no)
{
close(fd[no][0]);
close(fd[no+1][1]);
}
int overwrite_stdin(int no) { dup2(fd[no][0], 0); }
int overwrite_stdout(int no) { dup2(fd[no+1][1], 1); }
};
class sena
{
public:
vector<string> cmd_ary;
vector<int> cmd_spliter;
int cmd_size;
int parse(string q)
{
cmd_ary.clear();
cmd_spliter.clear();
cmd_spliter.push_back(-1);
istringstream ssin(q);
string tmp;
while (ssin >> tmp)
{
cmd_ary.push_back(tmp);
if (tmp == "|") cmd_spliter.push_back(cmd_ary.size() - 1);
}
cmd_spliter.push_back(cmd_ary.size());
cmd_size = cmd_spliter.size()-1;
}
int exec(int no)
{
char* ary_tmp[1000] = {0};
for (int i = cmd_spliter[no] + 1, j = 0; i < cmd_spliter[no+1]; i++, j++)
{
ary_tmp[j] = (char*)(cmd_ary[i].c_str());
}
execvp(ary_tmp[0], ary_tmp);
}
};
int kobato(string cmd)
{
sena a;
yozora b;
a.parse(cmd);
b.create(a.cmd_size);
for (int i = 0; i < a.cmd_size; i++)
{
int pid;
if (pid = fork())
{
b.clear_stdio(i);
waitpid(-1, 0, 0);
}
else
{
if (i != 0) b.overwrite_stdin(i);
if (i != a.cmd_size - 1) b.overwrite_stdout(i);
b.clear();
a.exec(i);
}
}
}
void handler(int sig_no)
{
cout << endl << "Bye Bye~" << endl;
exit(0);
}
int main()
{
string cmd;
if (signal(SIGINT, handler) == SIG_ERR)
{
perror("Can't set SIGUSR1: \n");
exit(1);
}
cout << "Yuki.N > ";
rika err_msg;
err_msg.init();
while (getline(cin, cmd))
{
if (fork())
{
waitpid(-1, 0, 0);
cout << "Yuki.N > ";
}
else
{
err_msg.overwrite_stderr();
kobato(cmd);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment