Linux 基础解惑:Linux 下文件描述符标志和文件描述符状态标志,文件状态标志,文件状态之间的区别

简介: Linux 基础解惑:Linux 下文件描述符标志和文件描述符状态标志,文件状态标志,文件状态之间的区别


以下是一个图示,展示了文件描述符以及与其相关的各种标志之间的关系:

在这个图中:

- "File Descriptor" 是一个文件的唯一标识符,它与一个具体的文件关联。

- "File Descriptor Flags" 控制文件的打开方式以及读写行为。

- "File Descriptor Status Flags" 控制文件描述符本身的状态。

- "File Status Flags" 和 "File Mode Flags" 控rols 文件的状态和模式。

简述

"文件描述符状态标志"(File Descriptor Status Flags)是用于表示文件描述符的状态。在进行 fork 操作时,文件描述符会被复制。目前,只定义了一种文件描述符状态标志,即 `FD_CLOEXEC`。这个标志用于指示在执行 exec 系列函数时关闭文件描述符,以防止新启动的程序意外访问到这个文件描述符。在一些文档和讨论中,人们可能会将 "文件描述符状态标志" 简称为 "文件描述符状态"。但是,为了避免混淆,我建议在讨论这些概念时尽可能使用完整的术语。

"文件描述符标志"(File Descriptor Flags)这些标志是在打开文件时设置的,用于控制文件的访问模式(例如,是只读、只写还是读写)和行为(例如,是否在数据写入时立即同步到磁盘,是否在读取时进行阻塞等)。这些标志可以在打开文件时通过 open 系统调用设置,也可以在文件打开后通过 fcntl 系统调用修改。

"文件状态":这是文件本身的一些属性,如文件的权限、大小、创建时间、修改时间等。这些属性通常可以通过 stat 系列的系统调用获取。

"文件状态标志"(File Status Flags)或 "文件模式标志"(File Mode Flags):这些标志位用于描述文件的状态,如文件的类型(普通文件、目录、符号链接等)、文件的访问权限(读、写、执行)等。这些标志位可以通过 stat、fstat、lstat 系列函数获取,也可以通过 chmod、fchmod 系列函数修改。

这四个概念都与文件和文件描述符的操作有关,但它们的含义和用途是不同的:在本文中,我们将介绍他们的区别

"文件描述符标志"(File Descriptor Flags)

  struct task_struct--->struct files_struct---> | struct file * fd_array[NR_OPEN_DEFAULT]
                                                                            | struct fdtable fdtab
  struct fdtable {
      unsigned int max_fds;
      struct file ** fd;      /* current fd array */
      fd_set *close_on_exec;
      fd_set *open_fds;
      struct rcu_head rcu;
      struct fdtable *next;
  };

在Linux内核中,每个进程都有一个task_struct结构,这个结构包含了进程的所有信息。其中,files_struct结构是用来管理进程打开的所有文件描述符的。

files_struct结构中有一个fd_array数组,这个数组中的每个元素都是一个指向file结构的指针,file结构代表了一个打开的文件。fd_array数组的索引就是我们通常说的文件描述符。

fdtable结构是用来管理文件描述符的,它包含了一个指向file结构指针数组的指针fd,以及两个fd_set类型的指针close_on_execopen_fdsclose_on_exec用来标记哪些文件描述符在执行exec系列函数时需要被关闭,open_fds用来标记哪些文件描述符是当前打开的。

文件描述符标志是指用于控制文件描述符行为的标志。在 Linux 中,每个打开的文件都会分配一个文件描述符,文件描述符是一个整数,它唯一标识打开的文件。文件描述符标志用于指定文件的打开模式(如只读、只写、读写等)和操作行为(如是否以追加模式写入、是否进行同步写入等)。

常见的文件描述符标志包括:

  • O_RDONLY:只读模式打开文件
  • O_WRONLY:只写模式打开文件
  • O_RDWR:读写模式打开文件
  • O_CREAT:如果文件不存在,则创建文件
  • O_TRUNC:截断文件
  • O_APPEND:追加到文件末尾
  • O_NONBLOCK:非阻塞I/O
  • O_SYNC:同步写入

可以使用系统调用open()来设置文件描述符标志。

