linux 读取系统调用没有得到 EOF
linux read sys call doesnt get EOF
首先很抱歉,如果我的英语不够流利和清晰。
我正在努力理解进程之间的管道和通信。我试图实现两个 c 程序,一个将他从标准输入中读取的内容写入某个管道,另一个等待管道打开并从中读取并打印到标准输出,直到 EOF。
这是编写器管道的代码:
fd = open(filename, O_RDWR);
if(fd == -1) print_error();
while(fgets(buffer, BUFFER_SIZE, stdin) != NULL) {
if(write(fd, buffer, BUFFER_SIZE) == -1) print_error();
}
这里是 reader 管道的代码:
while(1) {
if((fd = open(filename, O_RDWR)) == -1) {
if(errno == ENOENT) sleep(1);
else print_error();
}
else {
while(read(fd, buffer, BUFFER_SIZE) != 0) {
fprintf(stdout, "%s", buffer);
}
}
}
问题是,当我 运行 这两个程序同时运行时,基本概念起作用了,我在 writer 程序中向标准输入写了一些东西,我在另一个终端看到 reader程序将其打印到标准输出。问题是,当我通过为编写器程序按 CTRL + D 发送 EOF 时,reader 程序仍在等待输入,而且我确定这不是因为 while(1),我在调试器,读取系统调用只是在等待输入并且不明白我们得到了 EOF,行:read(fd, buffer, BUFFER_SIZE)
即使没有输入也没有评估。
我希望我提供了解决问题所需的所有数据,有人知道哪里出了问题吗?
如果 fgets()
检测到 EOF
它 returns 已经在其读取缓冲区中的内容或只是 returns NULL
.
在后一种情况下,您希望通过关闭管道等方式通知读取端传输已结束。
int fd = open(filename, O_RDWR);
if (fd == -1)
{
perror("open() failed");
}
else
{
while (fgets(buffer, BUFFER_SIZE, stdin) != NULL)
{
if (write(fd, buffer, BUFFER_SIZE) == -1)
{
perror("write() failed");
break;
}
}
if (ferror(stdin))
{
perror("fgets() failed");
}
close(fd); /* The other end's blocking call to read() would return 0. */
}
在任何情况下都不会读取 EOF
之类的内容。 EOF
不是字符而是状态。
来自 man 3 read
:
If some process has the pipe open for writing [...] read()
shall block the calling thread until some data is written or the pipe is closed by all processes that had the pipe
open for writing.
此外,此代码不涵盖 read()
失败:
while(read(fd, buffer, BUFFER_SIZE) != 0) {
fprintf(stdout, "%s", buffer);
}
它应该看起来像这样的例子:
ssize_t result;
while (0 != (result = read(fd, buffer, BUFFER_SIZE)))
{
if (0 > result)
{
if ((EINTR == errno) || (EAGAIN == errno))
{
continue;
}
perror("read() failed");
break;
}
fprintf(stdout, "%s", buffer);
}
更多这个循环...
while(1) {
if((fd = open(filename, O_RDWR)) == -1) {
if(errno == ENOENT) sleep(1);
else print_error();
}
...
}
...在(重新)打开它之前错过 close()
fd
。
如果 reader 没有写入,请通过指定 O_RDONLY
而不是 RDWR
打开管道。
read
也可以 return -1
出错。如果您的编写器进程未正确关闭其输出流,则可能会出现这种情况。所以你应该明确检查 read <= 0
.
但我希望您也知道周围的 while(1)
循环会立即进入下一轮的 read
调用,因此您也可能会看到这一点。
首先很抱歉,如果我的英语不够流利和清晰。
我正在努力理解进程之间的管道和通信。我试图实现两个 c 程序,一个将他从标准输入中读取的内容写入某个管道,另一个等待管道打开并从中读取并打印到标准输出,直到 EOF。
这是编写器管道的代码:
fd = open(filename, O_RDWR);
if(fd == -1) print_error();
while(fgets(buffer, BUFFER_SIZE, stdin) != NULL) {
if(write(fd, buffer, BUFFER_SIZE) == -1) print_error();
}
这里是 reader 管道的代码:
while(1) {
if((fd = open(filename, O_RDWR)) == -1) {
if(errno == ENOENT) sleep(1);
else print_error();
}
else {
while(read(fd, buffer, BUFFER_SIZE) != 0) {
fprintf(stdout, "%s", buffer);
}
}
}
问题是,当我 运行 这两个程序同时运行时,基本概念起作用了,我在 writer 程序中向标准输入写了一些东西,我在另一个终端看到 reader程序将其打印到标准输出。问题是,当我通过为编写器程序按 CTRL + D 发送 EOF 时,reader 程序仍在等待输入,而且我确定这不是因为 while(1),我在调试器,读取系统调用只是在等待输入并且不明白我们得到了 EOF,行:read(fd, buffer, BUFFER_SIZE)
即使没有输入也没有评估。
我希望我提供了解决问题所需的所有数据,有人知道哪里出了问题吗?
如果 fgets()
检测到 EOF
它 returns 已经在其读取缓冲区中的内容或只是 returns NULL
.
在后一种情况下,您希望通过关闭管道等方式通知读取端传输已结束。
int fd = open(filename, O_RDWR);
if (fd == -1)
{
perror("open() failed");
}
else
{
while (fgets(buffer, BUFFER_SIZE, stdin) != NULL)
{
if (write(fd, buffer, BUFFER_SIZE) == -1)
{
perror("write() failed");
break;
}
}
if (ferror(stdin))
{
perror("fgets() failed");
}
close(fd); /* The other end's blocking call to read() would return 0. */
}
在任何情况下都不会读取 EOF
之类的内容。 EOF
不是字符而是状态。
来自 man 3 read
:
If some process has the pipe open for writing [...]
read()
shall block the calling thread until some data is written or the pipe is closed by all processes that had the pipe open for writing.
此外,此代码不涵盖 read()
失败:
while(read(fd, buffer, BUFFER_SIZE) != 0) {
fprintf(stdout, "%s", buffer);
}
它应该看起来像这样的例子:
ssize_t result;
while (0 != (result = read(fd, buffer, BUFFER_SIZE)))
{
if (0 > result)
{
if ((EINTR == errno) || (EAGAIN == errno))
{
continue;
}
perror("read() failed");
break;
}
fprintf(stdout, "%s", buffer);
}
更多这个循环...
while(1) {
if((fd = open(filename, O_RDWR)) == -1) {
if(errno == ENOENT) sleep(1);
else print_error();
}
...
}
...在(重新)打开它之前错过 close()
fd
。
如果 reader 没有写入,请通过指定 O_RDONLY
而不是 RDWR
打开管道。
read
也可以 return -1
出错。如果您的编写器进程未正确关闭其输出流,则可能会出现这种情况。所以你应该明确检查 read <= 0
.
但我希望您也知道周围的 while(1)
循环会立即进入下一轮的 read
调用,因此您也可能会看到这一点。