Символическая связь позволяет косвенно адресовать другой файл файловой системы. Системный вызов symlink(2) служит для создания символической связи. Этим вызовом, кстати, пользуется команда ln -s .
#include
int symlink (const char *name, const char *synmame);
После создания символической связи, доступ к целевому файлу name может осуществляться с помощью symname
. При этом, функция open(2) , принимая в качестве аргумента имя символической связи, на самом деле открывает целевой файл. Такая особенность называется следованием символической связи. Не все системные вызовы обладают этим свойством. Например, системный вызов unlink(2) , удаляющий запись в каталоге, действует только на саму символическую связь. В противном случае, мы не имели бы возможности удалить ее. В табл. 2.11 показано, как работают с символическими связями различные системные вызовы.
Таблица 2.11. Интерпретация символической связи различными системными вызовами
Системный вызов |
Следует символической связи |
Не следует символической связи |
access(2) |
+ |
|
chdir(2) |
+ |
|
chmod(2) |
+ |
|
chown(2) |
+ |
|
lchown(2) |
|
+ |
creat(2) |
+ |
|
exec(2) |
+ |
|
link(2) |
+ |
|
mkdir(2) |
+ |
|
mknod(2) |
|
+ |
open(2) |
+ |
|
readlink(2) |
|
+ |
rename(2) |
|
+ |
stat(2) |
+ |
|
lstat(2) |
|
+ |
unlink(2) |
|
+ |
Для чтения содержимого файла — символической связи используется системный вызов readlink(2) :
#include
int readlink(const char *path, void *buf, size_t bufsiz);
Аргумент path
содержит имя символической связи. В буфере buf
размером bufsiz
возвращается содержимое файла — символической связи.
Для иллюстрации к вышеприведенным рассуждениям приведем пример программы, которая сначала выводит содержимое символической связи, а затем — целевого файла, пользуясь в обоих случаях символическим именем:
#include
#include
#include
#include
#define BUFSZ 256
/* В качестве аргумента программа принимает имя
символической связи */
main(int argc, char *argv[]) {
char buf[BUFSZ+1];
int nread, fd;
/* Прочитаем содержимое самой символической связи */
printf("Читаем символическую связь\n");
nread = readlink(argv[1], buf, BUFSZ);
if (nread < 0) {
perror("readlink");
exit(1);
}
/* readlink не завершает строку '\0' */
printf("Символическая связь:\n %s\n", buf);
/* Теперь прочитаем содержимое целевого файла */
printf("Читаем целевой файл\n");
fd = open(argv[1], O_RDONLY);
if (fd < 0) {
perror("open");
exit(2);
}
nread = read(fd, buf, BUFSIZ);
if (nread < 0) {
perror("read");
exit(3);
}
buf[nread] = '\0';
printf("Целевой файл:\n %s\n", buf);
close(fd);
exit(0);
}
Перед тем как запустить программу, создадим символическую связь с файлом unix0.txt:
$ ln -s unix0.txt symlink.txt
$ ls -l
lrwxrwxrwx 1 andy user 10 Jan 6 09:54 symlink.txt -> unix0.txt
-rw-r--r-- 1 andy user 498 Jan 6 09:53 unix0.txt
$ a.out symlink.txt
Читаем символическую связь
Символическая связь:
unix0.txt
Читаем целевой файл
Целевой файл:
Начиная с 1975 года фирма AT&T начала предоставлять лицензии на
использование операционной системы как научно-образовательным
учреждениям, так и коммерческим организациям. Поскольку основная
часть системы поставлялась в исходных текстах, написанных на
языке С, опытным программистам не требовалось детальной
документации, чтобы разобраться в архитектуре UNIX. С ростом
популярности микропроцессоров
...
Файлы, отображаемые в памяти
Системный вызов mmap(2) предоставляет механизм доступа к файлам, альтернативный вызовам read(2) и write(2) . С помощью этого вызова процесс имеет возможность отобразить участки файла в собственное адресное пространство. После этого данные файла могут быть получены или записаны путем чтения или записи в память. Функция mmap(2) определяется следующим образом:
#include
#include
caddr_t mmap(caddr_t addr, size_t len, int prot,
int flags, int fildes, off_t off);
Читать дальше