派生一个孩子并dub2()-将其stdin描述符传递到管道的读取端(其写入端在父进程中)后,使用read(0,...)(基于描述符)进行读取精细。但是使用fgets(stdin,...)(基于流)进行读取不起作用。为什么?
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
int main(){
char string[]="MY TEST STRING";
pid_t pid;
int bufSize=80;
char rBuf[bufSize];
int downlink[2], wrlen=0, rdlen=0, status;
memset(rBuf,0,bufSize);
if (pipe (downlink) == -1){
printf("Error with pipe()\n");
exit(4);
}
pid=fork();
if (pid>0){ //parent
wrlen=wrlen+write(downlink[1], string, strlen(string)+1);
//dprintf(downlink[1],"%s", string);
sleep(6);
}
else if (pid == 0){ // child
dup2(downlink[0],STDIN_FILENO);
//rdlen=read(downlink[0], rBuf, bufSize); //works
//rdlen=read(STDIN_FILENO, rBuf, bufSize); //works
//scanf("%s", rBuf);fflush(stdin); //doesn't work, reads up to first blank
//scanf(stdin,"%s", rBuf);fflush(stdin); //doesn't work, reads up to first blank
fgets(rBuf, bufSize, stdin);fflush(stdin); //doesn't work
printf("c: %s", rBuf), fflush(stdout);
//status =execl("/usr/bin/octave","octave","--no-gui",NULL);
//status =execl("/usr/bin/man","man",NULL);
//printf("c: status%d", status), fflush(stdout);
}
else{ //error
printf("Error with fork()\n");
exit(4);
}
return 0;
}
在此代码中,应该将fork()子级从stdin中读取(将其dub2()复制到下行链路[0](=从写入父级开始的管道的读取端))和printf()以stdout接收到的竞争 如果使用read()(基于描述符)进行读取,则一切正常。使用fgets()或scanf()(基于流)读取时,不会打印任何数据。
我在这里想念什么?
答案 0 :(得分:1)
fgets()
读取一行,但是您的父进程从不发送一行文本。因此,您需要在string
char string[]="MY TEST STRING\n";
read()
仅在可用时读取管道中的所有内容-它不会尝试读取所有可能的数据,直到换行符为止,这就是为什么使用{{1 }}
即使您不发送换行符,当管道的写入端关闭时,read()
也会返回。但是,您在父流程中创建的管道将被复制到子流程中。
这意味着,当父进程退出时,其管道的写端将关闭-但在子进程中不会关闭管道的写端-导致在父进程退出时管道仍处于打开状态。
因此,请确保在子进程中关闭管道的写入端,因为您不需要它:
fgets()