dup 和dup2 系统调用都可以用来复制文件描述符。
#include <unistd.h>
int dup( int oldfd); 可以用来复制参数oldfd所指的文件描述符,复制成功时 ,返回最小的尚未使用的文件描述符,有错误返回-1,错误代码存入errno中。返货的新文件说明符与参数oldfd指向同一文件,共享所有的锁定,读写指针和各项权限或标志位。
int dup2(int oldfd, int newfd); 可以用newfd指定新文件的描述符的数值,
~若newfd已被程序使用,系统回将其关闭并释放该文件描述符,
~dup2调用成功 ,返回新的描述符, 出错返回-1.
shell 中的重定向功能就是,就是通过dup或dup2 函 。
文件锁:
为了防止多个进程同时操作一个文件防止数据不同步,该文件的最后状态取决于写文件的是最后一个程序,有事进程需要确保它正在单独写一个文件,所哟用到了文件记录锁。
当fcntl用于管理文件记录锁的操作时,第三个参数指向一个struct flock *lock 的结构。
struct flock {
short_1_type; //锁类型
short_1_whence; //偏移量的起始位置
off_t_1_start; //starting offset for lock
off_t_1_len; //number of bytes to lock
pid_t_1_pid; //锁的属主进程ID
多个进程在一个给定的进程上可以有一把共享的锁,但是在一个给定的进程上的写锁只能有一个进程单独使用。
若某一文件区域已经存在文件记录锁,则如果再设锁在此区域,或替换旧锁。
1_whence , 1_start , 1_len 用来确定需要进行文件记录锁操作的区域。
为了锁住整个文件,1_start置为0, 1_whence置为SEEK_SET, 1_len置为0。
cmd 取值(执行成功返回0,有错时返回-1,错误存进errno)
~F_SETLK 此时fcntl系统调用被用来设置或释放 锁,
* 当1_type 取F_RDLCK或 F_UNLCK时,在由1_whence , 1_len ,1_start指定的区域上设置锁。
* 当1_type 取 F_UNLCK 时则释放锁。
* 若锁被其他进程占用,则返回 -1 并设置errno 为EACCES 或EAGAIN。
当设置一个共享锁(读锁)时,fd 所指向文件以可读方式打开
设置互斥锁(写锁)时, fd 以可写方式打开
设置两种锁时,以可读可写方式打开
当进程结束或文件描述符fd被close 系统调用时,锁会自动释放。
~F_SETLKW 与上面相似
不同的是当希望设置锁而有锁占着时,该命令会等待相冲突的锁被释放。
~F_GETLK
此时,第三个参数lock 指向一个希望设置的锁的属性的结构,若锁能被设置,该命令只修改lock的1_type域为F_UNLCK,然后返回。 如果存在一个锁或多个锁与希望设置的锁冲突,则fcntl返回其中一个锁的flock 结构。