Подтвердить что ты не робот

Будете писать (2) всегда писать меньше или равно SSIZE_MAX?

Сигнатура функции для write(2) равна ssize_t write(int fd, const void *buf, size_t count). Как правило, максимальное значение size_t больше, чем значение ssize_t. Означает ли это, что количество данных, которое write может фактически написать, на самом деле SSIZE_MAX вместо SIZE_MAX? Если это не так, что происходит, когда количество записанных байтов больше чем SSIZE_MAX относительно переполнения?

Я действительно задаюсь вопросом, ограничено ли количество данных, записанных write SSIZE_MAX или SIZE_MAX.

4b9b3361

Ответ 1

Тип ssize_t определяется POSIX как подписанный тип, который может хранить не менее 32767 (_POSIX_SSIZE_MAX) без другие гарантии. Поэтому его максимальное значение может быть меньше максимального значения size_t.

ssize_t Определение POSIX:

ssize_t

Используется для подсчета байтов или индикации ошибок.

Таким образом, количество байтов, которое вы запросили для записи, может быть больше, чем может удерживать ssize_t. В этом случае POSIX оставляет его в реализации.

От write() Спецификация POSIX:

ssize_t write(int fildes, const void *buf, size_t nbyte);

Если значение nbyte больше, чем {SSIZE_MAX},         результат определяется реализацией.

Ответ 2

Спецификация POSIX для write() говорит:

Если значение nbyte больше, чем {SSIZE_MAX}, результат определяется реализацией.

Таким образом, любая попытка записать больше байтов SSIZE_MAX приводит к поведению, которое не задано POSIX, но оно должно быть документировано системой (это определяется реализацией, а не undefined, поведением). Однако разные системы могут обрабатывать его по-разному, и нет ничего, чтобы одна система не могла сообщить об ошибке (возможно, errno установлена ​​в EINVAL) и другая запись SSIZE_MAX байтов и сообщила об этом, оставив ее в приложении повторить попытку на остальной части, а другие системы могут быть изобретательными и делать все по-другому.

Если у вас 64-разрядная система, SSIZE_MAX, вероятно, будет больше, чем объем дискового пространства в крупнейшем одном центре данных в мире (возможно, на порядок или больше, даже учитывая NSA и Google), так что вы вряд ли сможете столкнуться с реальными проблемами с этим, но в 32-битных системах вы можете легко иметь более 2 гигабайт пространства, а если ssize_t - 32-разрядный, вам придется справитесь со всем этим. (В Mac OS X 10.10.3 32-битная сборка имеет 4 байта size_t и ssize_t, по крайней мере по умолчанию.)

Ответ 3

Да, количество данных, которые могут быть записаны в одном вызове для записи, ограничено тем, что можно сохранить в ssize_t. Для уточнения см. соответствующую страницу документации glibc. Чтобы процитировать эту страницу, "ваша программа должна всегда писать по вызову в цикле, итерации до тех пор, пока все данные не будут записаны". (выделено мной) Эта страница также разъясняет, что ssize_t используется для представления размера блоков, которые могут быть прочитаны или записаны за одну операцию.