下面示例将展示如何使用不同的文件描述符标志来打开和操作文件:

#include <fcntl.h>
#include <stdio.h>
 
int main() {
    int fd;
    char buffer[100];
 
    // 打开一个文件,如果文件不存在则创建它,设置为只写模式,并以追加模式写入
    fd = open("test.txt", O_WRONLY | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR);
    if (fd == -1) {
        perror("open");
        return 1;
    }
 
    // 写入一些数据
    if (write(fd, "Hello, World!\n", 14) == -1) {
        perror("write");
        return 1;
    }
 
    // 关闭文件
    if (close(fd) == -1) {
        perror("close");
        return 1;
    }
 
    // 重新打开文件,设置为非阻塞模式,并以读写模式打开
    fd = open("test.txt", O_RDWR | O_NONBLOCK);
    if (fd == -1) {
        perror("open");
        return 1;
    }
 
    // 读取一些数据
    if (read(fd, buffer, 100) == -1) {
        perror("read");
        return 1;
    }
 
    // 打印读取的数据
    printf("%s\n", buffer);
 
    // 关闭文件
    if (close(fd) == -1) {
        perror("close");
        return 1;
    }
 
    return 0;
}

"文件描述符状态标志"(File Descriptor Status Flags)

fdtable字段  fd_set *close_on_exec;

保存着进程文件描述符标志  

当前只定义了一个文件描述符标志FDCLOEXEC    

0: exec时不关闭已经打开的文件描述符    

1: exec时关闭已经打开的文件描述符  

在Linux内核中,fdtable结构的close_on_exec字段是一个指向fd_set类型的指针,它用来保存进程的文件描述符标志。

目前,只定义了一个文件描述符标志FD_CLOEXEC,它用来控制在执行exec系列函数时是否关闭已经打开的文件描述符。

如果FD_CLOEXEC标志被设置(即值为1),那么在执行exec系列函数时,对应的文件描述符会被关闭,新的程序无法访问到这个文件描述符。如果FD_CLOEXEC标志没有被设置(即值为0),那么在执行exec系列函数时,文件描述符不会被关闭,新的程序可以继续访问这个文件描述符。

这个标志可以通过fcntl系统调用的F_GETFDF_SETFD命令来获取和设置。

文件描述符状态标志(File Descriptor Status Flags)是与文件描述符相关的一些状态信息。这些状态信息通常在文件打开或创建时设置,并且在文件的生命周期内保持不变。目前,Linux/Unix 系统中只定义了一种文件描述符状态标志,即 FD_CLOEXEC。这个标志用于指示在执行 exec 系列函数时关闭文件描述符,以防止新启动的程序意外访问到这个文件描述符。

这样的描述应该更准确地反映了 "文件描述符状态标志" 的含义。

1. `FD_CLOEXEC`(Close on Exec):在执行 exec 系列函数时关闭文件描述符。这是为了防止新启动的程序意外访问到这个文件描述符。

在 Linux 中,可以使用系统调用 `fcntl` 来获取或设置文件描述符状态标志。

文件状态标志可以使用fcntl()系统调用来设置或获取。例如,设置文件为非阻塞I/O模式可以使用以下代码:

#include <fcntl.h>
 
int flags;
 
// 获取文件描述符状态标志
flags = fcntl(fd, F_GETFD);
 
// 设置文件描述符状态标志
flags |= FD_CLOEXEC;
fcntl(fd, F_SETFD, flags);

在上述代码中,`fd` 是文件描述符,`F_GETFD` 是获取文件描述符状态标志的命令,`F_SETFD` 是设置文件描述符状态标志的命令。首先,我们使用 `fcntl` 获取当前的文件描述符状态标志,然后将 `FD_CLOEXEC` 标志添加到 `flags` 中,最后使用 `fcntl` 设置新的文件描述符状态标志。

请注意,文件描述符状态标志与文件描述符标志不同,它们不能在打开文件时设置,只能在文件打开后修改。


在使用文件描述符和文件状态标志时,需要注意它们的不同作用和使用方式。文件描述符标志用于打开文件和指定如何读写文件,而文件状态标志用于控制文件的操作和状态。同时,文件描述符标志和文件状态标志可以一起使用,以实现更多的功能。

