【命令功能】
linux系统中ls -l命令可以获得某个目录下文件的具体信息,比如:
gaolu@gaolu-desktop:~/test_folder$
gaolu@gaolu-desktop:~/test_folder$ ls -l
total 20
-rw-r--r-- 1 gaolu gaolu 2578 2009-03-08 02:10 gao.lu.c
-rw-r--r-- 1 gaolu gaolu 2577 2009-03-08 02:07 gao.lu.c~
-rwxr-xr-x 1 gaolu gaolu 9675 2009-03-08 02:12 ls.o
-rwxr--r-- 1 gaolu gaolu 0 2009-03-08 01:50 test1
-rw-r--r-- 1 gaolu gaolu 0 2009-03-08 01:50 test2
-rw-r--r-- 1 gaolu gaolu 0 2009-03-08 01:50 test3
-rw-r--r-- 1 gaolu gaolu 0 2009-03-08 01:51 test4
系统版本不同,显示的内容可能略有差别,主要包括几项:文件所在的inode值,权限信息,用户主和所属的组,最后修改日期,文件名,链接数等等。
【模块划分】
文件的这些基本信息都可以通过stat函数获得,因此只要可以获得某个目录下面的所有文件信息,再依次调用stat函数得到每个文件的信息,就可以实现ls -l命令的基本功能了。
结构如下:
------获得目录下所有文件列表
|
--目录文件列表获得模块-
| |
模块划分------ ------将文件列表存入链表
| -----------遍历链表
--信息输出模块--|
|
-------对每个文件调用stat获得信息并打印
【主要函数】
(1)DIR* opendir(const char *name)
功能:打开name指定的目录,返回指针,失败返回NULL.
相关头文件:
sys/types.h
dirent.h
(2)struct dirent* readdir(DIR* dir)
功能:获得某个打开目录下的具体内容
相关头文件:
sys/types.h
dirent.h
【代码实现】
#include <stdio.h>
#include <dirent.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <string.h>
//用于保存文件或者目录的名称
typedef struct dir_link{
char d_name[256];
struct dir_link * next;
}dirlink;
//保存单个文件的具体信息,方便输出
typedef struct item_info{
unsigned long inode;
char permission[11];
int owner;
int group;
off_t size;
time_t mod_time;
char name[256];
}info;
dirlink* get_dir_detail(char* dirname)
{
DIR* dir;
struct dirent* drt;
dirlink* head_node =NULL;
dirlink* cur_node = NULL;
dirlink* next_node = NULL;
dir = opendir(dirname); //打开指定目录
if(NULL == dir)
{
perror("Can't open the directroy.");
return NULL;
}
while((drt = readdir(dir)) != NULL)
{
if((strcmp(drt->d_name,".")==0)||(strcmp(drt->d_name,"..")==0))
{
continue; //忽略.目录和..目录
}
next_node = (dirlink*)malloc(sizeof(dirlink));
if(NULL == head_node)
{
head_node = next_node; //首节点
}
else
{
cur_node->next = next_node;
}
cur_node = next_node;
strcpy(cur_node->d_name,drt->d_name);
}
cur_node->next = NULL; //最后一个节点
closedir(dir);
return head_node; //返回链表头指针
}
void print_file_info(dirlink* head_node)
{
struct stat file_stat;
dirlink* cur_node = head_node;
info file_info;
static char* perm[] = {"---","--x","-w-","-wx","r--","r-x","rw-","rwx"};
while(NULL != cur_node) //遍历链表
{
int i = 3;
int j = 0;
unsigned int mask = 0700;
if(stat(cur_node->d_name,&file_stat) == -1)
{
perror("Can't get the information of the file.\n");
cur_node = cur_node->next;
continue;
}
if(S_ISREG(file_stat.st_mode)) //是普通文件
{
file_info.permission[0]='-';
}
if(S_ISDIR(file_stat.st_mode)) //是目录
{
file_info.permission[0]='d';
}
//通过移位运算计算具体权限
while(i>0)
{
file_info.permission[1+j*3] = perm[(file_stat.st_mode & mask)>>(i-1)*3][0];
file_info.permission[2+j*3] = perm[(file_stat.st_mode & mask)>>(i-1)*3][1];
file_info.permission[3+j*3] = perm[(file_stat.st_mode & mask)>>(i-1)*3][2];
i--;
j++;
mask>>=3;
}
//获得其他信息
file_info.permission[10] = '\0';
file_info.owner = file_stat.st_uid;
file_info.group = file_stat.st_gid;
file_info.mod_time = file_stat.st_atime;
file_info.size = file_stat.st_size;
file_info.inode = file_stat.st_ino;
strcpy(file_info.name,cur_node->d_name);
//打印信息
printf("%u ",file_info.inode);
printf("%s ",file_info.permission);
printf("%d ",file_info.owner);
printf("%d ",file_info.group);
printf("%u ",file_info.size);
printf("%s ",ctime(&file_info.mod_time));
printf("%s \n",file_info.name);
cur_node = cur_node->next;
}
}
int main(int argc,char* argv[])
{
dirlink* head = get_dir_detail("."); //输入参数为当前目录
print_file_info(head);
return 0;
}
【运行结果】
gaolu@gaolu-desktop:~/test_folder$ gcc -o ls.o gao.lu.c
gaolu@gaolu-desktop:~/test_folder$
gaolu@gaolu-desktop:~/test_folder$ ./ls.o
3771 -rwxr--r-- 1000 1000 0 Sun Mar 8 01:59:13 2009
test1
3773 -rw-r--r-- 1000 1000 0 Sun Mar 8 02:06:26 2009
test3
3772 -rw-r--r-- 1000 1000 0 Sun Mar 8 02:06:26 2009
test2
3822 -rw-r--r-- 1000 1000 2578 Sun Mar 8 02:10:43 2009
gao.lu.c
3785 -rwxr-xr-x 1000 1000 9675 Sun Mar 8 02:12:58 2009
ls.o
3774 -rw-r--r-- 1000 1000 0 Sun Mar 8 02:06:26 2009
test4
3770 -rw-r--r-- 1000 1000 2577 Sun Mar 8 02:07:23 2009
gao.lu.c~
gaolu@gaolu-desktop:~/test_folder$
gaolu@gaolu-desktop:~/test_folder$
【-_-! 改了半宿的bug...】