前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >嵌入式Linux:fcntl()和ioctl()函数

嵌入式Linux:fcntl()和ioctl()函数

作者头像
不脱发的程序猿
发布2024-05-26 10:29:20
850
发布2024-05-26 10:29:20
举报

fcntl()ioctl()是用于对文件描述符进行控制的两个系统调用,它们在不同的情况下有不同的用途和功能。

1、fcntl()函数

fcntl()函数提供了对已打开文件描述符执行各种控制操作的功能,例如复制文件描述符(与dupdup2类似)、获取/设置文件描述符标志、获取/设置文件状态标志等,是一个多功能的文件描述符管理工具。可通过"man 2 fcntl"命令查看fcntl()函数的原型。

代码语言:javascript
复制
#include <fcntl.h>

int fcntl(int fd, int cmd, ... /* arg */);

函数fcntl()的参数和返回值含义如下:

  • fd:文件描述符。
  • cmd:操作命令。用于指定对文件描述符 fd 执行的操作类型。这些命令通常以 F_XXX 开头,如 F_DUPFDF_GETFDF_SETFD 等,具体命令的作用可以通过查阅手册页面(man 2 fcntl)了解,常见的功能包括:
    • 复制文件描述符(F_DUPFDF_DUPFD_CLOEXEC);
    • 获取/设置文件描述符标志(F_GETFDF_SETFD);
    • 获取/设置文件状态标志(F_GETFLF_SETFL);
    • 获取/设置异步 IO 所有权(F_GETOWNF_SETOWN);
    • 获取/设置记录锁(F_GETLKF_SETLK)。
  • ...fcntl() 函数是一个可变参数函数,第三个参数根据不同的 cmd 需要传入相应的实参。
  • 返回值:若执行失败,则返回 -1 并设置 errno;若执行成功,则返回值与 cmd(操作命令)有关。例如,F_DUPFD(复制文件描述符)将返回一个新的文件描述符,F_GETFD(获取文件描述符标志)将返回文件描述符标志,F_GETFL(获取文件状态标志)将返回文件状态标志等。

示例用法:

代码语言:javascript
复制
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>

int main() {
    int fd = open("example.txt", O_RDONLY);
    if (fd == -1) {
        perror("open");
        return 1;
    }
    
    // 获取文件描述符标志
    int flags = fcntl(fd, F_GETFL, 0);
    if (flags == -1) {
        perror("fcntl");
        close(fd);
        return 1;
    }

    // 设置文件描述符标志,添加非阻塞标志
    if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1) {
        perror("fcntl");
        close(fd);
        return 1;
    }

    // 其他操作...

    close(fd);
    return 0;
}

2、ioctl()函数

ioctl()函数可视为文件IO操作的多功能工具箱,可处理各种杂项且不统一的任务,通常用于与特殊文件或硬件外设交互。

本篇博文只是介绍此系统调用,具体用法将在进阶篇中详细探讨,例如可以利用ioctl获取LCD相关信息等。ioctl()函数原型如下所示(可通过"man 2 ioctl"命令查看):

代码语言:javascript
复制
#include <sys/ioctl.h>

int ioctl(int fd, unsigned long request, ...);

函数ioctl()参数和返回值含义如下:

  • fd:文件描述符。
  • request:用于指定要执行的操作,具体值与操作对象有关,后续会详细介绍。
  • ...:可变参数列表,根据 request 参数确定具体参数,用于与请求相关的操作。
  • 返回值:成功时返回 0,失败时返回 -1。

示例用法:

代码语言:javascript
复制
#include <sys/ioctl.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <linux/fs.h>

int main() {
    int fd = open("/dev/sda", O_RDONLY);
    if (fd == -1) {
        perror("open");
        return 1;
    }

    // 查询设备块大小
    long block_size;
    if (ioctl(fd, BLKSSZGET, &block_size) == -1) {
        perror("ioctl");
        close(fd);
        return 1;
    }
    printf("Block size: %ld bytes\n", block_size);

    // 其他操作...

    close(fd);
    return 0;
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-04-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1、fcntl()函数
  • 2、ioctl()函数
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档