总之,理解文件描述符标志和文件状态标志的区别和使用,是Linux系统编程中的基础知识,对于实现高效的文件操作非常重要。


文件状态

"文件状态" 是指文件本身的一些属性,这些属性描述了文件的各种特性和状态。在 Unix 和 Linux 系统中,文件状态可以通过 `stat`、`fstat` 或 `lstat` 等系统调用获取。以下是一些常见的文件状态属性:

1. **文件类型**:这是文件的基本类型,可能的类型包括普通文件、目录、符号链接、字符设备、块设备、管道、套接字等。

2. **文件大小**:这是文件的大小,以字节为单位。对于某些类型的文件(如设备文件),这个值可能没有意义。

3. **文件权限**:这是文件的访问权限,包括所有者的权限、所属组的权限和其他用户的权限。每种权限都可以分为读、写和执行三种。

4. **文件所有者**:这是文件的所有者,通常是创建文件的用户的用户 ID。

5. **文件所属组**:这是文件的所属组,通常是创建文件的用户的主组。

6. **文件创建时间**:这是文件被创建的时间。

7. **文件访问时间**:这是文件最后被访问的时间。

8. **文件修改时间**:这是文件内容最后被修改的时间。

9. **文件状态改变时间**:这是文件状态(如权限或所有权)最后被修改的时间。

在 C 语言中,可以使用 `stat` 结构来保存 `stat` 系列函数返回的文件状态信息。例如:

#include <sys/stat.h>
#include <unistd.h>
 
struct stat st;
if (stat("/path/to/file", &st) == 0) {
    // 文件状态信息现在保存在 st 结构中
}

在这个例子中,`stat` 函数将 `/path/to/file` 的文件状态信息保存在 `st` 结构中。然后,你可以通过 `st` 结构的各个字段来访问文件的状态信息。例如,`st.st_size` 是文件的大小,`st.st_mode` 是文件的权限,`st.st_atime` 是文件的访问时间等。

文件状态标志"(File Status Flags)/"文件模式标志"(File Mode Flags)

在 Linux/Unix 系统中,我们通常讨论的是 "文件状态标志"(File Status Flags)或 "文件模式标志"(File Mode Flags)。这些标志位用于描述文件的状态,如文件的类型(普通文件、目录、符号链接等)、文件的访问权限(读、写、执行)等。这些标志位可以通过 `stat`、`fstat`、`lstat` 系列函数获取,也可以通过 `chmod`、`fchmod` 系列函数修改。

例如,以下是一些常见的文件状态标志:

- `S_IRUSR`:用户(文件所有者)具有读取权限。

- `S_IWUSR`:用户(文件所有者)具有写入权限。

- `S_IXUSR`:用户(文件所有者)具有执行权限。

- `S_IRGRP`:组(文件所有者所在的组)具有读取权限。

- `S_IWGRP`:组(文件所有者所在的组)具有写入权限。

- `S_IXGRP`:组(文件所有者所在的组)具有执行权限。

- `S_IROTH`:其他人(非文件所有者和非组成员)具有读取权限。

- `S_IWOTH`:其他人(非文件所有者和非组成员)具有写入权限。

- `S_IXOTH`:其他人(非文件所有者和非组成员)具有执行权限。

这些标志位可以组合使用,例如 `S_IRUSR | S_IWUSR | S_IXUSR` 表示用户(文件所有者)具有读、写、执行权限。

