Вы создаете канал и закрываете конец чтения, но никогда не говорите, что канал должен быть стандартным.
Звучит так, как будто вы намеревались вместо этого: 1. открыть канал только в дочернем элементе, 2. закройте конец write
, чтобы данные не могли быть прочитаны, 3. установите конец чтения как стандартный:
else { // Background
args[currArgsIndex-1] = NULL;
if((child_pid = fork()) == 0) {
int process_pipe[2];
pipe(process_pipe); // Piping
dup2(process_pipe[0], 0); // Copy read end as stdin
close(process_pipe[0]); // Close FD that is now unused
close(process_pipe[1]); // Close write end so no data can be read
execvp(filepath, args);
perror("execvp failed");
exit(1); // exit with error
}
}
Хотя нет смысла иметь канал. Вы можете более просто открыть /dev/null
для чтения и установки как stdin. В качестве альтернативы, просто закройте stdin
полностью (некоторые программы будут жаловаться):
else { // Background
args[currArgsIndex-1] = NULL;
if((child_pid = fork()) == 0) {
close(0); // Close stdin
execvp(filepath, args);
/* error handling */
}
Имейте в виду, что реальные оболочки позволяют перенаправлять на фоновые процессы, и в этом случае ничего из вышеперечисленного не будет работать:
wc -l < myfile &
Реальные оболочки фактически не будут закрывать или перенаправлять стандартный ввод, но помещают команду в свою собственную группу процессов, которая не управляет терминалом. Затем процесс получит SIGTSTP при попытке чтения из стандартного ввода, а затем вы можете использовать fg
, чтобы вывести его на передний план и начать вводить данные.