zoukankan      html  css  js  c++  java
  • 9、【Linux系统编程】fcntl函数

      上一篇博客我们以read终端设备为例介绍了非阻塞I/O,为什么我们不直接对STDIN_FILENO做非阻塞read,而要重新open一遍/dev/tty呢?因为STDIN_FILENO在程序启动时已经被自动打开了,而我们需要在调用open时指定O_NONBLOCK标志。这里介绍另外一种办法,可以用fcntl函数改变一个已打开的文件的属性,可以重新设置读、写、追加、非阻塞等标志(这些标志称为File Status Flag),而不必重新open文件。头文件及函数原型:

    1 #include <unistd.h>
    2 #include <fcntl.h>
    3 
    4 int fcntl(int fd, int cmd);
    5 int fcntl(int fd, int cmd, long arg);
    6 int fcntl(int fd, int cmd, struct flock *lock);

      这个函数和open一样,也是用可变参数实现的,可变参数的类型和个数取决于前面的cmd参数。下面的例子使用F_GETFL和F_SETFL这两种fcntl命令改变STDIN_FILENO的属性,加上O_NONBLOCK选项,实现前一博客 “非阻塞读终端”同样的功能。

     1 #include <unistd.h>
     2 #include <fcntl.h>
     3 #include <errno.h>
     4 #include <string.h>
     5 #include <stdlib.h>
     6 #include <iostream>
     7 using namespace std;
     8 
     9 #define MSG_TRY "try again
    "
    10 
    11 int main(void)
    12 {
    13     char buf[10];
    14     int n;
    15     int flags;
    16     flags = fcntl(STDIN_FILENO, F_GETFL);//获取标准输入的标志位
    17     flags |= O_NONBLOCK;//增加非阻塞状态标志
    18     if (fcntl(STDIN_FILENO, F_SETFL, flags) == -1)//写回标准输入标志位
    19     {
    20         cout << "fcntl" << endl;
    21         return 1;
    22     }
    23 tryagain:
    24     n = read(STDIN_FILENO, buf, 10);
    25     if (n < 0) {
    26         if (errno == EAGAIN) {
    27             sleep(1);
    28             write(STDOUT_FILENO, MSG_TRY, strlen(MSG_TRY));
    29             goto tryagain;
    30         }
    31         cout << "read stdin" << endl;
    32         return 1;
    33     }
    34     write(STDOUT_FILENO, buf, n);
    35     return 0;
    36 }
  • 相关阅读:
    管道命令'|' 和xargs find命令找到后把所有找到的删除
    UVa
    【手势交互】9. PS Move
    jquery时间格式化插件
    Android学习路线(十三)Activity生命周期——暂停和恢复(Pausing and Resuming )一个Activity
    hdu 2604 Queuing (矩阵高速幂)
    【Linux驱动】TQ2440 DM9000E网卡驱动移植(Linux-2.6.30.4)
    bzoj2648 SJY摆棋子
    Hive编程指南_学习笔记01
    通信协议中的转义符
  • 原文地址:https://www.cnblogs.com/Long-w/p/9437453.html
Copyright © 2011-2022 走看看