У меня есть программа, которая fork()
создает новый процесс, а затем перезаписывает stdin
этого нового процесса с помощью канала моего файлового дескриптора fd
. В этом процессе я затем использую execvp()
для выполнения wc
, и он должен прочитать свой ввод от родителя. Затем в родительском элементе я пишу в конец канала для записи и, закончив запись, закрываю канал.
Проблема в том, что wc
все еще ожидает ввода, а des не выходит.
Обычно я могу остановить wc
, набрав CTRLD, но я не могу отправить это сигнал в C/C++.
Как сказать wc
прекратить чтение?
EDIT: я следовал идиоме pipe/fork/dup/exec (думаю, так она и называется).
Потоковая передача работает с другими программами, которым нужен ввод, просто wc
нужен специальный EOF
, чтобы прекратить чтение.
int in_fd[2];
//parent-child setup
pipe(in_fd);
child = fork();
if(child == 0) {
close(in_fd[1]);
dup2(in_fd[0], 0);
close(in_fd[0]);
execvp(cmdArg[0], cmdArg);
} else {
close(in_fd[0]);
in_pid = fork_in_proc();
close(in_fd[1]);
}
//writing function
pid_t fork_in_proc() {
string line;
pid_t in_pid;
if((in_pid = fork()) == 0) {
close(in_fd[0]);
ifstream file(stream_file[STREAM_IN].c_str(), ios_base::in);
if (file.bad()) {
cerr << "File read error\n";
return 1;
}
while(file.good()) {
getline(file, line);
if(file.good()) {
write(in_fd[1], line.c_str(), line.length());
}
}
int end = 3;
write(in_fd[1], &end, sizeof(end));
file.close();
close(in_fd[1]);
cout << "PIPE IN" << endl;
exit(0);
} else {
return in_pid;
}
}
Извините, если код кажется немного бессвязным. Мне пришлось собирать его из файла.
execvp
неправильно. Вторым аргументом должен быть массив строк с последней записью в массиве, равнойNULL
. - person Some programmer dude   schedule 22.11.2011wc
- person chustar   schedule 22.11.2011ios_base::in
означает, что это не код C, а код C++. Аналогичные обозначения, такие какline.length()
. - person Jonathan Leffler   schedule 22.11.2011cat
вместоwc
, чтобы увидеть, что происходит.) - person DirtY iCE   schedule 23.11.2011