Linux-0.11 文件系统fcntl.c详解
大约 2 分钟
Linux-0.11 文件系统fcntl.c详解
模块简介
本模块实现了文件描述符复制的系统调用dup和dup2。除此以外还包含了fcntl这个可以修改已经打开的文件的状态。
函数详解
dupfd
static int dupfd(unsigned int fd, unsigned int arg)
该函数用于复制文件描述符。
入参fd代表计划复制的文件描述符。 arg代表新的文件描述符的最小值。
首先检查参数的有效性,如果fd大于进程最大可以打开的文件数,或者fd对应文件结构不存在,则返回-EBADF。如果arg大于了NR_OPEN,则返回EINVAL。
if (fd >= NR_OPEN || !current->filp[fd])
return -EBADF;
if (arg >= NR_OPEN)
return -EINVAL;
接着,从arg开始遍历,寻找合适的文件描述符用于复制。如果没有找到,则返回EMFILE。
while (arg < NR_OPEN)
if (current->filp[arg])
arg++;
else
break;
if (arg >= NR_OPEN)
return -EMFILE;
接下来复位close_on_exec中该句柄位。将fd对应的文件指针拷贝到arg对应的文件指针中。
current->close_on_exec &= ~(1<<arg);
(current->filp[arg] = current->filp[fd])->f_count++;
return arg;
sys_dup2
int sys_dup2(unsigned int oldfd, unsigned int newfd)
该函数与sys_dup函数类似,区别是其在进行文件描述符的复制时,如果newfd已经打开,其会进行关闭。
sys_close(newfd);
return dupfd(oldfd,newfd);
sys_dup
int sys_dup(unsigned int fildes)
该函数是复制文件描述符dup的系统调用。
其内部调用sys_dup函数,新的文件描述符从0开始寻找。
return dupfd(fildes,0);
sys_fcntl
int sys_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg)
该函数时文件控制系统调用的函数。其具有多个功能。
首先检查函数的入参,如果大于进程最大可以打开的文件数或者fd对应的文件结构体不存在,则返回-EBADF。
struct file * filp;
if (fd >= NR_OPEN || !(filp = current->filp[fd]))
return -EBADF;
接下来,根据cmd的不同类型,实现不同的功能。
如果cmd是F_DUPFD,则调用dupfd进行文件描述符的拷贝。
如果cmd是F_GETFD,则用于获取fd对应的执行时关闭的标志。
如果cmd是F_SETFD,则用于设置fd对应的执行时关闭的标志。
如果cmd是F_GETFL,则用于返回文件的状态标志和访问模式。
如果cmd是F_SETFL, 则用于设置文件的状态标志和访问模式。
cmd等于F_GETLK/F_SETLK/F_SETLKW,还没有实现。
switch (cmd) {
case F_DUPFD:
return dupfd(fd,arg);
case F_GETFD:
return (current->close_on_exec>>fd)&1;
case F_SETFD:
if (arg&1)
current->close_on_exec |= (1<<fd);
else
current->close_on_exec &= ~(1<<fd);
return 0;
case F_GETFL:
return filp->f_flags;
case F_SETFL:
filp->f_flags &= ~(O_APPEND | O_NONBLOCK);
filp->f_flags |= arg & (O_APPEND | O_NONBLOCK);
return 0;
case F_GETLK: case F_SETLK: case F_SETLKW:
return -1;
default:
return -1;
}
Q & A
Loading...