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

目录
相关文章
|
12天前
|
Linux
linux syscall和int 80的区别
通过以上内容,希望您能更清晰地理解 `int 0x80` 和 `syscall` 的区别及其在不同系统架构中的应用。
136 99
|
4天前
|
存储 网络协议 Linux
【Linux】进程IO|系统调用|open|write|文件描述符fd|封装|理解一切皆文件
本文详细介绍了Linux中的进程IO与系统调用,包括 `open`、`write`、`read`和 `close`函数及其用法,解释了文件描述符(fd)的概念,并深入探讨了Linux中的“一切皆文件”思想。这种设计极大地简化了系统编程,使得处理不同类型的IO设备变得更加一致和简单。通过本文的学习,您应该能够更好地理解和应用Linux中的进程IO操作,提高系统编程的效率和能力。
50 34
|
2月前
|
Linux Shell 网络安全
Kali Linux系统Metasploit框架利用 HTA 文件进行渗透测试实验
本指南介绍如何利用 HTA 文件和 Metasploit 框架进行渗透测试。通过创建反向 shell、生成 HTA 文件、设置 HTTP 服务器和发送文件,最终实现对目标系统的控制。适用于教育目的,需合法授权。
89 9
Kali Linux系统Metasploit框架利用 HTA 文件进行渗透测试实验
|
2月前
|
Linux Android开发 开发者
linux m、mm、mmm函数和make的区别
通过理解和合理使用这些命令,可以更高效地进行项目构建和管理,特别是在复杂的 Android 开发环境中。
81 18
|
2月前
|
Ubuntu Linux Go
golang编译成Linux可运行文件
本文介绍了如何在 Linux 上编译和运行 Golang 程序,涵盖了本地编译和交叉编译的步骤。通过这些步骤,您可以轻松地将 Golang 程序编译成适合 Linux 平台的可执行文件,并在目标服务器上运行。掌握这些技巧,可以提高开发和部署 Golang 应用的效率。
273 14
|
2月前
|
存储 NoSQL Linux
linux积累-core文件是干啥的
核心文件是Linux系统在程序崩溃时生成的重要调试文件,通过分析核心文件,开发者可以找到程序崩溃的原因并进行调试和修复。本文详细介绍了核心文件的生成、配置、查看和分析方法
158 6
|
2月前
|
存储 NoSQL Linux
linux之core文件如何查看和调试
通过设置和生成 core 文件,可以在程序崩溃时获取详细的调试信息。结合 GDB 等调试工具,可以深入分析 core 文件,找到程序崩溃的具体原因,并进行相应的修复。掌握这些调试技巧,对于提高程序的稳定性和可靠性具有重要意义。
413 6
|
3月前
|
Linux 开发工具 Perl
在Linux中,有一个文件,如何删除包含“www“字样的字符?
在Linux中,如果你想删除一个文件中包含特定字样(如“www”)的所有字符或行,你可以使用多种文本处理工具来实现。以下是一些常见的方法:
54 5
|
7天前
|
Linux
Linux系统之whereis命令的基本使用
Linux系统之whereis命令的基本使用
50 23
Linux系统之whereis命令的基本使用