readの正しい使い方、writeの正しい使い方
※2012年5月2日、追記。
下記のコードよりもcopybenchのコードを参考にした方がいいかもしれない。
C言語: write(2)の正しい使い方というページがあったのだが、今は見ることが出来なくなっているので、似たような内容を残しておくことにした。
正しい使い方とはつまり、システムコールは割り込まれて中断することがあるからちゃんとエラーチェックをしましょう、ということだ。
以下に、writeを使用するためのソースコードを転載する。
/* http://www.koders.com/c/fidBA4A85F16684724E234A9F3D52154B6A3EE76852.aspx?s=md5 */ ssize_t full_write(int fd, const void *buf, size_t len) { ssize_t cc; ssize_t total; total = 0; while (len) { cc = safe_write(fd, buf, len); if (cc < 0) return cc; /* write() returns -1 on failure. */ total += cc; buf = ((const char *)buf) + cc; len -= cc; } return total; }
/* http://www.koders.com/c/fid1D28BE2FE0F7496591C635321BDFC406ED821089.aspx?s=md5 */ ssize_t safe_write(int fd, const void *buf, size_t count) { ssize_t n; do { n = write(fd, buf, count); } while (n < 0 && errno == EINTR); return n; }
readも同じような処理が必要なので、以下のような関数を使う。
/* http://www.koders.com/c/fidE71B6BE5B9B1AE1265F1CFBA2DB698715258B0F5.aspx?s=ftp */ int full_read(int fd, char *buf, int len) { int cc; int total; total = 0; while (len > 0) { cc = read(fd, buf, len); if (cc < 0) return -1; if (cc == 0) break; buf += cc; total += cc; len -= cc; } return total; }
/* http://www.koders.com/c/fidA918F638FF7469723CAC99A84826115C1310BC35.aspx?s=ftp */ ssize_t safe_read(int fd, void *buf, size_t count) { ssize_t n; do { n = read(fd, buf, count); } while (n < 0 && errno == EINTR); return n; }
ネットワークアプリケーションの場合は、さらにSIGPIPEシグナルを無視する処理が必要らしい。
関連:Programming UNIX Sockets in C - Frequently Asked Questions