您可以使用
stdbuf
命令修改管道另一端程序的缓冲选项。要在C中执行此操作,可以编写:
char str[100] = "./app";
char **new_argv = malloc (sizeof (char *) * (argc + 9));
new_argv[0] = "stdbuf";
new_argv[1] = "-i";
new_argv[2] = "0";
new_argv[3] = "-o";
new_argv[4] = "L";
new_argv[5] = "-e";
new_argv[6] = "L";
new_argv[7] = str;
memcpy (&new_argv[8], &argv[1], argc - 1);
new_argv[argc + 8] = NULL;
execvp ("stdbuf", new_argv);
error ("execvp");
或者,如果您真的不需要将家长的参数传递给孩子,那么:
execlp ("stdbuf", "stdbuf", "-i", "0", "-o", "L", "-e", "L", "./app", NULL);
error ("execlp");
这个
stdbuf
命令使用LD\u PRELOAD加载库(
libstdbuf.so
)进入另一个程序。这个库完成了修改缓冲选项的技巧。您可以避免使用
stdbuf标准
并在exec()之前自行设置预加载选项。您也可以编写自己的库并预加载它。但是使用
stdbuf标准
如果有此命令可用,则可能是最简单的选项。
另请参见
stdbuf source code
下面是代码的完整修改示例:
//input.c
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <string.h>
#include <errno.h>
#define WRITE 1
#define READ 0
void error (char *msg)
{
perror (msg);
exit (-1);
}
void got_here (char *msg)
{
printf ("Got_here: %s\n", msg);
}
int main (int argc, char **argv, char **envp)
{
int fd_parent[2];
int fd_child[2]; // for parent and child to write respectively
pid_t child;
if (pipe (fd_parent) < 0) {
error ("pipe(fd_parent)");
}
if (pipe (fd_child) < 0) {
error ("pipe(fd_child)");
}
child = fork ();
if (child < 0) {
error ("fork");
} else if (child == 0) {
dup2 (fd_child[WRITE], STDOUT_FILENO);
dup2 (fd_parent[READ], STDIN_FILENO);
close (fd_parent[WRITE]);
close (fd_child[READ]);
char str[100] = "./app";
char **new_argv = malloc (sizeof (char *) * (argc + 9));
new_argv[0] = "stdbuf";
new_argv[1] = "-i";
new_argv[2] = "0";
new_argv[3] = "-o";
new_argv[4] = "L";
new_argv[5] = "-e";
new_argv[6] = "L";
new_argv[7] = str;
memcpy (&new_argv[8], &argv[1], argc - 1);
new_argv[argc + 8] = NULL;
execvp ("stdbuf", new_argv);
error ("execvp");
close (fd_parent[READ]);
close (fd_child[WRITE]);
return 0;
} else {
close (fd_parent[READ]);
close (fd_child[WRITE]);
FILE *stream = fdopen (fd_child[READ], "r");
FILE *stream_write = fdopen (fd_parent[WRITE], "w");
char str[20];
char menu[4] = "10\n";
int res = fread (str, sizeof (char), 20, stream); // Here is where the problem lies
printf ("res = %d\n", res);
got_here ("after read"); // it does not get here
fwrite (menu, sizeof (char), 3, stream_write);
fflush (stream_write);
fclose (stream);
fclose (stream_write);
printf ("Parent Done\n");
return 0;
}
}