В основном я хочу сделать в C (и без буферизации) такой же, как это баш-скрипт:C: Как перенаправить именованный канал STDIN/из дочернего процесса
#!/bin/sh
cat ./fifo_in | myprogram > ./fifo_out
Другими словами, я хочу exec «myprogram» и перенаправить его stdin и stdout на две трубы, которые были созданы ранее.
Другая программа служит для подачи данных в fifo_in и чтения из fifo_out.
Конечно, было бы легко просто прочитать из ./fifo_in
, буфера его в родительском и написать стандартный ввод MyProgram (и реверс для стандартного вывода и ./fifo_out
), но я думаю, что есть, вероятно, способ, чтобы «MyProgram» чтение/запись непосредственно от/до fifos без буферизации в родительском процессе.
Edit:
ответ Eugen, кажется, правильный, но я не могу заставить его работать.
Я использую эту функцию на C-стороне, которая, кажется, правильно мне:
pid_t execpipes(const char *wd, const char *command, const char *pipename)
{
char pipename_in[FALK_NAMESIZE];
char pipename_out[FALK_NAMESIZE];
strcpy(pipename_in, FALKPATH);
strcat(pipename_in, "/");
strcat(pipename_in, FALK_FIFO_PATH);
strcat(pipename_in, "/");
strncat(pipename_in, pipename, FALK_NAMESIZE-2);
strcpy(pipename_out, pipename_in);
strcat(pipename_out, "R");
pid_t pid;
pid = fork();
if (pid < 0)
{ //Error occured
perror("fork");
exit(1);
}
if (pid == 0)
{
chdir(wd);
d("execpipes: pipename_in=\"%s\"\n", pipename_in);
d(" pipename_out=\"%s\"\n", pipename_out);
freopen(pipename_in,"r",stdin);
freopen(pipename_out,"w",stdout);
d("execpipes: command=\"%s\"\n", command);
execl("/bin/sh", "sh", "-c", command, (char *)NULL); // using execv is probably faster
// Should never get here
perror("execl");
exit(1);
}
return pid;
}
Я читать и писать трубы из РНР-скрипта (только соответствующая часть размещена):
$pipe_in = fopen($fp.$pipename, "w");
$DEBUG .= "Write to pipe_in\n";
$ret = fwrite($pipe_in, $in);
$pipe_out = fopen($fp.$pipename.'R', "r");
$DEBUG .= "Read from pipe_out\n";
$atext = fread($pipe_out, 200000); // Program hangs here
Программа запускается правильно, правильно принимает входные данные через $pipe_in
, обрабатывает данные правильно и (потому что она работала нормально в течение многих месяцев). Я предполагаю, что она корректно выводит данные на стандартный вывод, но когда я пытаюсь читать с $pipe_out
, висит. Я знаю, что сами трубы настроены правильно, потому что, если я не открываю $pipe_out
, программа не получает никакого ввода - что имеет смысл, потому что нет читателя для $pipe_out
, и поэтому конвейер не завершен. Поэтому я могу открыть $pipe_out
, но я ничего не могу прочитать от него, что довольно странно.
Edit2:
Программа теперь работает, спасибо, ребята - По какой-то причине первой трубы должна быть закрыта, прежде чем вы можете прочитать из второй трубы:
$pipe_in = fopen($fp.$pipename, "w");
$pipe_out = fopen($fp.$pipename.'R', "r");
$DEBUG .= "Write to pipe_in\n";
$ret = fwrite($pipe_in, $in);
fclose($pipe_in);
$DEBUG .= "Read from pipe_out\n";
$atext = fread($pipe_out, 200000);
fclose($pipe_out);
unlink($fp.$pipename);
unlink($fp.$pipename.'R');
Вы пишете источник для 'myprogram' или для какой-либо другой программы, которая« называет »' myprogram'? – pmg
Любые причины злоупотреблять «кошкой»? Почему бы не использовать: 'myprogram < ./fifo_in >./Fifo_out'? –
Нет причин использовать кошку, сценарий bash - это просто, чтобы уточнить, что должна делать C-программа. – Robby75