在 Linux 上打开文件实际上有什么作用?
当我们谈论打开文件时,我们有不同的情况,例如打开文件时我们实际调用的是什么语言和 API。虽然在大多数情况下它非常简单,但高级语言最终会调用 C API 或直接调用open()同样用 C 编写的 Linux函数。
如果我们尝试谈论不同的语言,那么这是一个非常广泛的问题,无法在一篇文章中涵盖,这是因为添加新语言和不同 API 时会增加其绝对复杂性。
现在一旦确定我们在谈论 C 和 Linux,让我们首先看看在 Linux 中打开文件时调用的 C 代码。
考虑下面显示的代码 -
int sys_open(const char *filename, int flags, int mode) {char *tmp = getname(filename);
int fd = get_unused_fd();
struct file *f = filp_open(tmp, flags, mode);
fd_install(fd, f);
putname(tmp);
return fd;
}
上面的代码也可以在你的 linux 机器上的 fs/open.c 文件中找到。
现在,正如我们所看到的,从这个函数中调用了许多函数,其中第一个是命名的函数getname(),我们将文件名作为参数传递给它,函数的代码getname()看起来像这样 -
#define __getname() kmem_cache_alloc(names_cachep, SLAB_KERNEL)#define putname(name) kmem_cache_free(names_cachep, (void *)(name))
char *getname(const char *filename) {
char *tmp = __getname(); /* allocate some memory */
strncpy_from_user(tmp, filename, PATH_MAX + 1);
return tmp;
}
上面的代码可以在 fs/namei.c 文件中找到,它的主要用途是从用户空间复制文件名并传递到内核空间。然后在该getname()函数之后,我们有一个get_unused_fd()函数,它返回一个未使用的文件描述符,它只不过是当前打开的文件的可增长列表中的整数索引。get_unused_fd()函数的代码看起来像这样 -
int get_unused_fd(void) {struct files_struct *files = current->files;
int fd = find_next_zero_bit(files->open_fds,
files->max_fdset, files->next_fd);
FD_SET(fd, files->open_fds); /* in use now */
files->next_fd = fd + 1;
return fd;
}
现在我们有了filp_open()具有以下实现的函数 -
struct file *filp_open(const char *filename, int flags, int mode) {struct nameidata nd;
open_namei(filename, flags, mode, &nd);
return dentry_open(nd.dentry, nd.mnt, flags);
}
上述函数起到两个关键作用,首先,它使用文件系统查找与传入路径的文件名对应的 inode。接下来,如果创建一个包含有关 inode 的所有基本信息的结构文件,然后返回文件。
现在,调用堆栈中的下一个函数是fd_install()可以在 include/linux/file.h 文件中找到的函数。它用于存储函数返回的信息filp_open()。该fd_install()函数的代码如下所示 -
void fd_install(unsigned int fd, struct file *file) {struct files_struct *files = current->files;
files->fd[fd] = file;
}
然后我们有一个store()函数来存储从filp_open()函数返回的结构体,然后将该结构体安装到进程的打开文件列表中。
下一步是释放分配的内核控制内存块。最后,返回文件描述,然后可以传递给其他C函数一样close(),write()等等。
以上是 在 Linux 上打开文件实际上有什么作用? 的全部内容, 来源链接: utcz.com/z/338818.html