APUE: Создание файла с отверстием в нем: Рисунок 3.2 стр. 65

В примере из «Расширенное программирование в среде Unix» следующий пример программы создает файл, затем использует lseek для перемещения указателя файла на дополнительный адрес, таким образом создавая «дыру» в файле. Автор говорит, что пространство между ними заполнено «0». Я хотел посмотреть, распечатаются ли эти «0». Поэтому я немного изменил программу. Однако я заметил, что в файл записывались только допустимые символы.

Мой вопрос: как менеджер файловой системы Unix/Linux знает, что нельзя печатать промежуточные байты?

#include "apue.h"
#include <fcntl.h>
#include <unistd.h>

char buf1[] = "abcdefghij";
char buf2[] = "ABCDEFGHIJ";
char buf3[10];

int
main(void)
{
  int fd;

  if ((fd = creat("file.hole", FILE_MODE)) < 0) {
    err_sys("creat error");
  }

  if (write(fd, buf1, 10) != 10) {                                             /* offset is now = 10 */
    err_sys("buf1 write error");
  }

  if (lseek(fd, 16380, SEEK_SET) == -1) {                                      /* offset now = 16380 */
    err_sys("lseek error");
  }

  if (write(fd, buf2, 10) != 10) {                                             /* offset now = 16390 */
    err_sys("buf2 write error");
  }
  close(fd);

  if ((fd = open("file.hole", O_RDWR)) == -1) {
    err_sys("failed to re-open file");
  }

  ssize_t n;
  ssize_t m;
  while ((n = read(fd, buf3, 10)) > 0) {
    if ((m = write(STDOUT_FILENO, buf3, 10)) != 10) {
      err_sys("stdout write error");
    }
  }

  if (n == -1) {
    err_sys("buf3 read error");
  }
  exit(0);
}

person Matthew Hoggan    schedule 19.12.2011    source источник
comment
Также, я думаю, у вас есть ошибка в коде, которая может записать до 9 байт мусора после конца файла (а может даже сбросить нарушение), в случае, если вы измените остальной код для вывода количества байты, не делящиеся на 10. Чтобы избежать этого, измените обе 10 в последней write строке (той, что в цикле) на n.   -  person Amadan    schedule 20.12.2011


Ответы (1)


Символ \000 имеет отображаемое представление нулевой ширины. Он напечатан, но его печать невидима. Не каждая кодовая точка является символом. Точно так же \n печатается как новая строка, а не как символ.

person Amadan    schedule 19.12.2011
comment
Чтобы убедиться в этом, попробуйте направить вывод программы на то, что отображает непечатаемые символы в печатной форме, например cat -A, od -c или less. Обратите внимание, что вы получите много вывода. - person Keith Thompson; 20.12.2011
comment
Предположим, вы перенаправили вывод программы на file. Или просто ./program | hexdump -C | less. - person Keith Thompson; 20.12.2011
comment
Должен был написать file.hole :P Но поскольку он выводит на обоих концах (файл и стандартный вывод), оба должны работать. - person Amadan; 20.12.2011