Я хотел бы реализовать правильный write(2)
цикл, который берет буфер и продолжает называть write
, пока весь буфер не будет написано.
Я предполагаю, что базовый подход - это что-то вроде:
/** write len bytes of buf to fd, returns 0 on success */
int write_fully(int fd, char *buf, size_t len) {
while (len > 0) {
ssize_t written = write(fd, buf, len);
if (written < 0) {
// some kind of error, probably should try again if its EINTR?
return written;
}
buf += written;
len -= written;
}
return 0;
}
... но это ставит вопрос о том, может ли write()
корректно вернуть 0 байтов и что делать в этом случае. Если ситуация сохранится, приведенный выше код будет просто горячим нажатием на вызов write
, который выглядит как плохая идея. Пока что возвращается что-то ненужное, вы продвигаетесь вперед.
Страница руководства для write
немного неоднозначна. В нем говорится, например:
При успехе возвращается количество записанных байтов (ноль указывает ничего не было написано).
Что, по-видимому, указывает на то, что это возможно в некоторых сценариях. Вызывается только один такой сценарий:
Если count равен нулю, а fd относится к обычному файлу, то write() может возвращает статус отказа, если обнаружена одна из ошибок ниже. Если нет ошибки обнаружены или обнаружение ошибок не выполняется, 0 будет возвращен без какого-либо другого эффекта. Если count равен нулю и fd относится к файлу, отличному от обычного файла, результаты не указано.
Этот случай исключается выше, потому что я никогда не звоню write
с len == 0
. Есть много других случаев, когда ничего нельзя было написать, но в целом все они имеют определенные коды ошибок, связанные с ними.
Сам файл будет open
ed из пути/имени, указанного в командной строке. Поэтому обычно это обычный файл, но пользователи могут, конечно, передавать такие вещи, как трубы, выполнять перенаправление ввода, передавать специальные устройства, такие как /dev/stdout
и так далее. Я, по крайней мере, контролирую вызов open
, а флаг O_NONBLOCK
не передается для открытия. Я не могу разумно проверить поведение для всех файловых систем, всех специальных устройств (и даже если бы мог, больше будет добавлено), поэтому я хочу знать , как обращаться с этим разумным и общим способом.
*... для ненулевого размера буфера.