学习笔记
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);
位图在系统编程中出现的位置很多。
都是利用二进制位。
目的:是节省内存。