歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> Linux C 實現ls庖丁解牛

Linux C 實現ls庖丁解牛

日期:2017/3/1 9:41:43   编辑:Linux編程

一:背景


Linux下的ls可以實現什麼效果呢,ls有很多的選項,最為常用的選項莫過於是-l選項,列出所有文件的詳細信息。本文也著重去實現ls -l。首先看下ls -l的效果。本文將會完整的去描述怎麼樣一步一步去實現。

[root@bogon unix]# ls -l

total 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 status

man -k file|grep infomation

man -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

Copyright © Linux教程網 All Rights Reserved