Я не думаю, что это возможно, используя именованные каналы, если вы не можете изменить поведение программы. Так как по сути именованные каналы ничем не отличаются, то выдача вывода из стандартного ввода с перенаправлением.
Я также не думаю, что это возможно, если вы используете конвейер или свойства перенаправления оболочки, поскольку в этом случае в вашу программу всегда отправляется EOF, и вы не можете игнорировать EOF, поскольку вы не можете изменять программу.
Возможное решение - использовать обертку. Оболочка сначала прочитает подготовленный ввод, отправит их в вашу программу, после того как подготовленный ввод завершит, оболочка переключится на стандартный ввод. Фактическая программа просто продолжает потреблять ввод, она не знает о фактическом источнике данных.
Единственным недостатком является то, что вы не можете предоставить подготовленный ввод с помощью каналов или перенаправления, вы должны указать имя файла. (Я не уверен, что именованный канал будет работать или нет.) Причина очевидна: если вы предоставляете подготовленный ввод для оболочки из стандартного ввода, то такая же проблема существует для оболочки. Таким образом, вы просто делегируете проблему оболочке, которую можете создавать любым способом.
Возможная реализация в C (модифицированная из аналогичной оболочки, которую я использовал, не тестировалась):
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <fcntl.h>
int main(int argc, char * argv[]) {
char c;
char **pargs ;
char buf[20];
int n;
int pipe_fd[2];
int pid;
pargs = argv+2;
if (pipe(pipe_fd) < 0) {
perror("pipe failed");
exit(errno);
}
if ((pid=fork()) < 0) {
perror ("Fork failed");
exit(errno);
}
if (! pid) {
close(pipe_fd[1]);
dup2(pipe_fd[0],0);
close(pipe_fd[0]);
if (execvp(argv[2],pargs) < 0) {
perror("Exec failed");
exit(errno);
}
} else {
size_t filedesc = open(argv[1],O_RDONLY);
while((n = read(filedesc, buf, 100)) > 0)
write (pipe_fd[1], buf, n);
while((n = read(0, buf, 100)) > 0)
write (pipe_fd[1], buf, n);
}
}
Вы можете запустить вашу программу с помощью этой оболочки как:
./wrapper input.txt myprog possible command line arguments
Вы можете поместить свой начальный ввод в input.txt
.
Более простое решение - заново открыть стандартный ввод. Однако, если вы просто попытаетесь открыть его, как будто вы открываете файл, он не будет работать. Вам следует открыть поток терминала и скопировать его на стандартный ввод вашего приложения. Вы можете сделать это (снова используя оболочку) с помощью чего-то вроде:
size_t tty = open("/dev/tty",O_RDONLY);
dup2(tty,0);
Не говоря уже о том, что это второе решение предназначено для Linux и не переносимо.