Попытка реализовать оболочку с execp, dup2 и pipe, зависаниями или «плохим дескриптором файла»

Я пытаюсь реализовать оболочку с трубопроводами в C ++. У меня работают команды, но как только включаются каналы, все перестает работать. Я покажу вам, что я имею в виду. Вот код:

    int inPipe[2];
int outPipe[2];
pipe(inPipe);
pipe(outPipe);

int std_in = dup(0);
int std_out = dup(1);
std::for_each(cmds.begin(), cmds.end(), [&](Command command){
//printf("Executing [%s] \n", command.args[0].c_str());
auto pid = fork();
if(pid==-1) {
std::cerr << "Could not fork\n";
return;
}
if (pid==0) {
//std::cout << "Child\n";

if(command.inFile == "none") {
printf("In, none.\n");
dup2(std_in, 0);
close(std_in);
}
else if(command.inFile == "pipe") {
printf("In, pipe.\n");
dup2(inPipe[0], 0);
close(inPipe[0]);
}

if(command.outFile == "none") {
printf("Out, none.\n");
dup2(std_out, 1);
close(std_out);
}
else if(command.outFile == "pipe") {
printf("out, pipe.\n");
dup2(outPipe[1], 1);
close(outPipe[1]);
}

const char* name = command.args[0].c_str();
char** args = new char*[command.args.size()];
for(int i=0; i<command.args.size(); i++) {
args[i] = new char[command.args[i].size()];
strcpy(args[i], command.args[i].c_str());
}

execvp(name, args);
exit(errno);
}
else {
//std::cout << "Parent\n";
int status;
auto before = std::chrono::system_clock::now();

dup2(outPipe[0], inPipe[0]);
dup2(outPipe[1], inPipe[1]);
close(outPipe[0]);
close(outPipe[1]);
pipe(outPipe);

waitpid(pid, &status, 0);auto after = std::chrono::system_clock::now();
std::chrono::duration<double> ptime = after-before;
elapsed_time = elapsed_time + ptime.count();
}
});

Когда я запускаю команды с одним каналом, например, «ls», все работает нормально. Однако, если я использую ls | сортировка, это дает это сообщение об ошибке:

ls: cannot access : No such file or directory

и затем зависает, пока я не смогу оттуда выйти. Я думаю, что зависание происходит от того, что я каким-то образом неправильно обращаюсь с каналами (не закрывая их), но я не знаю, где и сколько раз это вставить. Я думаю, что «не могу получить доступ» происходит от того, что я потерял std_in, прежде чем смог вызвать Так или иначе. Я новичок почти во всех этих функциях (dup2, fork, execp, pipe и т. Д.), Поэтому я чувствую, что мои догадки и проверки больше похожи на 6-раундовую русскую рулетку.

В любом случае, любая помощь приветствуется. Спасибо!

0

Решение

Проверьте имя переменной и аргументы,
одно из этих значений может быть NULL

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]