Files & I/O

short reads and partial writes

You ask the kitchen for ten sandwiches but they hand you four and say 'that is all I have right now, ask again.' That is read() and write(): you request a count of bytes, but the system is allowed to satisfy only part of your request and tell you how much it actually did. Assuming you always get the full amount is one of the most common bugs in C I/O.

Concretely, read(fd, buf, n) returns the number of bytes it actually placed in buf, which can be anywhere from 1 up to n - a short read - or 0 at end-of-file, or -1 on error. A short read is normal, not a failure: reading from a pipe, a terminal, or a socket often returns whatever is available right now rather than waiting for all n bytes. Likewise write(fd, buf, n) returns how many bytes it actually accepted, which can be fewer than n - a partial write - especially on pipes and sockets, or when a disk fills. The correct pattern is a loop: keep calling, advancing your buffer pointer and shrinking your count by the amount moved each time, until you have transferred everything or hit EOF or a real error. Treat a -1 with errno == EINTR (interrupted by a signal) as 'just try again,' not as failure.

Why it matters: code that does ssize_t n = read(fd, buf, 100); and then blindly treats buf as holding exactly 100 bytes is broken - it may have 12. The bug often hides because reads from regular files on a fast disk frequently do return the full amount, so the code 'works' in testing and then corrupts data the day it reads from a pipe or a slow network. Always check the return value and loop; the bytes you asked for and the bytes you got are two different numbers.

/* write all n bytes, looping over partial writes */ size_t left = n; const char *p = buf; while (left > 0) { ssize_t w = write(fd, p, left); if (w < 0) { if (errno == EINTR) continue; return -1; } p += w; left -= w; }

Never trust one write() to move everything; advance the pointer and loop until left == 0.

A short read is not an error and read() == 0 means EOF, not failure. The bytes-requested and bytes-moved are independent numbers - code that ignores the return value of read/write is one of the most common and quietly destructive C bugs.

Also called
partial read/writeincomplete I/O不完整的讀寫