Язык программирования Си


         

Хрестоматия по программированию на Си в Unix- часть 164


- 164 - Си в UNIX

frd = fopen( "aFile", "r" );

fprintf( fwr, "%d: Hello, dude!", n); s = fgets( b, sizeof b, frd ); printf( "%s\n", s ? s : "EOF" ); }

Ответ: потому что к моменту чтения буфер канала fwr еще не вытолкнут в файл: файл пуст! Надо вставить

fflush(fwr);

после fprintf(). Вот еще подобный случай:

FILE *fp = fopen("users", "w"); ... fprintf(fp, ...); ... system("sort users | uniq > 00; mv 00 users");

К моменту вызова команды сортировки буфер канала fp (точнее, последний из накопленных за время работы буферов) может быть еще не вытолкнут в файл. Следует либо закрыть файл fclose(fp) непосредственно перед вызовом system, либо вставить туда же fflush(fp);

4.44. В UNIX многие внешние устройства (практически все!) с точки зрения программ являются просто файлами. Файлы-устройства имеют имена, но не занимают места на диске (не имеют блоков). Зато им соответствуют специальные программы-драйверы в ядре. При открытии такого файла-устройства мы на самом деле инициализируем драйвер этого уст- ройства, и в дальнейшем он выполняет наши запросы read, write, lseek аппаратно- зависимым образом. Для операций, специфичных для данного устройства, предусмотрен сисвызов ioctl (input/output control):

ioctl(fd, РОД_РАБОТЫ, аргумент);

где аргумент часто бывает адресом структуры, содержащей пакет аргументов, а РОД_РАБОТЫ - одно из целых чисел, специфичных для данного устройства (для каждого устр-ва есть свой собственный список допустимых операций). Обычно РОД_РАБОТЫ имеет некоторое мнемоническое обозначение. В качестве примера приведем операцию TCGETA, применимую только к терминалам и узнающую текущие моды драйвера терминала (см. главу "Экранные библиотеки"). То, что эта операция неприменима к другим устройствам и к обычным файлам (не устройствам), позволяет нам использовать ее для проверки - является ли открытый файл терминалом (или клавиатурой):

#include <termio.h> int isatty(fd){ struct termio tt; return ioctl(fd, TCGETA, &tt) < 0 ? 0 : 1; } main(){ printf("%s\n", isatty(0 /* STDIN */)? "term":"no"); }

Функция isatty является стандартной функцией[*]. Есть "псевдоустройства", которые представляют собой драйверы логических уст- ройств, не связанных напрямую с аппаратурой, либо связанных лишь косвенно. Примером такого устройства является псевдотерминал (см. пример в приложении). Наиболее упот- ребительны два псевдоустройства: /dev/null

Это устройство, представляющее собой "черную дыру". Чтение из него немедленно выдает признак конца файла: read(...)==0; а записываемая в него информация нигде не сохраняется (пропадает). Этот файл используется, например, в том случае, когда мы хотим проигнорировать вывод какой-либо программы (сообщения об ошибках, трассировку), нигде его не сохраняя. Тогда мы просто перенаправляем ее вывод в /dev/null:




Содержание  Назад  Вперед