当前位置:嗨网首页>书籍在线阅读

09-返回值

  
选择背景色: 黄橙 洋红 淡粉 水蓝 草绿 白色 选择字体: 宋体 黑体 微软雅黑 楷体 选择字体大小: 恢复默认

2.2.1 返回值

对于read()而言,返回小于len的非零正整数是合法的。在很多情况下会出现该现象:可用的字节数少于len,系统调用可能被信号打断,管道可能被破坏(如果fd指向的是管道)等。

使用read()时,还需要考虑返回值为0的情况。当到达文件末尾(end-of-file, EOF)时,read()返回0,在这种情况下,没有读取任何字节。EOF并不表示出错(因此返回值不是-1),它仅仅表示文件位置已经到达文件结尾,因此没有数据可读了。但是,如果调用是要读取len个字节,但是没有一个字节可读,调用会阻塞(sleep),直到有数据可读(假定文件描述符不是以非阻塞模式打开的,参见2.2.3小节)。注意,这种阻塞模式和返回EOF不同。也就是说,“没有数据可读”和“到达数据结尾”是两个不同的概念。对于EOF,表示到达了文件的结尾。对于阻塞模式,表示读操作在等待更多的数据——例如从socket或设备文件读取数据。

有些错误是可以恢复的。比如,当read()调用在读取任何字节之前被信号打断,它会返回-1(如果返回0,则无法和EOF的情况区分开),并把errno值设置成EINTR。在这种情况下,可以而且应该重新提交read请求。

实际上,调用read()有很多可能结果:

  • 调用返回值等于len。读取到的所有len个字节都被存储在buf中。结果和预期的一致。
  • 调用返回值小于len,大于0。读取到的字节被存储到buf中。这种情况有很多原因,比如在读取过程中信号中断或在读取中出错,可读的数据大于0字节小于len字节,在读取len字节之前到达EOF。再次执行read(分别更新了buf和len值)会把剩余的字节读到缓冲区中或者给出错误信息。
  • 调用返回0,表示EOF,没有更多可读的数据。
  • 由于当前没有数据可用,调用阻塞。在非阻塞模式下,不会发生这种情况。
  • 调用返回-1,并把errno设置成EINTR。这表示在读取任何字节之前接收到信号。调用可以重新执行。
  • 调用返回-1,并把errno设置成EAGAIN。这表示由于当前没有数据可用,读操作会阻塞,请求应该稍后再重新执行。这种情况只在非阻塞模式下发生。
  • 调用返回-1,并把errno设置成非EINTR或EAGAIN的一个值。这表示更严重的错误。重新执行读操作不会成功。