KnigaRead.com/
KnigaRead.com » Компьютеры и Интернет » Программное обеспечение » Андрей Робачевский - Операционная система UNIX

Андрей Робачевский - Операционная система UNIX

На нашем сайте KnigaRead.com Вы можете абсолютно бесплатно читать книгу онлайн Андрей Робачевский, "Операционная система UNIX" бесплатно, без регистрации.
Перейти на страницу:

Все значения времени, связанные с файлом (время доступа, модификации данных и метаданных) хранятся в секундах, прошедших с 0 часов 1 января 1970 года. Заметим, что информация о времени создания файла отсутствует.

Приведенная ниже программа выводит информацию о файле, имя которого передается ей в качестве аргумента:

#include <sys/types.h>

#include <sys/stat.h>

#include <time.h>


main(int argc, char *argv[]) {

 struct stat s;

 char* ptype;

 lstat(argv[1] , &s); /* Определим тип файла */

 if (S_ISREG(s.st_mode)) ptype = "Обычный файл";

 else if (S_ISDIR(s.st_mode)) ptype = "Каталог";

 else if (S_ISLNK(s.st_mode)) ptype = "Симв. Связь";

 else if (S_ISCHR(s.st_mode)) ptype = "Симв. Устройство";

 else if (S_ISBLK(s.st_mode)) ptype = "Бл.устройство";

 else if (S_ISSOCK(s.st_mode)) ptype = "Сокет";

 else if (S_ISFIFO(s.st_mode)) ptype = "FIFO";

 else ptype = "Неизвестный тип";

 /* Выведем информацию о файле */

 /* Его тип */

 printf("type = %sn", ptype);

 /* Права доступа */

 printf("perm =%on", s.st_mode & S_IAMB);

 /* Номер inode */

 printf("inode = %dn", s.st_ino);

 /* Число связей */

 printf("nlink = %dn", s.st_nlink);

 /* Устройство, на котором хранятся данные файла */

 printf("dev = (%d, %d)n", major(s.st_dev), minor(s.st_dev));

 /* Владельцы файла */

 printf("UID = %dn", s.st_uid);

 printf("GID = %dn", s.st_gid);

 /* Для специальных файлов устройств - номера устройства */

 printf("rdev = (%d, %d)n", major(s.st_rdev),

 minor(s.st_rdev));

 /* Размер файла */

 printf("size = %dn", s.st_size);

 /* Время доступа, модификации и модификации метаданных */

 printf("atime = %s", ctime(&s.st_atime));

 printf("mtime = %s", ctime(&s.st_mtime));

 printf("ctime = %s", ctime(&s.st_ctime));

}

Программа использует библиотечные функции major(3C) и minor(3C), возвращающие, соответственно, старший и младший номера устройства. Функция ctime(3C) преобразует системное время в удобный формат.

Запуск программы на выполнение приведет к следующим результатам:

$ а.out ftype.c

type = Обычный файл

perm = 644

inode = 13

nlink = 1

dev = (1, 42)

UID = 286

GID = 100

rdev = (0, 0)

size = 1064

atime = Wed Jan 8 17:25:34 1997

mtime = Wed Jan 8 17:19:27 1997

ctime = Wed Jan 8 17:19:27 1997

$ ls -il /tmp/ftype.c

13 -rw-r--r-- 1 andy user 1064 Jan 8 17:19 ftype.c

Процессы

В главе 1 уже упоминались процессы. Однако знакомство ограничивалось пользовательским, или командным интерфейсом операционной системы. В этом разделе попробуем взглянуть на них с точки зрения программиста.

Процессы являются основным двигателем операционной системы. Большинство функций выполняется ядром требованию того или иного процесса. Выполнение этих функций контролируется привилегиями процесса, которые соответствуют привилегиям пользователя, запустившего его.

В этом разделе рассматриваются:

□ Идентификаторы процесса

□ Программный интерфейс управления памятью: системные вызовы низкого уровня и библиотечные функции, позволяющие упростить управление динамической памятью процесса.

□ Важнейшие системные вызовы, обеспечивающие создание нового процесса и запуск новой программы. Именно с помощью этих вызовов создается существующая популяция процессов в операционной системе и ее функциональность.

□ Сигналы и способы управления ими. Сигналы можно рассматривать как элементарную форму межпроцессного взаимодействия, позволяющую процессам сообщать друг другу о наступлении некоторых событий. Более мощные средства будут рассмотрены в разделе "Взаимодействие между процессами" главы 3.

