Unix 获取 fread、fgetc 等特定错误?

问题描述 投票:0回答:1

我想在阅读此管道后得到特定的错误(EAGAIN)。我该怎么做?

#include <assert.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>

int main() {
  int rw[2]; assert(!pipe(rw));
  int r = rw[0], w = rw[1];
  fcntl(r, F_SETFL, O_NONBLOCK);
  printf("This will return EAGAIN\n");
  printf(" read -> %i\n", read(r, buf, 10));
  printf(" errno = %i \"%s\" (EAGAIN=%i)\n", errno, strerror(errno), EAGAIN);

  errno = 0;
  FILE* f = fdopen(r, "r");
  printf(" fgetc -> %i (EOF=%i) errno=%i\n", fgetc(f), EOF, errno);
  printf(" ferror -> %i\n", ferror(f));
}

打印

This will return EAGAIN
 read -> -1
 errno = 11 "Resource temporarily unavailable" (EAGAIN=11)
This doesn't give me any info
 fgetc -> -1 (EOF=-1) errno=0
 ferror -> 1
unix nonblocking fdopen
1个回答
0
投票

这是程序员错误,感谢@Shawn 在评论中提供帮助。

C 没有指定函数参数的求值顺序。即使在 fgetc() 错误之后 errno 处于有用状态,如果对参数求值,printf() 也可能会在调用 fgetc() 之前传递其值从右到左。

我现在意识到

fread()
和朋友们在
all
都没有提到errno——这意味着(我猜?)如果发生错误,他们也不会修改errno。很有趣!

我修改了第二位

  printf("Errno has the answers!\n");
  FILE* f = fdopen(r, "r");
  errno = 0;
  printf(" errno has been set to %i\n", errno);
  printf(" fgetc -> %i (EOF=%i)\n", fgetc(f), EOF);
  printf(" errno=%i (pre ferror)\n", errno);
  printf(" ferror -> %i\n", ferror(f));
  printf(" errno=%i\n", errno);

哪个打印

Errno has the answers!
 errno has been set to 0
 fgetc -> -1 (EOF=-1)
 errno=11 (pre ferror)
 ferror -> 1
 errno=11
© www.soinside.com 2019 - 2024. All rights reserved.