在常规文件

时间:2018-08-08 06:46:04

标签: c linux input posix errno

所以,这是一个奇怪的情况,我有时看到并且无法找出原因。

我们有一个C程序,可以从常规文件中读取。还有其他写入同一文件的进程。该应用程序基于这样的事实:在Linux中,写操作是原子的,写大小最大为4096字节。

该文件未使用非阻塞标志打开,因此我认为读取将被阻塞。

但是有时在启动过程中,我们看到errno中设置了“ 资源暂时不可用”错误。而且读取的大小是!= -1,但部分读取的大小。

错误消息类似于:

 2018-08-07T06:40:52.991141Z, Invalid message size, log_s.bin, fd 670, Resource temporarily unavailable, read size 285, expected size 525

我的问题是:

  1. 为什么在阻止文件读取时得到EAGAIN

  2. 为什么返回值不为-1?

  3. 这仅在启动的最初时间内发生。此后工作正常。在这种情况下有哪些优势案例可以解决?

1 个答案:

答案 0 :(得分:5)

  

为什么我们在阻止文件读取时获得EAGAIN?

您不是(请参阅下文)。

  

为什么返回值不为-1?

因为操作没有失败。

如果对errno的调用失败,则read()的值具有合理的值。仅当返回read()时,对-1的调用失败。

来自Linux man-page for read()

  

返回值

     

成功后,返回读取的字节数(零表示结束          的文件名),文件位置按此数字前进。它是          如果此数字小于字节数,则不是错误          请求;

     

[...]

     

发生错误时,将返回-1,并且已正确设置errno

read()的常见模式是

char buffer[BUFFER_MAX];
char * p = buffer;
size_t to_read = ... /* not larger then BUFFER_MAX! */

while (to_read > 0)
{
  ssize_t result = read(..., p, to_read);
  if (-1 == result)
  {
    if (EAGAIN == errno || EWOULDBLOCK == errno)
    {
      continue;
    }

    if (EINTR == errno)
    {
      continue; /* or break depending on application design. */
    }

    perror("read() failed");

    exit(EXIT_FAILURE);
  }
  else if (0 < result)
  {
    to_read -= (size_t) result;
    p += (size_t) result;
  }
  else if (0 == result) /* end of file  /  connection shut down for reading */
  {
    break;
  }
  else
  {
    fprintf(stderr, "read() returned the unexpected value of %zd. You probably hit a (kernel) bug ... :-/\n", result);

    exit(EXIT_FAILURE);
  }
}

If (0 < to_read)
{
  fprintf(stderr, "Encountered early end of stream. %zu bytes not read.\n", to_read);
}