□ Группы и сеансы; взаимодействие процесса с пользователем.

□ Ограничения, накладываемые на процесс, и функции, которые позволяют управлять этими ограничениями.

Идентификаторы процесса

Вы уже знаете, что каждый процесс характеризуется набором атрибутов и идентификаторов, позволяющих системе управлять его работой. Важнейшими из них являются идентификатор процесса PID и идентификатор родительского процесса PPID. PID является именем процесса в операционной системе, по которому мы можем адресовать его, например, при отправлении сигнала. PPID указывает на родственные отношения между процессами, которые (как и в жизни) в значительной степени определяют его свойства и возможности.

Однако нельзя не отметить еще четыре идентификатора, играющие решающую роль при доступе к системным ресурсам: идентификатор пользователя UID, эффективный идентификатор пользователя EUID, идентификатор группы GID и эффективный идентификатор группы EGID. Эти идентификаторы определяют права процесса в файловой системе, и как следствие, в операционной системе в целом. Запуская различные команды и утилиты, можно заметить, что порожденные этими командами процессы полностью отражают права пользователя UNIX. Причина проста — все процессы, которые запускаются, имеют идентификатор пользователя и идентификатор группы. Исключение составляют процессы с установленными флагами SUID и SGID.

При регистрации пользователя в системе утилита login(1) запускает командный интерпретатор, — login shell, имя которого является одним из атрибутов пользователя. При этом идентификаторам UID (EUID) и GID (EGID) процесса shell присваиваются значения, полученные из записи пользователя в файле паролей /etc/passwd. Таким образом, командный интерпретатор обладает правами, определенными для данного пользователя.

При запуске программы командный интерпретатор порождает процесс, который наследует все четыре идентификатора и, следовательно, имеет те же права, что и shell. Поскольку в конкретном сеансе работы пользователя в системе прародителем всех процессов является login shell, то и их пользовательские идентификаторы будут идентичны.

Казалось бы, эту стройную систему могут "испортить" утилиты с установленными флагами SUID и SGID. Но не стоит волноваться — как правило, такие программы не позволяют порождать другие процессы, в противном случае, эти утилиты необходимо немедленно уничтожить!

На рис. 2.10. показан процесс наследования пользовательских идентификаторов в рамках одного сеанса работы.

Рис. 2.10. Наследование пользовательских идентификаторов

Для получения значений идентификаторов процесса используются следующие системные вызовы:

#include <sys/types.h>

#include <unistd.h>


uid_t getuid(void);

uid_t geteuid(void);

gid_t getgid(void);

gid_t getegid(void);

Эти функции возвращают для сделавшего вызов процесса соответственно реальный и эффективный идентификаторы пользователя и реальный и эффективный идентификаторы группы.

Процесс также может изменить значения этих идентификаторов с помощью системных вызовов:

#include <sys/types.h>

#include <unistd.h>


int setuid(uid_t uid);

int setegid(gid_t egid);

int seteuid(uid_t euid);

int setgid(gid_t gid);

Системные вызовы setuid(2) и setgid(2) устанавливают сразу реальный и эффективный идентификаторы, а системные вызовы seteuid(2) и setegid(2) — только эффективные.

Ниже приведен фрагмент программы login(1), изменяющей идентификаторы процесса на значения, полученные из записи файла паролей. В стандартной библиотеке имеется ряд функций работы с записями файла паролей, каждая из которых описывается структурой passwd, определенной в файле <pwd.h>. Поля этой структуры приведены в табл. 2.17.


Таблица 2.17. Поля структуры passwd

Поле Значение char *pw_name Имя пользователя char *pw_passwd Строка, содержащая пароль в зашифрованном виде; из соображения безопасности в большинстве систем пароль хранится в файле /etc/shadow, а это поле не используется uid_t pw_uid Идентификатор пользователя gid_t pw_gid Идентификатор группы char *pw_gecos Комментарий (поле GECOS), обычно реальное имя пользователя и дополнительная информация char *pw_dir Домашний каталог пользователя char *pw_shell Командный интерпретатор

Функция, которая потребуется для нашего примера, позволяет получить запись файла паролей по имени пользователя. Она имеет следующий вид:

Перейти на страницу:
Прокомментировать
Подтвердите что вы не робот:*