Welcome 微信登录
编程资源 图片资源库 蚂蚁家优选 PDF转换器

首页 / 操作系统 / Linux / Linux C 实现ls庖丁解牛

一:背景
   Linux下的ls可以实现什么效果呢,ls有很多的选项,最为常用的选项莫过于是-l选项,列出所有文件的详细信息。本文也着重去实现ls -l。首先看下ls -l的效果。本文将会完整的去描述怎么样一步一步去实现。[root@bogon unix]# ls -ltotal 116-rw-r--r--. 1 root root 1063 Jul  6 20:18 aaaa-rwxr-xr-x. 1 root root 9811 Jul 18 22:17 a.out-rw-r--r--. 1 root root 1474 Jul 10 21:58 cp1.c-rw-r--r--. 1 root root  386 Jul 10 21:54 exis.c-rw-r--r--. 1 root root  601 Jul 15 22:22 fileinfo.c-rw-r--r--. 1 root root  515 Jul  6 21:39 logout_tty.c-rw-r--r--. 1 root root  755 Jul 12 15:21 ls1.c-rw-r--r--. 1 root root 2625 Jul 18 22:17 ls2.c----------. 1 root root 1063 Jul  3 21:31 more01.c-rwxrwxrwx. 1 root root 1651 Jul  5 21:48 more02.c-rw-r--r--. 1 root root  270 Jul 15 22:16 stattest.c-rw-r--r--. 1 root root  262 Jul  4 21:51 test1.c-rw-r--r--. 1 root root 1337 Jul 12 14:19 test2.c-rw-r--r--. 1 root root  140 Jul 12 14:11 test3.c-rw-r--r--. 1 root root  527 Jul  3 22:19 test.c-rw-r--r--. 1 root root  169 Jul  7 22:42 ttytest.c-rw-r--r--. 1 root root  955 Jul  7 20:54 utmplib.c-rw-r--r--. 1 root root  87 Jul  6 21:13 utmplib.h-rw-r--r--. 1 root root 2688 Jul  6 21:12 utmplib.o-rwxr-xr-x. 1 root root  980 Jul 12 14:22 who1.c-rwxr-xr-x. 1 root root 9576 Jul  6 21:13 who2-rw-r--r--. 1 root root 1791 Jul 12 13:15 who2.c-rw-r--r--. 1 root root 2720 Jul  6 21:13 who2.o-rw-r--r--. 1 root root 1424 Jul 12 12:45 who_am_i.c-rw-r--r--. 1 root root  80 Jul  7 22:43 whoami.c
这是一个使用ls -l选项列出的的文件信息,可以看出ls -l列出了所有文件的 属性,连接,属主,属组,大小,ctime以及文件名等信息。要获取文件的这些信息并进去适当的格式化,就是本文所要做的事情了。------------------------------分割线------------------------------C++ Primer Plus 第6版 中文版 清晰有书签PDF+源代码 http://www.linuxidc.com/Linux/2014-05/101227.htm读C++ Primer 之构造函数陷阱 http://www.linuxidc.com/Linux/2011-08/40176.htm读C++ Primer 之智能指针 http://www.linuxidc.com/Linux/2011-08/40177.htm读C++ Primer 之句柄类 http://www.linuxidc.com/Linux/2011-08/40175.htm将C语言梳理一下,分布在以下10个章节中:
  1. Linux-C成长之路(一):Linux下C编程概要 http://www.linuxidc.com/Linux/2014-05/101242.htm
  2. Linux-C成长之路(二):基本数据类型 http://www.linuxidc.com/Linux/2014-05/101242p2.htm
  3. Linux-C成长之路(三):基本IO函数操作 http://www.linuxidc.com/Linux/2014-05/101242p3.htm
  4. Linux-C成长之路(四):运算符 http://www.linuxidc.com/Linux/2014-05/101242p4.htm
  5. Linux-C成长之路(五):控制流 http://www.linuxidc.com/Linux/2014-05/101242p5.htm
  6. Linux-C成长之路(六):函数要义 http://www.linuxidc.com/Linux/2014-05/101242p6.htm
  7. Linux-C成长之路(七):数组与指针 http://www.linuxidc.com/Linux/2014-05/101242p7.htm
  8. Linux-C成长之路(八):存储类,动态内存 http://www.linuxidc.com/Linux/2014-05/101242p8.htm
  9. Linux-C成长之路(九):复合数据类型 http://www.linuxidc.com/Linux/2014-05/101242p9.htm
  10. Linux-C成长之路(十):其他高级议题
