Linux系统调用--fcntl函数详解

2023-11-15

分类:  ARM-Linux应用程序


 
今天在看《Linux设备驱动程序(第3版)》碰到了fcntl系统调用,以前没接触过。在网上查到了这份资料,转载自  企鹅乐园_雅虎群组
【fcntl系统调用】   
    
功能描述:根据文件描述词来操作文件的特性。 
  
用法:   
int fcntl(int fd, int cmd); 
int fcntl(int fd, int cmd, long arg); 
int fcntl(int fd, int cmd, struct flock *lock); 
  
  
参数:   
fd:文件描述词。 
cmd:操作命令。 
arg:供命令使用的参数。 
lock:同上。 
  
有以下操作命令可供使用 

一.  F_DUPFD :复制文件描述词 。 

二.  FD_CLOEXEC :设置close-on-exec标志。如果FD_CLOEXEC位是0,执行execve的过程中,文件保持打开。反之则关闭。 

三.   F_GETFD :读取文件描述词标志。 

四.   F_SETFD :设置文件描述词标志。 

五.  F_GETFL :读取文件状态标志。 

六.   F_SETFL :设置文件状态标志。
其中O_RDONLY, O_WRONLY, O_RDWR, O_CREAT,  O_EXCL, O_NOCTTY 和 O_TRUNC不受影响,
可以更改的标志有 O_APPEND,O_ASYNC, O_DIRECT, O_NOATIME 和 O_NONBLOCK。 

七.  F_GETLK, F_SETLK 和 F_SETLKW :获取,释放或测试记录锁,使用到的参数是以下结构体指针:
F_SETLK:在指定的字节范围获取锁(F_RDLCK, F_WRLCK)或者释放锁(F_UNLCK)。如果与另一个进程的锁操作发生冲突,返回 -1并将errno设置为EACCES或EAGAIN。 
         
F_SETLKW:行为如同F_SETLK,除了不能获取锁时会睡眠等待外。如果在等待的过程中接收到信号,会立即返回并将errno置为EINTR。 

F_GETLK:获取文件锁信息。 

F_UNLCK:释放文件锁。 
    
为了设置读锁,文件必须以读的方式打开。为了设置写锁,文件必须以写的方式打开。为了设置读写锁,文件必须以读写的方式打开。 

八. 信号管理 
F_GETOWN, F_SETOWN, F_GETSIG 和 F_SETSIG 被用于IO可获取的信号。 

F_GETOWN:获取当前在文件描述词 fd上接收到SIGIO 或 SIGURG事件信号的进程或进程组标识 。 

F_SETOWN:设置将要在文件描述词fd上接收SIGIO 或 SIGURG事件信号的进程或进程组标识 。 

F_GETSIG:获取标识输入输出可进行的信号。 

F_SETSIG:设置标识输入输出可进行的信号。 

使用以上命令,大部分时间程序无须使用select()或poll()即可实现完整的异步I/O。 

九. 租约( Leases) 
F_SETLEASE 和 F_GETLEASE 被用于当前进程在文件上的租约。文件租约提供当一个进程试图打开或折断文件内容时,拥有文件租约的进程将会被通告的机制。 

F_SETLEASE:根据以下符号值设置或者删除文件租约 

1.F_RDLCK设置读租约,当文件由另一个进程以写的方式打开或折断内容时,拥有租约的当前进程会被通告。 
2.F_WRLCK设置写租约,当文件由另一个进程以读或以写的方式打开或折断内容时,拥有租约的当前进程会被通告。 
3.F_UNLCK删除文件租约。 

F_GETLEASE:获取租约类型。 

十.文件或目录改变通告 
(linux 2.4以上)当fd索引的目录或目录中所包含的某一文件发生变化时,将会向进程发出通告。arg参数指定的通告事件有以下,两个或多个值可以通过或运算组合。 
1.DN_ACCESS 文件被访问 (read, pread, readv) 
2.DN_MODIFY 文件被修改(write, pwrite,writev, truncate, ftruncate) 
3.DN_CREATE 文件被建立(open, creat, mknod, mkdir, link, symlink, rename) 
4.DN_DELETE 文件被删除(unlink, rmdir) 
5.DN_RENAME 文件被重命名(rename) 
6.DN_ATTRIB 文件属性被改变(chown, chmod, utime[s]) 

