fd
がソケットや PIPE 以外を指していて
O_NONBLOCK
が設定されており、読み込みを行うと停止する状態にある
EBADF
fd
が有効なファイルディスクリプターでないか、読み込みのために オープン (open) されていない
EINTR
指定されたバイト数を読み込み完了するまでにシグナルに割り込まれた
ファイルディスクリプター
fd
から最大
count
バイトをアドレス
buf
で始まるバッファーへ読み込む
fd
が seek に対応しているファイルを指している場合、read は現在のファイルオフセットから開始される。ファイルオフセットは読み込んだバイト数分だけインクリメントされる
現在のファイルオフセットがファイル末尾の場合は、読み出しは行われず 0 を返す
count
が
SSIZE_MAX
より大きい場合、動作は保証されない
read 関数は、引数
count
で
指定したバイト数を必ず読み込んでくれるわけではない。
例えば、read 処理中に signal などの割り込みが発生した場合、 read は途中で中断されます。
これらのケアを正しく行わないと、中途半端なデータを処理してしまって
プログラムが破綻してしまう
。
注意ポイント②
ソケットなどにアクセスする場合は、届いているデータを
最後まで読み出す必要
があります。
カーネル側のバッファが溢れ、
書き込む側でエラーが発生
します。
サンプル:エラーの対処と最後まで読みだす細工
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#define LOG_FILE_PATH "./test.log"
static
ssize_t
my_read
(
int
fd
,
char
*
buf
,
size_t
size
)
{
ssize_t
done
=
0
;
size
_
t
s
=
size
;
while
(
s
>
0
)
{
done
=
read
(
fd
,
(
void
*
)
buf
,
s
)
;
if
(
done
<
0
)
{
if
(
errno
==
EINTR
)
/* Interrupt */
continue
;
else
/* Error */
return
done
;
}
else
if
(
done
==
0
)
{
/* EOF */
return
size
-
s
;
}
else
{
buf
+=
done
;
s
-=
done
;
}
}
return
size
;
}
int
main
(
void
)
{
int
fd
,
size
;
char
buf
[
128
]
;
fd
=
open
(
LOG_FILE_PATH
,
O_RDONLY
)
;
if
(
fd
<
0
)
return
-
1
;
size
=
my_read
(
fd
,
buf
,
sizeof
(
buf
)
)
;
if
(
size
!=
sizeof
(
buf
)
)
{
close
(
fd
)
;
return
-
1
;
}
/* 処理を書く */
close
(
fd
)
;
return
0
;
}
2023/07/23
OpenCVでlibjpeg-turboのSIMDを有効化する方法
2023/07/07
生成AI「StableStudio」をUbuntu20.04上で動かす方法
2023/06/21
【C#】NICを指定してMulticastを受信する方法
SANACHANの記事をもっと見る