int symlink(const char *oldpath, const char *newpath);

Аргумент oldpath содержит указываемый файл или каталог, a newpath является именем создаваемой символической ссылки. При успехе возвращается 0, а при ошибке (-1), возможные значения errno см. в справочной странице для symlink(2). У символических ссылок есть свои недостатки:

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

• Они добавляют лишние накладные расходы. Ядро должно больше работать для разрешения имени пути, содержащего символические ссылки.

• Они могут создать «циклы». Рассмотрите следующее:

$ rm -f a b /* Убедиться, что 'a' и 'b' не существуют */

$ ln -s a b /* Создать ссылку старого файла 'a' на новый 'b' */

$ ln -s b a /* Создать ссылку старого файла 'b' на новый 'a' */

$ cat а /* Что случилось? */

cat: a: Too many levels of symbolic links

Ядро должно быть способно определить такой случай и выдать сообщение об ошибке.

• Они легко обрываются. Если переместить указываемый файл в другое место или переименовать его, символическая ссылка больше не действительна. С прямой ссылкой такого случиться не может.

<p>5.2. Создание и удаление каталогов</p>

Создание и удаление каталогов просто. Двумя системными вызовами, что неудивительно, являются mkdir() и rmdir() соответственно:

#include /* POSIX */

#include

int mkdir(const char *pathname, mode_t mode);

#include /* POSIX */

int rmdir(const char *pathname);

Оба возвращают 0 при успехе и (-1) при ошибке, с соответствующим errno. Аргумент mode для mkdir() представляет права доступа, которые должны быть использованы для каталога. Он полностью идентичен аргументам mode для creat() и open(), обсуждавшимся в разделе 4.6 «Создание файлов».

Обе функции обрабатывают '.' и '..' в создаваемом или удаляемом каталоге. Перед удалением каталог должен быть пуст; если это не так, errno устанавливается в ENOTEMPTY. (В данном случае, «пуст» означает, что каталог содержит только '.' и '..'.)

Новым каталогам, как и всем файлам, присваивается идентификационный номер группы. К сожалению, его работа запутана. Мы отложим обсуждение до раздела 11.5.1 «Группа по умолчанию для новых файлов и каталогов».

Обе функции работают на одном уровне каталога за раз. Если /somedir существует, a /somedir/sub1 нет, 'mkdir("/somedir/sub1/sub2")' завершится неудачей. Каждый компонент в длинном пути должен создаваться отдельно (в соответствии с опцией -р mkdir, см. mkdir(1)).

Также, если pathname завершается символом '/', на некоторых системах mkdir() и rmdir() потерпят неудачу, а на других нет. Следующая программа, ch05-trymkdir.с, демонстрирует оба аспекта.

1  /* ch05-trymkdir.c --- Демонстрирует поведение mkdir().

2     Любезность Nelson H.F. Beebe. */

3

4  #include

5  #include

6  #include

7

8  #if !defined(EXIT_SUCCESS)

9  #define EXIT_SUCCESS 0

10 #endif

11

12 void do_test(const char *path)

13 {

14  int retcode;

15

16  errno = 0;

17  retcode = mkdir(path, 0755);

18  printf("mkdir(\"%s\") returns %d: errno = %d [%s)\n",

19   path, retcode, errno, strerror(errno));

20 }

21

22 int main(void)

23 {

24  do_test("/tmp/t1/t2/t3/t4"); /*Попытка создания в подкаталоге*/

25  do_test("/tmp/t1/t2/t3");

26  do_test("/tmp/t1/t2");

27  do_test("/tmp/t1");

28

29  do_test("/tmp/u1"); /* Создать подкаталоги */

30  do_test("/tmp/u1/u2");

31  do_test("/tmp/u1/u2/u3");

32  do_test("/tmp/u1/u2/u3/u4");

33

34  do_test("/tmp/v1/"); /* Как обрабатывается завершающий '/'? */

35  do_test("/tmp/v1/v2/");

36  do_test("/tmp/v1/v2/v3/");

37  do_test("/tmp/v1/v2/v3/v4/");

38

Перейти на страницу:

Похожие книги