Читать книгу 📗 "Linux программирование в примерах - Роббинс Арнольд"
devtype = "char"; else if (S_ISBLK(sbuf.st_mode)) devtype = "block"; else { fprintf(stderr, "%s is not a block or character devicen", argv[1]); exit(1); } printf("%s: major: %d, minor: %dn", devtype, major(sbuf.st_rdev), minor(sbuf.st_rdev)); exit(0);}Вот что происходит при запуске программы:
$ <b>ch05-devnum /tmp </b>/* Попробовать не устройство *//tmp is not a block or character device$ <b>ch05-devnum /dev/null</b> /* Символьное устройство */char: major: 1, minor: 3$ <b>ch05-devnum /dev/hda2</b> /* Блочное устройство */block: major: 3, minor: 2К счастью, вывод согласуется с выводом
lsВоспроизведение вывода ls замечательно и хорошо, но действительно ли это полезно? Ответ — да. Любое приложение, работающее с иерархиями файлов, должно быть способно различать различные типы файлов. Подумайте об архиваторе, таком как
tarcpiofindfind5.4.4.2. Возвращаясь к V7
catВ разделе 4.4.4 «Пример: Unix cat» мы обещали вернуться к программе V7
catstat()31 fstat(fileno(stdout), &statb);32 statb.st_mode &= S_IFMT;33 if (statb.st_mode != S_IFCHR && statb.st_mode != S_IFBLK) {34 dev = statb.st_dev;35 ino = statb.st_ino;36 }Этот код теперь должен иметь смысл. В строке 31 вызывается
fstat()statbstatb.st_modeS_IFMTdevino50 fstat(fileno(fi), &statb);51 if (statb.st_dev == dev && statb.st_ino == ino) {52 fprintf(stderr, "cat: input %s is outputn",53 ffig ? "-" : *argv);54 fclose(fi);55 continue;56 }Если значения
st_devst_inocatПроверка сделана безусловно, хотя
devinoint dev, ino = -1;Поскольку
inodevdevgcc -WallОбратите также внимание, что ни один вызов
fstat()fstat()Проверка того, что входной файл не равен выходному файлу, осуществляется лишь для файлов, не являющихся устройствами. Это дает возможность использовать
cat$ <b>tty</b> /* Вывести имя устройства текущего терминала *//dev/pts/3$ <b>cat /dev/pts/3 > /dev/pts/3</b> /* Копировать ввод от клавиатуры на экран */<b>this is a line of text</b> /* Набираемое в строке */this is a line of text /* cat это повторяет */5.4.5. Работа с символическими ссылками
В общем, символические ссылки ведут себя подобно прямым ссылкам; файловые операции, такие, как
open()stat()По этой причине существует системный вызов
lstat()stat()