Для создания каталога в вызов mkdir() передаётся путь к создаваемому каталогу. Вышележащий каталог должен существовать (??) и пользователь должен иметь право на запись в него.
#include <sys/stat.h>
int mkdir(const char *path, mode_t mode);
При создании файла вызовом open() с флагом O_CREAT в указанном в пути к файлу каталоге создаётся запись с именем файла. Новое имя для файла можно создать вызовом link().
#include <unistd.h>
int link("oldpath", "newpath");
Поскольку жёсткие ссылки возможны только в рамках одной ФС, то и имена "oldpath" и "newpath" должны находиться внутри одной ФС.
В Unix нет операции удаление файла. Есть лишь операция удаление из каталога жёсткой ссылки (имени) на объект. Каждый раз после удаления имени уменьшается счётчик имён в Inode файла. Когда счётчик имён становится равным нулю, файл становится недоступным по имени. Однако, если в этот момент файл был открыт одним или несколькими процессами, то он не удаляется из ФС. Только тогда, когда у файла ноль имён и он не открыт ни в одном процессе, его Inode и его блоки данных помечаются как свободные, т.е. происходит уничтожение файла.
Данное поведение позволяет выполнять трюк с невидимыми временными файлами. Файл создаётся, открывается, и тут же удаляется его имя. В результате невидимый файл будет существовать до завершения процесса в котором он был создан. В такой ситуации аварийное завершение процесса не оставляет нигде в ФС ненужных временных файлов.
Вызов unlink() неприменим к каталогам. unlink() символической ссылки удаляет имя символической ссылки, никак не влияя на объект, на который указывает символическая ссылка.
#include <unistd.h>
int unlink("file");
Вызов rename("old", "new") эквивалентен паре вызовов link("old", "new"); unlink("old");. В отличие от этой пары rename() можно применять к каталогам, а так же он не удалит объект при переименовании его в самого себя - rename("x", "x").
Каталог в Linux можно открыть как файл с помощью open с флагом O_DIRECTORY:
struct old_linux_dirent {
long d_ino; /* inode number */
off_t d_off; /* offset to this dirent */
unsigned short d_reclen; /* length of this d_name */
char d_name [NAME_MAX+1]; /* file name (null-terminated) */
} olddirp[SIZE];
// в Linux каталог можно открыть с помощью open
int fd=open("dirname", O_DIRECTORY);
// и прочитать его внутреннюю структуру
retval=readdir(fd, olddirp, SIZE);
но так делать не надо.
Для работы с каталогами надо использовать библиотечные функции opendir(3), readdir(3) и т.д.
#include <dirent.h>
struct dirent {
ino_t d_ino; /* номер inode */
off_t d_off; /* заглушка */
unsigned short d_reclen; /* заглушка */
unsigned char d_type; /* тип файла; поле не стандартизовано */
char d_name[256]; /* имя файла */
};
// открыть каталог
DIR *dirp;
dirp=opendir("dirname");
// или
dirp=fopendir(fd);
// прочитать запись за записью
struct dirent *rec;
do{
rec=readdir(dirp);
}while(rec)
// начать сначала
rewinddir(dirp);
// закрыть каталог
closedir(dirp);
Удалять можно только пустые каталоги.
#include <unistd.h>
int rmdir("pathname");