一、创建文件
1、创建普通文件
int creat(const char *pathname, mode_t mode);
也可以使用open和openat创建普通文件:如果参数flags设置标志位O_CREAT,表示“如果文件不存在,创建文件”;如果参数flags设置标志位O_CREAT|O_EXCL,表示创建文件,如果文件已经存在,返回错误:
int open(const char *pathname, int flags, mode_t mode);
int openat(int dirfd, const char *pathname, int flags, mode_t mode);
2、创建目录
int mkdir(const char *pathname, mode_t mode);
int mkdirat(int dirfd, const char *pathname, mode_t mode);
3、创建符号链接
int symlink(const char *oldpath, const char *newpath);
int symlinkat(const char *oldpath, int newdirfd, const char *newpath);
4、mknod通常用来创建字符设备文件和块设备文件,也可以创建普通文件、命名管道和套接字:
int mknod(const char *pathname, mode_t mode, dev_t dev);
int mknodat(int dirfd, const char *pathname, mode_t mode, dev_t dev);
5、link用来创建硬链接,给已经存在的文件增加新的名称
int link(const char *oldpath, const char *newpath);
int linkat(int olddfd, const char *oldpath, int newdfd, const char *newpath);
glibc库封装了和上面的系统调用同名的库函数,还封装了创建命名管道的库函数:
int mkfifo(const char *pathname, mode_t mode);
库函数mkfifo是通过调用系统调用mknod来实现的。
创建文件需要在文件系统中分配一个索引节点,然后在父目录的数据中增加一个目录项来保存文件的名称和索引节点编号。因为各种文件系统类型的物理结构不同,所以需要提供索引节点操作集合的create方法。
二、删除文件
1、unlink用来删除文件的名称,如果文件的硬链接计数变成0,并且没有进程打开这个文件,那么删除文件。
int unlink(const char *pathname);
int unlinkat(int dirfd, const char *pathname, int flags);
2、删除目录
int rmdir(const char *pathname);
删除文件需要从父目录的数据中删除文件对应的目录项,把文件的索引节点的硬链接计数减1(一个文件可以有多个名称,Linux把文件名称称为硬链接),如果索引节点的硬链接计数变成0,那么释放索引节点。因为各种文件系统类型的物理结构不同,所以需要提供索引节点操作集合的unlink方法。
系统调用unlink和unlinkat都把主要工作委托给函数do_unlinkat,unlink传入特殊的文件描述符AT_FDCWD,表示“如果文件路径是相对路径,解释为相对调用进程的当前工作目录”:
fs/namei.c
SYSCALL_DEFINE3(unlinkat, int, dfd, const char __user *, pathname, int, flag)
{
if ((flag & ~AT_REMOVEDIR) != 0)
return -EINVAL;
if (flag & AT_REMOVEDIR)
return do_rmdir(dfd, pathname);
return do_unlinkat(dfd, pathname);
}
SYSCALL_DEFINE1(unlink, const char __user *, pathname)
{
return do_unlinkat(AT_FDCWD, pathname);
}