二:开始实现要想自己实现ls -l就得知道可以通过什么系统调用可以获取到这些文件信息。首先自然是要通过man来查找相关的系统调用。man -k file|grep statusman -k file|grep infomationman -k file |grep info不停的换上多个关键词来搜索,通过上面的搜索就可以得到stat这个系统调用来获取文件信息。紧接着就可以man 2 stat来获取系统调用的详细使用方法。      #include <sys/types.h>      #include <sys/stat.h>      #include <unistd.h>      int stat(const char *path, struct stat *buf);          struct stat {              dev_t    st_dev;    /* ID of device containing file */              ino_t    st_ino;    /* inode number */              mode_t    st_mode;    /* protection */              nlink_t  st_nlink;  /* number of hard links */              uid_t    st_uid;    /* user ID of owner */              gid_t    st_gid;    /* group ID of owner */              dev_t    st_rdev;    /* device ID (if special file) */              off_t    st_size;    /* total size, in bytes */              blksize_t st_blksize; /* blocksize for file system I/O */              blkcnt_t  st_blocks;  /* number of 512B blocks allocated */              time_t    st_atime;  /* time of last access */              time_t    st_mtime;  /* time of last modification */              time_t    st_ctime;  /* time of last status change */          };
到了这里处理起来似乎很顺畅了,只要获取相应字段进行格式处理就OK了。三:权限处理    st_mode就是文件的权限部分,对于这个部分要把其处理成ls -l列出的那种形式。st_mode本身就是一个16位的二进制,前四位是文件的类型,紧接着三位是文件的特殊权限,最后的九位就是ls -l列出来的九个权限。如何把st_mode转换成对应的权限就是权限处理这块的关键了。Linux本身提供了很多测试宏来测试文件的类型的。#define __S_IFMT        0170000 /* These bits determine file type.  *//* File types.  */#define __S_IFDIR      0040000 /* Directory.  */#define __S_IFCHR      0020000 /* Character device.  */#define __S_IFBLK      0060000 /* Block device.  */#define __S_IFREG      0100000 /* Regular file.  */#define __S_IFIFO      0010000 /* FIFO.  */#define __S_IFLNK      0120000 /* Symbolic link.  */#define __S_IFSOCK      0140000 /* Socket.  */
# define S_IFMT        __S_IFMT
# define S_IFDIR        __S_IFDIR
# define S_IFCHR        __S_IFCHR
# define S_IFBLK        __S_IFBLK
# define S_IFREG        __S_IFREG
利用上面的测试宏就可以判断文件的类型,至于文件的权限部分可以使用掩码的方式来处理。具体代码如下:void mode_to_letters(int mode,char str[]){//S_IS***测试宏        strcpy(str,"----------");        if(S_ISDIR(mode))str[0] = "d";        if(S_ISCHR(mode))str[0] = "c";        if(S_ISBLK(mode))str[0] = "b"; //与 掩码        if(mode&S_IRUSR)str[1] = "r";        if(mode&S_IWUSR)str[2] = "w";        if(mode&S_IXUSR)str[3] = "x";         if(mode&S_IRGRP)str[4] = "r";        if(mode&S_IWGRP)str[5] = "w";        if(mode&S_IXGRP)str[6] = "x";         if(mode&S_IROTH)str[7] = "r";        if(mode&S_IWOTH)str[8] = "w";        if(mode&S_IXOTH)str[9] = "x";}更多详情见请继续阅读下一页的精彩内容: http://www.linuxidc.com/Linux/2014-07/104739p2.htm