返回说明:   
成功执行时,对于不同的操作,有不同的返回值 
F_DUPFD: 新文件描述词 
F_GETFD:  标志值 
F_GETFL:  标志值 
F_GETOWN: 文件描述词属主 
F_GETSIG: 读写变得可行时将要发送的通告信号,或者0对于传统的SIGIO行为 

对于其它命令返回0。 

失败返回-1,errno被设为以下的某个值   
EACCES/EAGAIN: 操作不被允许,尚未可行 
EBADF: 文件描述词无效 
EDEADLK: 探测到可能会发生死锁 
EFAULT: 锁操作发生在可访问的地址空间外 
EINTR: 操作被信号中断 
EINVAL: 参数无效 
EMFILE: 进程已超出文件的最大可使用范围 
ENOLCK: 锁已被用尽 
EPERM:权能不允许

struct flock {
             short l_type; /* 锁类型: F_RDLCK, F_WRLCK, F_UNLCK */
             short l_whence; /* l_start字段参照点: SEEK_SET(文件头), SEEK_CUR(文件当前位置), SEEK_END(文件尾) */
             off_t l_start; /* 相对于l_whence字段的偏移量 */
             off_t l_len; /* 需要锁定的长度 */
             pid_t l_pid; /* 当前获得文件锁的进程标识(F_GETLK) */
};


linux文件设备与I/O:fcntl函数
2009年05月07日 星期四 14:24
可以用fcntl 函数改变一个已打开的文件的属性,可以重新设置读、写、追加、非阻塞等标志(这些标志称为File StatusFlag),而不必重新open 文件。
#include <unistd.h>
#include <fcntl.h>
int fcntl(int fd, int cmd);
int fcntl(int fd, int cmd, long arg);
int fcntl(int fd, int cmd, struct flock *lock);


这个函数和open 一样,也是用可变参数实现的,可变参数的类型和个数取决于前面的cmd 参数。

针对 第2个参数,int cmd fcntl函数有五种功能:
• 复制一个现存的描述符(cmd=F_DUPFD)    。
• 获得/设置文件描述符标记(cmd=F_GETFD或F_SETFD)   。
• 获得/设置文件状态标志(cmd=F_GETFL或F_SETFL) 。
• 获得/设置异步I/O有权(cmd=F_GETOWN或F_SETOWN) 。
• 获得/设置记录锁(cmd=F_GETLK,F_SETLK或F_SETLKW)。

我们将涉及与进程表项中各文件描述符相关联的文件描述符标志, 以及每个文件表项中的文件状态标志,

一~复制文件描述符
• F_DUPFD 复制文件描述符filedes,新文件描述符作为函数值返回。它是尚未打开的各
描述符中大于或等于第三个参数值(取为整型值)中各值的最小值。新描述符与 filedes 共享同
一文件表项。但是,新描述符有它自己的一套文件描述符标志,其 F D _ C L O E X E C
文件描述符标志则被清除。
• F_GETFD 对应于filedes 的文件描述符标志作为函数值返回。当前只定义了一个文件描
述符标志FD_CLOEXEC。
• F_SETFD 对于filedes 设置文件描述符标志。新标志值按第三个参数 (取为整型值)设置。
应当了解很多现存的涉及文件描述符标志的程序并不使用常数 F D _ C L O E X E C,而是将此
标志设置为0(系统默认,在exec时不关闭)或1(在exec时关闭)。

二~文件描述符号,套接口 属性相关
• F_GETFL 对应于filedes 的文件状态标志作为函数值返回。在说明 open函数时,已说明
了文件状态标志   不幸的是,三个存取方式标志 (O_RDONLY,O_WRONLY,以及O_RDWR)并不各占1位。(正
如前述,这三种标志的值各是 0、1和2,由于历史原因。这三种值互斥 — 一个文件只能有这
三种值之一。 )因此首先必须用屏蔽字  O_ACCMODE相与 取得存取方式位,然后将结果与这三种值
相比较。
• F_SETFL 将文件状态标志设置为第三个参数的值 (取为整型值)。 可以更改的几个标志是:
O_APPEND,O_NONBLOCK,O_SYNC和O_ASYNC。

fcntl的文件状态标志共有7个, O_RDONLY,O_WRONLY,O_RDWR,O_APPEND,O_NONBLOCK,O_SYNC和O_ASYNC


