Файлы -- это часть ресурсов, которыми распоряжается UNIX, имена файлов с этой точки зрения являются описывающими объектами.
Каждый файл обладает несколькими (хотя бы одним) полными именами,
с помощью этих имён пользователь может обращаться к файлам.
Для логической организации имён в реализации системы используются
каталоги, это специальные файлы содержащие список имён других файлов.
Специальный каталог называемый корневым содержит имена
файлов и каталогов, если пройтись по всем ссылкам в корневом каталоге то
мы посетим все файлы в файловой системе.
Для безопасности в большинстве систем UNIX, каталог может
обладать только одним именем, это предотвращает появление циклов в
графе файловой системы.
Таким образом файловая система образует дерево, листья которого --
это ссылки на файлы-не-каталоги. На рис.
показа
организация файловой системы.
Необходимость для файлов иметь несколько имён возникает из-за того, что на один и тот же файл можно смотреть с логически-разных точек зрения.
Полное имя файла определяется последовательностью имён каталогов, отделённых косой чертой `/'. Последняя часть полного имени называется просто именем файла.
Например: /usr/share/doc/bash/README
usr -- ссылка в корневом каталоге на каталог usr.
share -- ссылка в каталоге usr на каталог share с полным именем /usr/share
...
README -- ссылка в каталоге bash на файл README c полным именем
/usr/share/doc/bash/README
Имена файлов состоят из символов алфавита принятого в системе, и обычно следуя соглашениям принятым в языке С, буквы нижнего и верхнего регистра различаются, т. е. README, readME, readme -- три разных имени, вероятно трёх разных файлов.
Каждому файлу кроме имён ставится в соответствие один единственный набор
информации об этом файле. Эта информация хранится в файловой системе в
структуре, называемой inode(индекс -- не точный русский эквивалент).
inode содержит тип файла (см.
), права доступа к
файлу (см.
), время модификации файла, время создания
файла и время изменения inode (т. е. информации о файле), а так же
расположение файла на диске.
Современные системы поддерживают так называемую виртуальную файловую систему (VFS), т. е. ОС работает со стандартными, ,,виртуальными'' индексами, а то как информация хранится на диске -- дело драйверов файловых систем.
Таким образом для каждого файла не зависимо от имён (которые служат только логической организации файлов) содержится одна информация о том как с этим файлом работать.
Для каждого файла процесс может прочесть информацию о нем с помощью
системного вызова stat или fstat, если это
открытый файл (см.
)
Пользователь должен уметь запускать программы, а программы должны уметь читать входные данные и записывать результат. В результате мы получаем 3 основные операции: read (читать), write (писать), exec (выполнять).
Рассмотрим программу на языке С, читающую файл:
#include <unistd.h>
#include <fcntl.h>
int main (int argc, char **argv)
{
int fd;
char buf[100];
fd = open ("file.txt", O_RDONLY);
read (fd, buf, 100);
close (fd);
}
fd и buf -- переменные в программе. open, read и close -- стандартной библиотеки, которые просто вызывают (обычно по средствам программных прерываний) функции ядра ОС, носящие такие же названия (такие вызовы называются системными (system call)).
Системный вызов open регистрирует среди информации о процессе обращение к соответствующему файлу и записывает информацию необходимую для работы с файлом. Мы назовём это сессией работы с файлом. Результатом системного вызова является то, что процесс получает число называемое файловым дескриптором (file descriptor), это число идентифицирует обращение к данному файлу среди информации о процессе, т. е. является описывающим объектом для сессии.
Вызов read записывает 100 байт в место памяти buf, прочитанных из файла, на который ссылается дескриптор fd.
Вызов close сообщает системе что процесс больше не будет обращаться к файлу по данному дескриптору.
Каждая сессия работы с файлом содержит указатель на место чтения/записи, соответствующие операции производимые с данным обращением читают или записывают информацию в файле начиная с места определяемого этим указателем; операции также изменяют значение указателя, так чтобы последующие операции чтения или записи работали уже на новом месте в файле, с новыми данными.
Процессы работают не с именами файлов а с дескрипторами. Одна и та же сессия работы с файлом может иметь несколько дескрипторов на него ссылающихся, причем одну и ту же сессию могут использовать несколько процессов одновременно, у каждого из которых будет свой дескриптор ссылающийся на эту сессию. Если процессы читают файл одновременно, то каждый прочтет только часть этого файла, причем процессы не будут заранее знать какую часть. Один и тот же указатель на место чтения процессы будут сдвигать независимо друг от друга.
Для сессий работы с файлами у нас есть следующие системные вызовы:
Для непосредственной работы с открытыми файлами используются следующие системные вызовы:
Действия, которые выполняются различными системными вызовами, а именно: open, close, exec, read, write, lseek, -- зависят от типа файла. В UNIX эти типы заранее определены (в отличие от других систем, напр. Plan 9), вот они:
Например в имени /usr/doc/bash/README, /usr/doc -- символьная ссылка содержащая путь ``share/doc'', поэтому при системных вызовах ядро подставляет в строку пути вместо doc share/doc и получает /usr/share/doc/bash/README.
В системе UNIX одновременно могут работать несколько (много) пользователей. Каждый процесс выполняет какую-либо одну пользовательскую задачу, но у разных пользователей могут быть различные задачи. Поэтому присутствие пользователя в системе характеризуется тем, что какой-либо процесс работает от имени этого пользователя. Кроме этого пользователь никак не связан с системой. У каждого процесса есть пользователь от лица которого он работает.
Для ядра системы пользователь это просто число, называемое UID (user identifer) или идентификатор пользователя. Для пользователей с некоторыми UID'ами могут быть связаны осмысленные, ,,человеческие'' имена.
Было бы невозможно работать на ЭВМ, если бы пользователи могли
изменять, смотреть данные друг друга без разрешения. Для этого в файловой
системе хранится набор прав доступа к файлам (см.
).
В системе существует понятие группы, объединяющее пользователей
обладающих одинаковыми правами.
Итак, для каждого файла в файловой системе хранится идентификатор пользователя -- владельца файла, идентификатор группы которой принадлежит файл, и удостоверение права на выполнение 3-х операций: записи, чтения и выполнения, -- для 3-х категорий пользователей: владельца, членов группы, и всех остальных, не попадающих в первые две категории.
Владелец файла -- пользователь имеющий право изменять индекс файла, т. е. независимо от прав других пользователей только владелец может распоряжаться своими правами и раздавать права другим.
Группа файла -- способ выделить группу пользователей, которые будут обладать другими (обычно большими правами, чем остальные). Так как в UNIX все ресурсы представлены (по крайней мере так задумано) в виде файлов, то права пользователя в системе определяются именно правами на доступ к файлам. Если пользователь хочет дать некоторым другим пользователям особые права для доступа к файлу (файлам), то он создаёт группу и устанавливает идентификатор группы файла равным идентификатору данной группы, устанавливает необходимые права доступа для группы. В итоге пользователи входящие в эту группу (а пользователь может входить во много групп) получают установленные права. Таким образом для того чтобы получить набор прав пользователь должен входить в нужную группу. Группы позволяют разъединить права пользователя на отдельные составляющие, а также делить права между пользователями. Возможно было бы задавать права для каждого пользователя в отдельности, но тогда пришлось бы модифицировать при необходимости права каждого, а при использовании групп достаточно изменить права доступа файла для группы и все пользователи входящие в группы сразу получат другие права. Также можно легко давать и лишать прав пользователя, достаточно включить, исключить его из группы.
Каждый процесс содержит идентификаторы пользователя и групп от имени которых он работает. Процесс содержит
Для процесса обращающегося к файлу набор прав выбирается в следующей последовательности:
Такая последовательность выбора позволяет дать группе меньшие права, чем остальным, или даже лишить себя (владельца) части прав по отношению к остальным пользователям, правда эти возможности редко используются.
Мы знаем что для некоторых файлов мы не можем выполнить некоторые операции, например запись и выполнение для каталога, зачем же им все права доступа? Для каталога право на запись означает возможность создавать файлы в таком каталоге. А право на исполнение даёт возможность использовать каталог, как часть пути для доступа к файлу. Например пользователь может не иметь право читать каталог, но у него будет право на его исполнение, тогда пользователь не сможет прочитать какие файлы содержаться в каталоге, но сможет обратится к файлу в каталоге имя которого он знает.
Существует специальный пользователь от лица которого системные администраторы выполняют критические для системы действия. Имя такого пользователя root, для него обычно создаётся группа с тем же именем. Особенность этого пользователя в том что он не связан правами доступа к файлам и может выполнять любые физически возможные действия. Обычные пользователи не должны работать от лица root'а, обычно у системного администратора есть пароль для входа в систему как root, администратор запускает некоторые системные программы от имени root'а чтобы внести изменения, касающиеся всех пользователей системы.
Права доступа к файлу обычно записываются в одну строчку. Такую информацию выдаёт команда ls:
drwxr-xr-x 13 root root 312 Ноя 8 15:20 usrпервая строка символов -- это тип и права доступа к файлу, d -- тип файла, в данном случае каталог (directory), следующие три символа (rwx) -- права доступа для владельца файла (ему разрешены чтение (r, Reading), исполнение (x, eXecution) и запись (w, Writing). Следующая тройка символов для группы файла, пользователи из группы могут читать и писать в файл, на месте символа w стоит прочерк, означающий запрет на запись. Аналогично для всех остальных пользователей. Число тринадцать -- количество ссылок на файл, т. е. количество имён файла в файловой системе плюс количество процессов, которые работают с этим файлом. Первое слово root -- имя владельца файла, второе -- имя группы файла, дальше идёт дата модификации и имя файла.
Процессы могут изменять права доступа к файлу по своему усмотрению, если они являются владельцами файла. Насколько я знаю только root, может изменить владельца файла, таким образом большинство владельцев файлов являются их создателями. Процесс может изменить группу файла, если это одна из групп в которые входит этот процесс (т. е. это фактический идентификатор группы процесса или один из идентификаторов содержащимся в списке групп процесса). Для изменения группы и/или владельца файла используется системный вызов chown. Для изменения прав доступа используется вызов chmod.