Книга: Linux программирование в примерах

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

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

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

#include <sys/types.h> /* POSIX */
#include <sys/stat.h>
int mkdir(const char *pathname, mode_t mode);
#include <unistd.h> /* 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 <stdio.h>
5  #include <stdlib.h>
6  #include <errno.h>
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
39  return(EXIT_SUCCESS);
40 }

Вот результаты для GNU/Linux:

$ ch05-trymkdir
mkdir("/tmp/t1/t2/t3/t4") returns -1: errno = 2 [No such file or directory)
mkdir("/tmp/t1/t2/t3") returns -1: errno = 2 [No such file or directory)
mkdir("/tmp/t1/t2") returns -1: errno = 2 [No such file or directory]
mkdir("/tmp/t1") returns 0: errno = 0 [Success]
mkdir("/tmp/u1") returns 0: errno = 0 [Success]
mkdir("/tmp/u1/u2") returns 0: errno = 0 [Success]
mkdir("/tmp/u1/u2/u3") returns 0: errno = 0 [Success]
mkdir("/tmp/u1/u2/u3/u4") returns 0: errno = 0 [Success]
mkdir("/tmp/v1/") returns 0: errno = 0 [Success]
mkdir("/tmp/v1/v2/") returns 0: errno = 0 (Success]
mkdir("/tmp/v1/v2/v3/") returns 0: errno = 0 [Success]
mkdir("/tmp/v1/v2/v3/v4/") returns 0: errno = 0 [Success]

Обратите внимание, как GNU/Linux принимает завершающий слеш. Не все системы так делают.

Оглавление книги


Генерация: 3.342. Запросов К БД/Cache: 3 / 0
поделиться
Вверх Вниз