三~信号驱动I/O , 带外数据,设置套接口接受信号的属主
SIGIO,跟信号驱动I/O有关
SIGURG, 和接受带外数据有关
• F_GETOWN 取当前接收SIGIO和SIGURG信号的进程ID或进程组ID。12.6.2节将论述这
两种4.3+BSD异步I/O信号。
• F_SETOWN 设置接收SIGIO和SIGURG信号的进程ID或进程组ID。正的arg指定一个进
程ID,负的arg表示等于arg绝对值的一个进程组ID。



下面的例子使用 F_GETFL和F_SETFL这两种fcntl 命令改变STDIN_FILENO的属性,上O_NONBLOCK 选项,实现非阻塞读终端的功能。

用fcntl改变File Status Flag
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#define MSG_TRY "try again\n"
int main(void)
{
char buf[10];
int n;
int flags;
flags = fcntl(STDIN_FILENO, F_GETFL);
flags |= O_NONBLOCK;
if (fcntl(STDIN_FILENO, F_SETFL, flags) == -1)
{
perror("fcntl");
exit(1);
}
tryagain:
n = read(STDIN_FILENO, buf, 10);
if (n < 0) 
{
if (errno == EAGAIN)
{
sleep(1);
write(STDOUT_FILENO, MSG_TRY,strlen(MSG_TRY));
goto tryagain;
}
perror("read stdin");
exit(1);
}
write(STDOUT_FILENO, buf, n);
return 0;
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Linux系统调用--fcntl函数详解 的相关文章

  • 重新链接匿名(未链接但打开)文件

    在 Unix 中 可以创建匿名文件的句柄 例如 使用 creat 创建并打开它 然后使用 unlink 删除目录链接 留下一个带有 inode 和存储的文件 但没有可能的方法重新打开它 此类文件通常用作临时文件 通常这就是 tmpfile
  • 进程如何知道它已收到信号

    如果我错了 请纠正我 以下是我对信号的理解 据我所知 信号生成 和信号传递有2个不同 事物 为了产生信号 操作系统只是在位数组中设置一个位 在过程控制中维护 工艺块 PCB 每一位 对应于特定信号 当设置一个位时 这意味着 该位对应的信号为
  • 从 using 语句中修改值类型是否是未定义的行为?

    这确实是一个分支这个问题 https stackoverflow com questions 4642665 why does capturing a mutable struct variable inside a closure wit
  • X 按键/释放事件捕获,与焦点窗口无关

    我想记录所有传入的按键事件 无论哪个窗口处于焦点状态或指针位于何处 我编写了一个示例代码 它应该捕获当前焦点窗口的按键事件 include
  • Flex 的远程版本误解了我的规则

    我使用 flex 和 bison 编写了一个小汇编程序 可以在我的机器 ubuntu 10 10 上构建并运行正常 现在其他人正在尝试在 arch linux 上构建它 并且他们安装的 flex 产生了不同的 lex yy c 这是不匹配的
  • 在Linux中创建可执行文件

    我计划做的一件事是编写 非常简单的 Perl 脚本 并且我希望能够在不从终端显式调用 Perl 的情况下运行它们 我明白 要做到这一点 我需要授予他们执行权限 使用 chmod 执行此操作非常简单 但它似乎也是一个稍微费力的额外步骤 我想要
  • 在Linux中使用C/C++获取机器序列号和CPU ID

    在Linux系统中如何获取机器序列号和CPU ID 示例代码受到高度赞赏 Here http lxr linux no linux v2 6 39 arch x86 include asm processor h L173Linux 内核似
  • 期待、互动,然后再次期待

    有几篇关于相同内容的帖子 但我仍然无法使我的期望脚本正常工作 我的目的是自动化一切 但保留用户输入的密码 所以脚本有 3 个部分 自动登录 给予用户交互以输入密码 将控制权交还给 Expect 脚本以继续工作 所以我有一个将生成的脚本 其中
  • Linux Shellcode“你好,世界!”

    我有以下可用的 NASM 代码 global start section text start mov eax 0x4 mov ebx 0x1 mov ecx message mov edx 0xF int 0x80 mov eax 0x1
  • 如果目录不存在,有没有办法让 mv 创建要移动到的目录?

    因此 如果我在主目录中并且想将 foo c 移动到 bar baz foo c 但这些目录不存在 是否有某种方法可以自动创建这些目录 以便你只需要输入 mv foo c bar baz 一切都会顺利吗 似乎您可以将 mv 别名为一个简单的
  • _dl_runtime_resolve -- 共享对象何时加载到内存中?

    我们有一个对性能要求很高的消息处理系统 最近我们注意到第一条消息比后续消息花费的时间要长很多倍 当它通过我们的系统时 会发生大量转换和消息增强 其中大部分是通过外部库完成的 我刚刚描述了这个问题 使用 callgrind 将仅一条消息的 运
  • 为什么 RHEL 上的 bash 中 `read -t` 没有超时?

    Why read t在 RHEL5 或 RHEL6 上从管道读取时不会超时 这是我的示例 在从管道读取数据时 我的 RHEL 盒子不会超时 tail f logfile log grep something read t 3 variabl
  • 如何更改 Kubernetes 中的文件系统观察程序限制 (fs.inotify.max_user_watches)

    我在用着pm2 https github com Unitech pm2查看保存我的应用程序服务器的 NodeJS 程序源代码的目录 该程序在 Kubernetes 集群中运行 但是 我收到此错误 ENOSPC System limit f
  • 我如何知道用户在使用 ncurses (Linux) 的控制台中按下了 ESC 键?

    I have a problem in detecting whether I just got a plain ESC key just code 27 or whether it was another special key such
  • 有没有更有效的方法通过ffmpeg批量添加水印和加入视频?

    我有这个批处理文件 使用 ffmpeg 在我的视频中添加徽标 然后添加简介 但需要 10 小时到一天的时间 具体取决于我需要添加水印的数量 是否有更有效的方法来实现此目的 视频有时具有不同的分辨率 因此我无法删除到 1280 720 尺寸的
  • 如何重载“新”方法?

    我刚刚开始学习 Rust 我想知道是否有方法重载方法 首先 我创建了一个结构并使用 impl 来实现基本的 新 方法 然后我想添加带有一些参数的 新 方法 并且我尝试使用 Trait 来实现这一点 以下代码已成功编译 但是当我尝试将 new
  • 从 Windows 命令行打印 PDF

    我正在尝试打印当前目录中的所有 pdf 文件 当我在 cmd 中调用这个 bash 脚本时 singlepdf sh C Program Files x86 Adobe Reader 10 0 Reader AcroRd32 exe t G
  • 如何从 Linux 命令行打开 Sublime Text 2 文件到选项卡,而不是新窗口

    我有 ST2 设置 这样我就可以执行 sublime file txt 它将在 ST2 窗口中打开 但是我怎样才能让它在当前打开的窗口的新选项卡中打开呢 尝试 Sublime 命令行帮助 subl 帮助 Sublime Text 2 内部版
  • 在 shell 脚本中将脚本目录更改为用户的 homedir

    在我的 bash 脚本中 我需要将当前目录更改为用户的主目录 如果我想更改为用户的foo主目录 从命令行我可以执行以下操作 cd foo 效果很好 但是当我从script它告诉我 bar sh line 4 cd foo No such f
  • Python 线程与 Linux 中的多处理

    基于此question https stackoverflow com questions 807506 threads vs processes in linux我假设创建新流程应该几乎和创造新线程在Linux中 然而 很少的测试显示出截

随机推荐

  • C++中引用的用法以及将引用作为函数的形参

    在C 中引用就相当于是给变量起了一个别名 有点类似于指针 但是与指针又不同 引用的初始化 int i i 10 变量i的引用 引用必须在创建的时候就要初始化 而指针可以在任意的时候初始化 引用就相当于是给变量起了一个别名 int i r i
  • HTML基本结构

    HTML一般是在vscod中进行书写 后缀为html 其完整的基本结构如下 h1 一级标题 h1 每一个尖括号 lt gt 代表着标签或者说是元素 不同的标签代表有着不同的作用 标签一般成对出现后一个标签为前一个标签加一个 例如 但也有单个
  • 基于巴法云的esp8266实现温湿度、LED、sg90舵机和HC-RS04实现的小程序远程控制

    基于巴法云的esp8266实现温湿度 LED sg90舵机和HC RS04实现的小程序远程控制 具体代码 本项目想法已经在我脑海想了很久了 都没有时间去实现它 这次刚刚考完试就用了两天把它做了出来 希望对大家有帮助 有什么需要的可以在下面留
  • upload-labs:pass-10

    is upload false msg null if isset POST submit if file exists UPLOAD PATH deny ext array php php5 php4 php3 php2 html htm
  • 工厂三兄弟之工厂方法模式(四)

    5 重载的工厂方法 Sunny公司开发人员通过进一步分析 发现可以通过多种方式来初始化日志记录器 例如可以为各种日志记录器提供默认实现 还可以为数据库日志记录器提供数据库连接字符串 为文件日志记录器提供文件路径 也可以将参数封装在一个Obj
  • Puppeteer 安装与注意事项 《一》

    Puppeteer 安装与注意事项 1 安装node js 在使用puppeteer的时候 它一些低版本的node是不支持的 作者推荐使用8以上的版本 否则node在后面使用puppeteer的时候会 抛出 SyntaxError Unex
  • 从外部验证安全密码存储

    许多网站 包括 Adobe Yahoo LinkedIn Gawker等大型网站 不安全地存储用户密码 可以是纯文本格式的 也可以是加密的 可逆的 格式 或者是使用残破或蛮力的哈希函数 许多网站的密码存储机制仍然很差 所以呢 好吧 如果数据
  • js生成柱状图

  • 内存泄露的检测方法

    本文来自http blog csdn net lijun84 引用必须注明出处 在谈及内存泄漏时 对于没有太多经验的新人来说总是很头疼的一件事 因为如果项目早期没有将其纳入代码框架 后期部署上线之后 仅从进程 crash 的 dump 很难
  • openGauss学习笔记-36 openGauss 高级数据管理-TRUNCATE TABLE语句

    文章目录 openGauss学习笔记 36 openGauss 高级数据管理 TRUNCATE TABLE语句 36 1 语法格式 36 2 参数说明 36 3 示例 openGauss学习笔记 36 openGauss 高级数据管理 TR
  • Docker部署Emqx并配置ssl支持微信小程序

    1 端口介绍 1883 MQTT 协议端口 8084 MQTT SSL 端口 8083 MQTT WebSocket 端口 8080 HTTP API 端口 18083 Dashboard 管理控制台端口 2 拉取镜像 docker pul
  • 算法与数据结构—LeetCode刷题笔记

    算法刷题笔记 一 动态规划 53 最大子序和 300 最长上升子序列 70 爬楼梯 242 有效的字母异位词 463 岛屿的周长 文章与视频资源多平台更新 微信公众号 知乎 B站 头条 AI研习图书馆 一 动态规划 53 最大子序和 典型的
  • js执行时序 宏任务和微任务

    宏任务一般是 包括整体代码script setTimeout setInterval I O UI render 微任务主要是 Promise Object observe MutationObserver process nextTick
  • 【MySQL高性能】MyCat 2.分片策略以及原理分析

    简介 数据库分片可以把他理解成分库 将一张表拆分到多个数据库中 通常是在表数据大的情况进行拆分 根据InnerDB索引原理 主键索引类型bigint计算得出一张表达到2千万就需要进行拆分了 当然也需要提前做好拆分 数据量大查询效率会慢 阿里
  • android kernel devices睡眠唤醒调试

    主要是在kernel添加关键log 获取有用信息 可以调试suspend resume earlysuspend lateresume等方面的问题 如哪一过程时间过长 跟踪log才可以很好定位问题 解决问题 1 early suspend
  • PermissionError: [WinError 5] 拒绝访问

    使用Pycharm运行时 报错 PermissionError WinError 5 拒绝访问 但是使用终端 Terminal 运行就没有问题 尝试方案 三步解决python PermissionError WinError 5 拒绝访问的
  • vue 报错:Invalid prop: type check failed for prop “xxx“. Expected String with value “1“,Number...

    期望的是String类型 但是传的值是Number 类型 如果你传的是number类型的你需要先转化为字符串就可以了 改成
  • python 爬虫刷浏览量(单线程)---仅供学习目的,切莫有其他想法

    重要的事情说三遍 仅供学习使用 若有其他想法 请出门右转 仅供学习使用 若有其他想法 请出门右转 仅供学习使用 若有其他想法 请出门右转 准备 简单的网站浏览量无非就是访问次数 那么一直按F5就可以 做得比较好的网站会根据 ip 计算浏览量
  • (无需编译)使用官方prebuilt文件在win10下配置caffe for python

    网上给出的caffe安装教程基本上需要自己编译 我在编译的过程中遇到很多问题 弄了很久也没有配置好 然而官方给出了prebuilt的版本 网址 BVLC caffe at windows 之前看到过prebuilt版本但一直不知道怎么使用
  • Linux系统调用--fcntl函数详解

    Linux系统调用 fcntl函数详解 2007 11 06 15 09 分类 ARM Linux应用程序 今天在看 Linux设备驱动程序 第3版 碰到了fcntl系统调用 以前没接触过 在网上查到了这份资料 转载自 企鹅乐园 雅虎群组