系统调用open的大概执行路径

系统调用open的执行路径

代码来自Ucore教学操作系统

//用户通过open系统调用接口,执行int 0x80指令,进入内核,查找系统调用表,调用sys_open。

level 1: sys_open

//---level 1---

static uint32_t
sys_open(uint32_t arg[]) {
    const char *path = (const char *)arg[0];
    uint32_t open_flags = (uint32_t)arg[1];



  //调用level 2.1 【VFS】
    return sysfile_open(path, open_flags); //返回打开文件的文件描述符fd
}

level 2.1: sysfile_open【VFS层】

//---level 2.1【VFS】---

int
sysfile_open(const char *__path, uint32_t open_flags) {
    int ret;
    char *path;

    if ((ret = copy_path(&path, __path)) != 0) {
  //help routine 1
        return ret; //返回错误信息
    }


 //----------------------------------------
     //调用level 2.2
    ret = file_open(path, open_flags);
 //----------------------------------------


    kfree(path); //释放path指向的内核空间

    return ret;//返回打开文件的文件描述符fd
}

help routine 1: copy_path

static int copy_path(char **to, const char *from)
{
    struct mm_struct *mm = current->mm;

    char *buffer;
    //为内核申请容纳字符串的空间
    if ((buffer = kmalloc(FS_MAX_FPATH_LEN + 1)) == NULL) {
      //kmalloc申请的空间来自物理内存的前896M,对应内核虚拟空间的直接映射区,物理/虚拟地址
      //空间均连续
        return -E_NO_MEM;
    }

    lock_mm(mm);

  //将用户空间的路径字符串拷贝到内核空间
    if (!copy_string(mm, buffer, from, FS_MAX_FPATH_LEN + 1)) {
        unlock_mm(mm);
        goto failed_cleanup;
    }

    unlock_mm(mm);

    *to = buffer;//to指向buffer

    return 0;

failed_cleanup:
    kfree(buffer);
    return -E_INVAL;
}

level 2.2: file_open

//---level 2.2---
/*
 这个函数会建立一个file并加入到进程打开文件数组中,返回一个文件描述符fd作为索引
*/
int
file_open(char *path, uint32_t open_flags) {

  //根据用户标志参数判断文件打开标志,用于在file结构体中设置读写标志
    bool readable = 0, writable = 0;
    switch (open_flags & O_ACCMODE) {
    case O_RDONLY: readable = 1; break;
    case O_WRONLY: writable = 1; break;
    case O_RDWR:
        readable = writable = 1;
        break;
    default:
        return -E_INVAL;
    }

    int ret;

    struct file *file;  
  //新建一个文件,加入到进程的打开文件数组中
    if ((ret = filemap_alloc(NO_FD, &file)) != 0) { 
        return ret;
    }


 //-------------------------------------------------------- 
    struct inode *node;
    //调用level 2.3 
    if ((ret = vfs_open(path, open_flags, &node)) != 0) { //新建一个inode
 //-------------------------------------------------------- 



        filemap_free(file);
        return ret;
    }

    file->pos = 0;
    if (open_flags & O_APPEND) {
        struct stat __stat, *stat = &__stat;


        if ((ret = vop_fstat(node, stat)) != 0) {       
            vfs_close(node);
            filemap_free(file);
            return ret;
        }
        file->pos = stat->st_size;//设置文件指针初始偏移位置
    }

    file->node = node;//指向node
    //设置读写模式
    file->readable = readable;
    file->writable = writable;

    //增加文件的引用计数
    filemap_open(file);

    return file->fd; //返回
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值