目录
相关文章
|
3月前
|
存储 数据管理 Linux
区分Linux中.tar文件与.tar.gz文件的不同。
总之,".tar"文件提供了一种方便的文件整理方式,其归档但不压缩的特点适用于快速打包和解压,而".tar.gz"文件通过额外的压缩步骤,尽管处理时间更长,但可以减小文件尺寸,更适合于需要节约存储空间或进行文件传输的场景。用户在选择时应根据具体需求,考虑两种格式各自的优劣。
499 13
|
2月前
|
存储 Ubuntu 安全
Linux中Centos和Ubuntu的区别
CentOS主要面向服务器环境,而Ubuntu适用于服务器和桌面环境。   CentOS提供更精简的安装,而Ubuntu提供更广泛的开箱即用功能。   CentOS遵循RHEL的所有安全实践,而Ubuntu在安全方面采取更积极的方法。
|
2月前
|
Ubuntu 安全 Unix
Linux和Ubuntu有什么区别
综上所述,Linux和Ubuntu之间存在明显的区别。Linux是一种操作系统内核,而Ubuntu是基于Linux内核的发行版本,具有更好的易用性、社区支持和软件仓库。用户可以根据自己的需求选择不同的Linux发行版本,如果需要一个稳定、易于使用的桌面环境,Ubuntu是一个不错的选择。如果需要更加灵活和定制性强的系统,其他Linux发行版本可能更加适合。
|
4月前
|
安全 Linux
Linux赋予文件000权限的恢复技巧
以上这些步骤就像是打开一扇锁住的门,步骤看似简单,但是背后却有着严格的逻辑和规则。切记,在任何时候,变更文件权限都要考虑安全性,不要无谓地放宽权限,那样可能
152 16
|
3月前
|
安全 Unix Java
linux中kill -9和kill -15区别
在 Linux/Unix 系统中,`kill -9` 和 `kill -15` 是终止进程的常用命令,核心区别在于发送的信号类型不同,导致进程终止行为截然不同。`kill -15`(SIGTERM)允许进程进行清理操作后优雅退出,适用于正常关闭;而 `kill -9`(SIGKILL)则强制终止进程,不给予任何清理机会,仅在进程无响应时使用。本文从信号类型、行为、工作原理及使用建议等方面进行详细对比,帮助你更安全、有效地管理进程。
351 0
|
4月前
|
存储 Linux 数据处理
深入剖析Linux中一切即文件的哲学和重定向的机制
在计算机的奇妙世界中,Linux的这套哲学和机制减少了不同类型资源的处理方式,简化了抽象的概念,并蕴藏着强大的灵活性。就像变戏法一样,轻轻松松地在文件、程序与设备之间转换数据流,标准输入、输出、错误流就在指尖舞动,程序的交互和数据处理因此变得既高效又富有乐趣。
72 4
|
5月前
|
Linux
【Linux】 Linux文件I/O常见操作技巧
以上就是Linux文件I/O操作的一些技巧,接纳它们,让它们成为你在Linux世界中的得力伙伴,工作会变得轻松许多。不过记住,技巧的运用也需要根据实际情况灵活掌握,毕竟,最适合的才是最好的。
144 28
|
5月前
|
Ubuntu Linux
"unzip"命令解析:Linux下如何处理压缩文件。
总的来说,`unzip`命令是Linux系统下一款实用而方便的ZIP格式文件处理工具。本文通过简明扼要的方式,详细介绍了在各类Linux发行版上安装 `unzip`的方法,以及如何使用 `unzip`命令进行解压、查看和测试ZIP文件。希望本文章能为用户带来实际帮助,提高日常操作的效率。
679 12
|
4月前
|
Linux
linux文件重命名命令
本指南介绍Linux文件重命名方法,包括单文件操作的`mv`命令和批量处理的`rename`命令。`mv`可简单更改文件名并保留扩展名,如`mv old_file.txt new_name.txt`;`rename`支持正则表达式,适用于复杂批量操作,如`rename &#39;s/2023/2024/&#39; *.log`。提供实用技巧如大小写转换、数字序列处理等,并提醒覆盖风险与版本差异,建议使用`-n`参数预览效果。
|
Linux
linux下两个进程可以同时打开同一个文件吗?返回的文件描述符一样吗?
linux下两个进程可以同时打开同一个文件吗?返回的文件描述符一样吗? 一:结论 1.两个进程中分别产生生成两个独立的fd 2.两个进程可以任意对文件进行读写操作,操作系统并不保证写的原子性 3.进程可以通过系统调用对文件加锁,从而实现对文件内容的保护 4. 任何一个进程删除该文件时,另外一个进程不会立即出现读写失败 5.两个进程可以分别读取文件的不同部分而不会相互影响 6.一个进程对文件长度和内容的修改另外一个进程可以立即感知   二:文件描述符与打开文件的关系? 内核中,对应于每个进程都有一个文件描述符表,表示这个进程打开的所有文件。
3237 0
下一篇
oss教程