乱读天书, 不求甚解
周祎骏的个人云笔记
Toggle navigation
乱读天书, 不求甚解
主页
Linux:系统配置
Linux:用户管理
Linux:优化排错
Linux:进程调度
Linux:文件系统
Linux:网络
Linux:系统服务
Linux:安全
Linux:内核
容器:Docker
容器:containerd
容器编排:Kubernetes
IAC:Terraform
大数据:Hadoop
大数据:Zookeeper
大数据:Hbase
消息队列:rsyslog
消息队列:kafka
数据库:MySQL
数据库:MongoDB
搜索引擎:Elasticsearch
时序数据库:OpenTSDB
网站服务:Nginx
编程:Bash
编程:Perl
编程:Python
编程:C
编程:JAVA
编程:Rust
版本控制:gitlab
知识管理:docusaurus
常用小工具
关于我
标签
C 2.07 Linux函数库fcntl
2018-06-17 08:23:04
72
0
0
admin
> 创建文件,操作文件句柄 #函数 **int creat(char *name.int perms)** 创建文件,返回文件句柄 ``` #include <stdio.h> #include <fcntl.h> main() { int a = creat("file_name",0777); printf("%d\n",a); } ``` **int open(char *name,int flags, int perms)**:打开文件,返回文件句柄,失败返回-1 | flags | 含义 | |-----------|------------------------------------------------------| |O_RDONLY |只读(3选1) | |O_WRONLY |只写(3选1) | |O_RDWR |读写(3选1) | |O_APPEND |追加 | |O_CREAT |当文件不存在的时候,创建文件,权限用perms | |O_EXCL |在有O_CREAT的情况下,如果文件事先已经存在,则错误退出 | |O_NOCTTY |如果指向终端,则不把该终端作为进程的控制终端 | |O_TRUNC |清空文件 | |O_NONBLOCK |如果打开的是管道文件,设备文件,那么用非阻塞的方式 | |O_SYNC |写操作时进程被阻塞,直到写到磁盘上 | **close(int fd)** 关闭文件句柄 **unlink(char *name)** 删除文件 ``` #include <stdio.h> #include <fcntl.h> #include <unistd.h> main(int argc,char *argv[]) { int fd_read = open(argv[1],O_RDONLY,0); int fd_write = open("./log",O_WRONLY|O_APPEND|O_CREAT,00644); char c[BUFSIZ];//BUFSIZ 是stdio.h里设定好的 int n; while ((n=read(fd_read,c,BUFSIZ)) > 0) write(fd_write,c,n); close(fd_read); close(fd_write); } ``` *** **int fcntl(int fd, int cmd,d,.../* struct flock *flockptr */)** 操作文件句柄,第三个参数用于文件锁。 cmd: F_DUPFD: 复制一个现存的文件句柄,新句柄是可用的最小句柄或者第三个参数,返回句柄 F_GETFD:获得文件句柄属性,只有一个属性FD_CLOEXEC F_SETFD:设置文件句柄属性,只有一个属性FD_CLOEXEC ``` FD_CLOEXEC=0 调用exec时不关闭该句柄,默认 FD_CLOEXEC=1 关闭 ``` F_GETFL: 获得文件状态标志,就是函数open 的flag 函数 F_SETFL:设置文件状态标志,就是函数open 的flag 函数 只读,只写,读写这三个配置不是各占一位,我们要让取得的值与O_ACCMODE做一次与的位运算来取得结果,详情看后面例子 | flag | | |----------|---------------| |O_RDONLY |只读(不可改) | |O_WRONLY |只写(不可改) | |O_RDWR |读写(不可改) | |O_APPEND |追加 | |O_NONBLOCK|非阻塞 | |O_SYNC |等待写完成 | |O_ASYNC |异步IO | ``` #include <stdio.h> #include <sys/types.h> #include <fcntl.h> main() { int accmode,val; if ((val = fcntl(1,F_GETFL,0)) < 0) { printf("Failed to get fl\n"); return 1; } accmode = val & O_ACCMODE; if (accmode == O_RDONLY) printf("read only\n"); else if (accmode == O_WRONLY) printf("write only\n"); else if (accmode == O_RDWR) printf("read write\n"); else printf("Unknown access mode\n"); if (val & O_APPEND) printf("append\n"); val |= O_APPEND; if (fcntl(1,F_SETFL,val)<0) { printf("Failed to set fl\n"); } } ``` F_GETOWN: 获得异步IO所有权 F_SETOWN: 设置异步IO所有权 ``` struct flock { short l_type;/*F_RDLCK(共享读锁), F_WRLCK(独占写锁), or F_UNLCK(解锁)*/ off_t l_start;/*相对于l_whence的偏移值,字节为单位*/ short l_whence;/*从哪里开始:SEEK_SET, SEEK_CUR, or SEEK_END*/ off_t l_len;/*长度, 字节为单位; 0 意味着缩到文件结尾*/ pid_t l_pid;/*returned with F_GETLK*/ }; ``` F_GETLK: 获得锁,如果获得锁,把flock->l_type改成F_UNLCK,如果不能获得锁,将当前锁的信息写入flock F_SETLK:设置锁,如果无法获得锁,出错返回,errno设置为EACCES或EAGAIN F_SETLKW: 设置锁,阻塞 > F_GETLK 是先检测能不能获得锁再通过F_SETLKW来设置锁,两者不是原子操作,所以可能发生两个操作中间的时间锁被别人拿走而导致的阻塞,为了防止发生这种情况建议用F_SETLK来设置锁然后检查返回值来确定是否获得锁。 >如果内核返回ENOLCK说明内核中的锁已经用完了 >如果文件系统挂载时用了-o mand 参数,同时文件设置了sgid以及关闭了组-运行位(如2767),则这个文件的锁就是强制锁,默认是建议锁
上一篇:
C 2.06 函数库sys/stat.h
下一篇:
C 2.08 Linux函数库unistd
文档导航