int symlink(const char *oldpath, const char *newpath);
Аргумент oldpath
содержит указываемый файл или каталог, a newpath
является именем создаваемой символической ссылки. При успехе возвращается 0, а при ошибке (-1), возможные значения errno
см. в справочной странице для
• Они занимают лишнее дисковое пространство, требуя отдельного индекса и блока данных. Прямые ссылки занимают лишь элемент каталога.
• Они добавляют лишние накладные расходы. Ядро должно больше работать для разрешения имени пути, содержащего символические ссылки.
• Они могут создать «циклы». Рассмотрите следующее:
$ 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
Ядро должно быть способно определить такой случай и выдать сообщение об ошибке.
• Они легко обрываются. Если переместить указываемый файл в другое место или переименовать его, символическая ссылка больше не действительна. С прямой ссылкой такого случиться не может.
5.2. Создание и удаление каталогов
Создание и удаление каталогов просто. Двумя системными вызовами, что неудивительно, являются mkdir()
и rmdir()
соответственно:
#include
#include
int mkdir(const char *pathname, mode_t mode);
#include
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
, см.
Также, если 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