Я пишу обертку вокруг общих файловых операций и не знаю, как справиться со случаем, когда write возвращает меньший размер, чем предоставленный.
справочная страница для записи говорит:
Количество записанных байтов может быть меньше количества, если, например, на базовом физическом носителе недостаточно места или обнаружено ограничение ресурса RLIMIT_FSIZE (см. Setrlimit (2)), или вызов был прерван обработчиком сигнала после записав меньше, чем считать байтов. (См. Также трубу (7).)
Из моего понимания вышеизложенного, это смесь ошибок (средняя заполнена) и побуждения вернуться (прерванный вызов). Если все мои файловые дескрипторы неблокируемые, я не должен получать случай прерывания, и тогда единственной причиной будет ошибка. Я прав ?
Пример кода:
int size_written = write(fd, str, count);
if (size_written == -1) {
if (errno == EAGAIN) {
// poll on fd and come back later
} else {
// throw an error
}
} else if (size_written < count) {
// ***************
// what should I do here ?
// throw an error ?
// ***************
}
Вам нужно использовать сырые функции ввода / вывода в петля:
ssize_t todo = count;
for (ssize_t n; todo > 0; )
{
n = write(fd, str, todo);
if (n == -1 && errno != EINTR)
{
// error
break;
}
str += n;
todo -= n;
}
if (todo != 0) { /* error */ }
Особое условие, касающееся EINTR
позволяет прервать вызов записи сигналом, не вызывая сбоя всей операции. В противном случае мы ожидаем, что в конечном итоге сможем записать все данные.
Если вы не можете закончить запись всех данных, потому что ваш файловый дескриптор не блокируется и не может принять какие-либо данные в данный момент, вам нужно сохранить оставшиеся данные и повторить попытку позже, когда дескриптор файла сообщит, что он снова готов к записи.
Других решений пока нет …