系统调用跟踪——ls功能实现(二)

在上篇文章中我们跟踪 ls命令看到了其所使用的这么几个系统调用: stat、openat、fstat、getdents、close、write等,这里再简单介绍下这几个系统调用的功能:
stat:为获取文件状态系统调用
openat:将打开目录/data获取它的文件描述符,返回值3即为文件描述符;
fstat:获取文件描述符为3的文件状态
getdents64:获取文件描述符为3的目录项
close:关闭文件描述符3
write:在获取到文件目录信息后将参数2中的信息标准输出到控制台

系统调用

在golang中已经给我们封装好了系统调用的相关函数,只要调用相关函数传入所对应的参数即可,go中的系统调用相关函数都放在syscall包下,如在调用sys_getcwd,获取当前工作目录的绝对路径:

//接收目录字节数组
dir:=make([]byte,100)
//调用sys_getcwd系统调用
n,e:= syscall.Getcwd(dir)
fmt.Println(string(dir))

实现ls

在Linux中将所有的设备都当做文件来处理,用文件描述符来标识每个文件对象;标准输入、标准输出、标准错误的文件描述符分别为:0、1、2;
ls指令的具体实现流程为:获取目录状态、获取目录项、获取文件状态、获取用户信息;
在调用getdents64系统调用获取目录项时需要传入该目录的文件描述符,所以需提前获取该目录的文件描述符;

具体的实现流程为:

系统调用跟踪——ls功能实现(二)

状态对象stat

st_ino   与该文件关联的inode
st_dev   保存文件的设备
st_uid   文件属主的UID号
st_gid   文件属主的GID号
st_atime 文件上一次被访问的时间
st_ctime 文件的权限、属主、组或内容上一次被修改的时间
st_mtime 文件的内容上一次被修改的时间。(和st_ctime的不同之处显而易见)
st_nlink  该文件上硬连接的个数

dir目录对象

d_ino  int64  //索引节点
off_t  int64  //目录中文件偏移
reclen int16  //长度
d_type int8   //文件类型
d_name []byte //文件名

用户信息: 所属用户、所属组、
权限信息: 目录、文件、符号链接、读写执行

实现伪代码:

//获取目录文件描述符  只读|非阻塞|打开目录|执行系统调用时关闭文件描述符(自动关闭)
fd,e := syscall.Openat(-0x64,path,syscall.O_RDONLY|syscall.O_NONBLOCK|sysc all.O_DIRECTORY|syscall.O_CLOEXEC, 0666)
//获取目录状态
e := syscall.Lstat(path, dirStat)
var b = make([]byte, dirStat.Size)
//获得目录项
n, e := syscall.Getdents(fd, b)
buf := bytes.NewBuffer(b)
//目录信息
dir := &dirent{}
var c = 0
//遍历获取目录信息
for ; c < n; {
  _ = binary.Read(buf, binary.LittleEndian, &dir.d_ino)
  binary.Read(buf, binary.LittleEndian, &dir.off_t)
  binary.Read(buf, binary.LittleEndian, &dir.reclen)
  binary.Read(buf, binary.LittleEndian, &dir.d_type)
  //&#x540D;&#x79F0;&#x957F;&#x5EA6;
  nLen := dir.reclen - 19
  name := buf.Next(int(nLen))
  dir.d_name = name[:len(name)-1]
  //&#x83B7;&#x53D6;&#x76EE;&#x5F55;&#x4E2D;&#x6587;&#x4EF6;&#x72B6;&#x6001;&#x4FE1;&#x606F;
  e := syscall.Stat(filePath, stat)
  if e != nil {
     fmt.Println(e.Error())
  }else {
    mode := stat.Mode
    m := parserAuth(mode)
    //&#x4F7F;&#x7528;uid&#x83B7;&#x53D6;&#x7528;&#x6237;&#x540D;
    u, e := user.LookupId(strconv.Itoa(int(stat.Uid)))
    if e == nil {
      //&#x4F7F;&#x7528;gid&#x83B7;&#x53D6;&#x7EC4;&#x540D;
      g, _ := user.LookupGroupId(u.Gid) //mtim &#x6700;&#x540E;&#x4E00;&#x6B21;&#x4FEE;&#x6539;&#x6587;&#x4EF6;&#x65F6;&#x95F4;,atim &#x6700;  &#x540E;&#x4E00;&#x6B21;&#x8BBF;&#x95EE;&#x6587;&#x4EF6;&#x65F6;&#x95F4; ctim&#x6700;&#x540E;&#x4E00;&#x6B21;&#x6539;&#x53D8;&#x6587;&#x4EF6;&#x72B6;&#x6001;&#x65F6;&#x95F4;
      opt:=&option{m,u.Username,g.Name,int(stat.Size),time.Unix(stat.Mtim.Unix()).Format(TIME_LAYOUT), string(dir.d_name)}
      list = append(list, opt)
     }
   }
   c = c + int(dir.reclen)
 }

程序执行:

