学习笔记
fcntl函数 前面改变一个已经打开的文件的访问属性(比如阻塞状态变为非阻塞状态), 要重新打开以下。
fcntl函数可以不重新打开,就直接改变文件的访问属性。
?int fcntl(int fd, int cmd, ... /* arg */ ); 第一个参数:文件描述符 第二个参数:命令 第三个参数变参:根据命令来决定有什么后续的参数
重点学习:
F_GETFL F_ 相当于命名空间。 FL:代表file status flags, 就是文件的状态。 arg 被忽略。 所以该命令是用于获取文件状态。
F_SETFL 该命令是用于设置文件状态。
拷贝44节的文件夹并命名为45fcntl
$cp -r 44block 45fcntl
查看文件夹内容
$cd 45fcntl/
$ls
block_readtty ? ?noblock_readtty ? ? ? ? ?noblock_readtty_timeout.c
block_readtty.c ?noblock_readtty.c
makefile ? ? ? ? noblock_readtty_timeout
复习在指定文件查找内容
$grep "include" noblock_readtty.c
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include<string.h>
#include<errno.h>
?复习在指定文件夹内查找内容include(-r?可以去子文件夹内查找,当前没有子文件夹)
$grep "include" ./
grep: ./: Is a directory
$grep "include" ./*
Binary file ./block_readtty matches
./block_readtty.c:#include <unistd.h>
./block_readtty.c:#include <stdlib.h>
./block_readtty.c:#include <stdio.h>
Binary file ./noblock_readtty matches
./noblock_readtty.c:#include <unistd.h>
./noblock_readtty.c:#include <stdlib.h>
./noblock_readtty.c:#include <stdio.h>
./noblock_readtty.c:#include <fcntl.h>
./noblock_readtty.c:#include<string.h>
./noblock_readtty.c:#include<errno.h>
Binary file ./noblock_readtty_timeout matches
./noblock_readtty_timeout.c:#include <unistd.h>
./noblock_readtty_timeout.c:#include <stdlib.h>
./noblock_readtty_timeout.c:#include <stdio.h>
./noblock_readtty_timeout.c:#include <fcntl.h>
./noblock_readtty_timeout.c:#include<string.h>
./noblock_readtty_timeout.c:#include<errno.h>
?删除其他文件,只保留makefile
$find ./ -name "*block*" -exec ls -l {} \;
-rwxrwxr-x 1 ubuntu ubuntu 19968 12月 22 21:42 ./noblock_readtty
-rw-rw-r-- 1 ubuntu ubuntu 242 12月 22 21:42 ./block_readtty.c
-rwxrwxr-x 1 ubuntu ubuntu 19992 12月 22 21:42 ./noblock_readtty_timeout
-rw-rw-r-- 1 ubuntu ubuntu 887 12月 22 21:42 ./noblock_readtty_timeout.c
-rw-rw-r-- 1 ubuntu ubuntu 668 12月 22 21:42 ./noblock_readtty.c
-rwxrwxr-x 1 ubuntu ubuntu 19640 12月 22 21:42 ./block_readtty
$find ./ -name "*block*" -exec rm -rf {} \;?
$ls
makefile
看一下下面的程序:
> cat fcntl.c
#include<unistd.h>
#include<fcntl.h>
#include<errno.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MSG_TRY "try again\n"
int main(void)
{
?? ?char buf[10];
?? ?int flags,n;
?? ?flags = fcntl(STDIN_FILENO,F_GETFL);
?? ?if(-1 == flags)
?? ?{
?? ??? ?perror("fcntl error");
?? ??? ?exit(1);
?? ?}
?? ?flags|= O_NONBLOCK;
?? ?int ret = fcntl(STDIN_FILENO,F_SETFL,flags);
?? ?if(-1 == ret )
?? ?{
?? ??? ?perror("fcntl error");
?? ??? ?exit(1);
?? ?}
tryagain:
?? ?n = read(STDIN_FILENO,buf,10);
?? ?if( n<0 )
?? ?{
?? ??? ?if( EAGAIN != errno )
?? ??? ?{
?? ??? ??? ?perror("read /dev/tty");
?? ??? ??? ?exit(1);
?? ??? ?}
?? ??? ?sleep(3);
?? ??? ?write(STDOUT_FILENO,MSG_TRY,strlen(MSG_TRY));
?? ??? ?goto tryagain;
?? ?}
?? ?write(STDOUT_FILENO,buf,n);
?? ?return 0;
}
$./fcntl
try again
try again
try again
^Z
没有输入的时候,可以看出一直try again
现在要讲一下位图的概念。
位图:
可以理解成一张图表。图表以二进制位为画图依据。 每一个二进制位表示一个含义。 比如: O_CREAT O_TRUNC O_NONBLOCK
int flgs = fcntl(STDIN_FILENO,F_GETFL); flgs |= O_NONBLOCK;
fcntl(STDIN_FILENO,F_SETFL,flgs);
位图在系统编程中出现的位置很多。 都是利用二进制位。 目的:是节省内存。
|