Архитектура Unix

. Удаление связи с открытым файлом



Рисунок 5.33. Удаление связи с открытым файлом

#include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> main(argc,argv) int argc; char *argv[]; { int fd; char buf[1024]; struct stat statbuf; if (argc != 2) /* нужен параметр */ exit(); fd = open(argv[1],O_RDONLY); if (fd == -1) /* open завершилась неудачно */ exit(); if (unlink(argv[1]) == -1) /* удалить связь с только что открытым файлом */ exit(); if (stat(argv[1],&statbuf) == -1) /* узнать состоя- ние файла по имени */ printf("stat %s завершилась неудачно\n",argv[1]); /* как и следовало бы */ else printf("stat %s завершилась успешно!\n",argv[1]); if (fstat(fd,&statbuf) == -1) /* узнать состояние файла по идентификатору */ printf("fstat %s сработала неудачно!\n",argv[1]); else printf("fstat %s завершилась успешно\n",argv[1]); /* как и следовало бы */ while (read(fd,buf,sizeof(buf)) > 0) /* чтение откры- того файла с удаленной связью */ printf("%1024s",buf); /* вывод на печать поля размером 1 Кбайт */ }


Процесс может удалить связь файла в то время, как другому процессу нужно, чтобы файл оставался открытым. (Даже процесс, удаляющий связь, может быть процессом, выполнившим это открытие). Поскольку ядро снимает с индекса блокировку по окончании выполнения функции open, функция unlink завершится успешно. Ядро будет выполнять алгоритм unlink точно так же, как если бы файл не был открыт, и удалит из каталога запись о файле. Теперь по имени удаленной связи к файлу не сможет обратиться никакой другой процесс. Однако, так как системная функция open увеличила значение счетчика ссылок в индексе, ядро не очищает содержимое файла при выполнении алгоритма iput перед завершением функции unlink. Поэтому процесс, открывший файл, может производить над файлом все обычные действия по его дескриптору, включая чтение из файла и запись в файл. Но когда процесс закрывает файл, значение счетчика ссылок в алгоритме iput становится равным 0, и ядро очищает содержимое файла. Короче говоря, процесс, открывший файл, продолжает работу так, как если бы функция unlink не выполнялась, а unlink, в свою очередь, работает так, как если бы файл не был открыт. Другие системные функции также могут продолжать выполняться в процессе, открывшем файл.

В приведенном на Рисунке 5.33 примере процесс открывает файл, указанный в качестве параметра, и затем удаляет связь только что открытого файла. Функция stat завершится неудачно, поскольку первоначальное имя после unlink больше не указывает на файл (предполагается, что тем временем никакой другой процесс не создал файл с тем же именем), но функция fstat завершится успешно, так как она выбирает индекс по дескриптору файла. Процесс выполняет цикл, считывая на каждом шаге по 1024 байта и пересылая файл в стандартный вывод. Когда при чтении будет обнаружен конец файла, процесс завершает работу: после завершения процесса файл перестает существовать. Процессы часто создают временные файлы и сразу же удаляют связь с ними; они могут продолжать ввод-вывод в эти файлы, но имена файлов больше не появляются в иерархии каталогов. Если процесс по какой-либо причине завершается аварийно, он не оставляет от временных файлов никакого следа.



Содержание раздела