系统调用跟踪——ls功能实现(二)
文章首发地址:https://mp.weixin.qq.com/s/Xn_xUHei10sgWkqEhMZo5g

Original: https://www.cnblogs.com/softlin/p/15315376.html
Author: AiFly
Title: 系统调用跟踪——ls功能实现(二)

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/622641/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 【MySQL】order by引起的慢查询问题总结

    最近遇到了一个SQL没有走索引导致出现慢查询的问题,SQL本身很简单,两张表联合查询然后进行排序和分页,由于涉及到一些业务,这里以用户表和订单表为例,用户表数据在35W左右,订单表…

    Java 2023年6月8日
    074
  • JAVA入门基础_从零开始的培训_JDBC和数据库连接池_基于MYSQL

    JDBC是什么? JDBC实际上就是为了能够访问不同的数据库,而提供的一套接口规范。 各个数据库厂商实现这套接口规范再提供相对应的jar包让JAVA程序能够操作对应的数据库。 学习…

    Java 2023年6月9日
    067
  • Collections.singletonList方法

    这个方法主要用于只有一个元素的优化, 减少内存分配,无需分配额外的内存,可以从SingletonList内部类看得出来,由于只有一个element,因此可以做到内存分配最小化,相比…

    Java 2023年6月13日
    072
  • Oracle总结二

    Where子句的作用:用where子句来指定查询条件 1.1 用法示例 select * from emp where deptno=10; select * from emp w…

    Java 2023年6月8日
    054
  • Intellij IDEA 显示 access.log 日志

    先配置 SpringBoot 记录 access.log 日志,先让accesslog 显示出来 Original: https://www.cnblogs.com/vipsoft…

    Java 2023年6月13日
    065
  • 在QT中添加zeromq DLL库

    1)下载地址:http://zeromq.org/distro:microsoft-windows 2)按照说明。获取相应的版本,并安装。 3 ) 安装目录中,include文件集…

    Java 2023年5月30日
    0105
  • 哈工大《形式语言与自动机》做题心得

    1、第二章——有穷自动机 1、NFA –> DFA 对于使用子集构造法去做NFA转DFA的题时,一开始我十分迷惑,认为对于状态 {A, B},输入0之后应该跳转到…

    Java 2023年6月9日
    063
  • xmind指定32位jdk解决在64位系统上不能启动的问题

    在xmind.ini文件的第一行添加下面的内容: -vmF:\kfgj\Java32.1.6\jdk1.6.0_16\bin\javaw.exe (根据实际情况指定32位jdk的j…

    Java 2023年5月30日
    059
  • RabbitMQ——整合SpringAMQP

    一。什么是Spring-AMQP? 1.Spring框架的AMQP消息解决方案,提供模板化的发送和接收消息的抽象层,提供基于消息驱动的POJO(Plain Ordinary Jav…

    Java 2023年5月30日
    075
  • Java微服务分布式架构

    摘自《Java微服务分布式架构企业实战》 1.传统单体应用架构存在的问题一个完整的单体应用程序通常主要由三部分组成:客户端用户界面、模块和数据库,如图1.1所示。传统单体应用的开发…

    Java 2023年5月29日
    072
  • [置顶][水贴]给所有制作同人/独立游戏的同学一些建议

    趁最近搞游戏引擎系列之时给所有制作同人/独立游戏的同学一些建议 当然我想来这个BLog 80%-90% 的人都不是制作同人/独立游戏的同学。 所以说水贴一个。。。 时间: 我记得当…

    Java 2023年5月29日
    065
  • Mysql基础篇-查询、函数、多表、事务

    基础篇 1.1 mysql用户和权限管理 查询用户 USER mysql; SELECT * FROM user; 创建用户 CREATE USER ‘&#x7528;&a…

    Java 2023年6月8日
    075
  • Project Lombok (即 Lombok)学习记录

    参考文档 什么是 Project Lombok ? 下载 Project Lombok 支持的安装方式 安装 Project Lombok lombok.jar 安装 eclips…

    Java 2023年6月9日
    069
  • JVM面试题(已归类)

    一年一度的面试高峰期又来了,技术学习群的很多朋友问我有没有关于JVM基础面试题,网上各种面试题没有分类很混乱,无法系统性参考学习。 于是,我就把之前整理的以及我面试过的真题和答案都…

    Java 2023年6月6日
    089
  • JDK成长记14:(深度好文)你能从3个层面分析volatile底层原理么?(下)

    上一节我们基本了解Volatile的作用,从JMM层面简单分析了下volatile可见性的实现要求。发现JMM设定了一些操作要求,在这些要求下,可以保证线程间的可见性。可是具体实现…

    Java 2023年6月5日
    071
  • spring cloud(二)简单快速的实现负载均衡的功能

    上篇参考:Spring Cloud快速使用教程(一) 在快速搭建Spring Cloud我们如果要简单快速的使用负载均衡可以如下实现 以下是实现示例: 使用Spring Cloud…

    Java 2023年5月30日
    074
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球