Поведение записи по умолчанию-O_TRUNC или O_APPEND?
Каково поведение по умолчанию при open
файла в режиме доступа O_WRONLY
или O_RDWR
. Файл открыт в режиме добавления или усечения? Из мужских страниц:
Флаги аргументов должны включать один из следующих режимов доступа: O_RDONLY, O_WRONLY или O_RDWR.
...
Кроме того, ноль или более флагов создания файлов и флагов состояния файлов могут быть побитовыми или в виде флагов.
Это звучит так, как будто O_APPEND
и O_TRUNC
необязательны. Итак, что же делает следующее?
void main ( void )
{
int fd = open( "foo.txt", O_WRONLY );
write( fd, "hello", 5 );
close( fd );
}
Ответы - Поведение записи по умолчанию-O_TRUNC или O_APPEND? / Default write behaviour - O_TRUNC or O_APPEND?

23.01.2020 11:34:40
Ни.
По умолчанию файл открывается курсором, расположенным в начале строки. Запись перезаписывает байты в начале файла.
O_TRUNC
вызывает усечение файла, если он существует.O_APPEND
приводит к тому, что записи добавляются в конец файла вместо перезаписи в начале. Этот флаг является постоянным. При перемещении курсора в другое место для чтения данных он всегда перемещается в конец файла перед каждой записью.
Флаги ортогональны и не являются взаимоисключающими. Вы даже можете объединить их, если вы хотите изначально усечь файл и убедиться, что все последующие записи всегда добавляются.

pwrite()
для записи в любом месте в файле, даже если он открыт с O_APPEND
: "в pwrite()
функция должна быть эквивалентна write()
, за исключением того, что он пишет в данной позиции и не меняет смещение файла (независимо от того, O_APPEND
имеет значение)."Это позволяет файлу, открытому с O_APPEND
, либо атомарно добавлять данные, либо атомарно записывать их с произвольным смещением. К сожалению, pwrite()
в Linux не работает

pwritev2
syscall с аргументом flags, я думаю, что это, наконец, исправимо без нарушения стабильности API ядра. Непроверенный патч для добавления опции
, которую функция userspace pwrite может передать, чтобы исправить это: ix.io/28aG

23.01.2020 11:46:35
При использовании флага O_WRONLY
он сам открывает файл для записи, сохраняет существующее содержимое файла и помещает указатель файла в начало файла. Любая запись перезаписывает существующий контент.
Если вы используете lseek
для изменения положения указателя файла, последующие записи будут выполняться с измененным смещением.
Это поведение контрастирует с O_TRUNC
, который усекает содержимое файла при открытии, и с O_APPEND
, который заставляет все записи происходить в конце файла.