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` 表示用户(文件所有者)具有读、写、执行权限。

目录
相关文章
|
9天前
|
Linux Shell 网络安全
Kali Linux系统Metasploit框架利用 HTA 文件进行渗透测试实验
本指南介绍如何利用 HTA 文件和 Metasploit 框架进行渗透测试。通过创建反向 shell、生成 HTA 文件、设置 HTTP 服务器和发送文件,最终实现对目标系统的控制。适用于教育目的,需合法授权。
42 9
Kali Linux系统Metasploit框架利用 HTA 文件进行渗透测试实验
|
1月前
|
Linux 开发工具 Perl
在Linux中,有一个文件,如何删除包含“www“字样的字符?
在Linux中,如果你想删除一个文件中包含特定字样(如“www”)的所有字符或行,你可以使用多种文本处理工具来实现。以下是一些常见的方法:
41 5
|
1月前
|
安全 Linux 数据安全/隐私保护
在 Linux 系统中,查找文件所有者是系统管理和安全审计的重要技能。
在 Linux 系统中,查找文件所有者是系统管理和安全审计的重要技能。本文介绍了使用 `ls -l` 和 `stat` 命令查找文件所有者的基本方法,以及通过文件路径、通配符和结合其他命令的高级技巧。还提供了实际案例分析和注意事项,帮助读者更好地掌握这一操作。
51 6
|
1月前
|
Linux
在 Linux 系统中,`find` 命令是一个强大的文件查找工具
在 Linux 系统中,`find` 命令是一个强大的文件查找工具。本文详细介绍了 `find` 命令的基本语法、常用选项和具体应用示例,帮助用户快速掌握如何根据文件名、类型、大小、修改时间等条件查找文件,并展示了如何结合逻辑运算符、正则表达式和排除特定目录等高级用法。
94 6
|
1月前
|
监控 Linux Perl
Linux 命令小技巧:显示文件指定行的内容
在 Linux 系统中,处理文本文件是一项常见任务。本文介绍了如何使用 head、tail、sed 和 awk 等命令快速显示文件中的指定行内容,帮助你高效处理文本文件。通过实际应用场景和案例分析,展示了这些命令在代码审查、日志分析和文本处理中的具体用途。同时,还提供了注意事项和技巧,帮助你更好地掌握这些命令。
79 4
|
1月前
|
网络协议 Linux
linux系统重要文件目录
本文介绍了Linux系统中的重要目录及其历史背景,包括根目录、/usr、/etc、/var/log和/proc等目录的结构和功能。其中,/etc目录下包含了许多关键配置文件,如网卡配置、DNS解析、主机名设置等。文章还详细解释了各目录和文件的作用,帮助读者更好地理解和管理Linux系统。
59 2
|
1月前
|
缓存 监控 Linux
|
1月前
|
Linux 网络安全 数据安全/隐私保护
Linux 超级强大的十六进制 dump 工具:XXD 命令,我教你应该如何使用!
在 Linux 系统中,xxd 命令是一个强大的十六进制 dump 工具,可以将文件或数据以十六进制和 ASCII 字符形式显示,帮助用户深入了解和分析数据。本文详细介绍了 xxd 命令的基本用法、高级功能及实际应用案例,包括查看文件内容、指定输出格式、写入文件、数据比较、数据提取、数据转换和数据加密解密等。通过掌握这些技巧,用户可以更高效地处理各种数据问题。
96 8
|
1月前
|
监控 Linux
如何检查 Linux 内存使用量是否耗尽?这 5 个命令堪称绝了!
本文介绍了在Linux系统中检查内存使用情况的5个常用命令:`free`、`top`、`vmstat`、`pidstat` 和 `/proc/meminfo` 文件,帮助用户准确监控内存状态,确保系统稳定运行。
281 6