Как ведет себя карта памяти, поддерживаемая файлом -, при чтении или записи по адресу, превышающему длину файла?

  1. Укажите свои переменные. Кроме того, используйте ${i/Old/New}без символа решетки(#)перед Old. #заставляет совпадение начинаться с начала имени файла, но ни один из файлов не начинается с Old, все они начинаются с 0.

    $ touch "01. Old Name.txt" "02. Old Name.txt" "03. Old Name.txt"
    $ for i in *.txt ; do mv -v "$i" "${i/Old/New}" ; done
    renamed '01. Old Name.txt' -> '01. New Name.txt'
    renamed '02. Old Name.txt' -> '02. New Name.txt'
    renamed '03. Old Name.txt' -> '03. New Name.txt'
    
  2. Установите и используйте Perl renameутилиту (, например. sudo apt-get install renameна Debian и его производных ). Это намного лучше, чем массовое переименование своими руками.

1
28.10.2020, 16:05
2 ответа

Поведение указано, но не в справочной странице Linux mmap, а в POSIX:

The system shall always zero-fill any partial page at the end of an object. Further, the system shall never write out any modified portions of the last page of an object which are beyond its end. References within the address range starting at pa and continuing for len bytes to whole pages following the end of an object shall result in delivery of a SIGBUS signal.

Если вы mmapиспользуете файл с MAP_SHAREDсопоставлением, превышающим размер файла, и пытаетесь записать в память за пределами конца файла, вы можете получить SIGBUS, хотя само отображение охватывает диапазон (check/proc/.../maps). В приведенном выше тексте pa — это адрес, возвращаемый mmap, поэтому в спецификации говорится, что доступ к адресам на страницах, которые попадают в отображаемую область памяти, но полностью выходят за конец отображаемого объекта приведет к SIGBUS. Чтение и запись на странице, которая частично находится внутри сопоставленного объекта, работает, что соответствует защите, обычно предоставляемой модулями управления памятью.

Кроме того, поведение, необходимое для вашего варианта использования, не определено:

If the size of the mapped file changes after the call to mmap() as a result of some other operation on the mapped file, the effect of references to portions of the mapped region that correspond to added or removed portions of the file is unspecified.

Есть некоторые дополнительные тонкости, связанные с кэшем страниц в Linux (см. раздел ошибок на странице руководства ), и они могут привести к неожиданному поведению вдобавок к вышесказанному — данные записываются за конец файл, но в пределах последней сопоставленной страницы, не будет записан в файл, но может сохраниться до последующих сопоставлений.

mmapвозвращает EINVALпри отображении файла, если предоставленные значения недействительны в общих чертах, не связаны конкретно с отображаемым файлом :, т.е. , если требования выравнивания не выполняются, или смещение и длина несовместимы с максимальным размером файла, которым может управлять ядро.

1
18.03.2021, 22:54

Ответ (скрыт )в разделе ПРИМЕЧАНИЯ на mmap (2 )страница:

   A file is mapped in multiples of the page size.  For a  file  that
   is not a multiple of the page size, the remaining memory is zeroed
   when mapped, and writes to that region are not written out to  the
   file.

Но этот текст мог бы быть немного яснее, а обсуждение SIGBUSна странице совсем не ясно. Я изменил приведенный выше текст на:

   A  file  is mapped in multiples of the page size.  For a file that
   is not a multiple of the page size, the  remaining  bytes  in  the
   partial page at the end of the mapping are zeroed when mapped, and
   modifications to that region are not written out to the file.

И я изменил описание SIGBUSна :

.
   SIGBUS Attempted  access  to a page of the buffer that lies beyond
          the end of the mapped file.   For  an  explanation  of  the
          treatment  of the bytes in the page that corresponds to the
          end of a mapped file that is not a  multiple  of  the  page
          size, see NOTES.
1
18.03.2021, 22:54

Теги

Похожие вопросы