linux 0.11 内核学习 -- fcntl.c

/*

 *  linux/fs/fcntl.c

 *

 *  (C) 1991  Linus Torvalds

 */

#include <string.h>

#include <errno.h>

#include <linux/sched.h>

#include <linux/kernel.h>

#include <asm/segment.h>

#include <fcntl.h>

#include <sys/stat.h>

extern int sys_close(int fd);

/* 复制文件句柄,参数fd是指与复制的文件句柄,arg是指定新文件的句柄的最小值 */

static int dupfd(unsigned int fd, unsigned int arg)

{

// 如果文件句柄值大于一个程序最多打开文件数NR_OPEN,或者该句柄的文件结构不存在,则出错,

// 返回出错码并退出

if (fd >= NR_OPEN || !current->filp[fd])

return -EBADF;

// 如果指定的新句柄值arg 大于最多打开文件数,则出错

if (arg >= NR_OPEN)

return -EINVAL;

// 在当前进程的文件结构指针数组中寻找索引号大于等于arg 但还没有使用的项

while (arg < NR_OPEN)

if (current->filp[arg])

arg++;

else

break;

// 如果找到的新句柄值arg 大于最多打开文件数,则出错

if (arg >= NR_OPEN)

return -EMFILE;

// 在运行exec()类函数时不关闭该句柄

current->close_on_exec &= ~(1<<arg);

// 令该文件结构指针等于原句柄fd 的指针,并将文件引用计数增1

(current->filp[arg] = current->filp[fd])->f_count++;

return arg;

}

/* 复制文件句柄系统调用函数 */

int sys_dup2(unsigned int oldfd, unsigned int newfd)

{

// 若句柄newfd 已经打开,则首先关闭之

sys_close(newfd);

// 复制并返回新句柄

return dupfd(oldfd,newfd);

}

/* 复制文件句柄系统调用函数。新句柄的值是当前最小的未用句柄 */

int sys_dup(unsigned int fildes)

{

return dupfd(fildes,0);

}

/* 文件控制系统调用函数 */

int sys_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg)

{

struct file * filp;

// 如果文件句柄值大于一个进程最多打开文件数NR_OPEN,或者该句柄的文件结构指针为空,则出错,

// 返回出错码并退出

if (fd >= NR_OPEN || !(filp = current->filp[fd]))

return -EBADF;

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;

}

}

参考《linux内核完全注释》和网上相关文章

posted @   qiang.xu  阅读(536)  评论(0编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
点击右上角即可分享
微信分享提示