ls命令编写

学习编写ls命令,带参数 -l,

读取文件系统的信息要涉及到dirent.h头文件和相关函数

DIR* opendir(char *path); 打开目录,失败返回NULL

dirent* readdir(DIR* dir); 读取目录的记录,失败返回NULL

stat(direct* dir,stat *st); 读取每条记录的详细信息,失败返回-1

char* ctime(long); 将是数字串转换成字符时间函数,成功返回字符指针

char* getpwuid(int uid); 根据用户id返回用户名

char* getgrdgid(int gid); 根据组id返回组名

权限的转换方法见程序 规则见sys/stat.h和bits/stat.h头文件

该程序可以接收多各参数,效果同ls -l命令

参考unix/linux编程实践教程 编写


#include
<unistd.h>
#include
<stdio.h>
#include
<sys/types.h>
#include
<sys/stat.h>
#include
<dirent.h>
void errmsg(char *msg,char *msg2);
void do_ls(char *dir);
void do_stat_info(char *statname);
void do_file_info(char *file_name,struct stat *);
void mode_to_letters(int mode,char mode_str[]);
char *uid_to_name(uid_t); //define stat.h
char *gid_to_name(gid_t); //define stat.h

int main(int ac,char *av[])
{
        
if(ac==1)
                do_ls(
".");
        
else
                
while(--ac)
                {
                        do_ls(
*++av);
                }
}
void errmsg(char *msg,char *msg2)
{
        fprintf(stderr,
"%s\n",msg);
        perror(msg2);
        exit(
1);
}
void do_ls(char *dir)
{
        DIR 
*dir_p;
        
struct dirent * dirent_p;
        
if((dir_p=opendir(dir))==NULL)
                errmsg(
"can't open directory.",dir);
        
else
        {
                
while((dirent_p=readdir(dir_p))!=NULL)
                        do_stat_info(dirent_p
->d_name);
                closedir(dir_p);
        }
}
void do_stat_info(char *statname)
{
        
struct stat *statinfo;   //can't use pointer,else malloc
        statinfo=(struct stat *)malloc(sizeof(struct stat));
        
//stat(statname,statinfo);
        if(stat(statname,statinfo)==-1)
                perror(statname);
        
else
                do_file_info(statname,statinfo);
        free(statinfo);
}
void do_file_info(char *filename,struct stat *statinfo)
{
        
char mode_str[11];
        mode_to_letters(statinfo
->st_mode,mode_str);
        printf(
"%-10s ",mode_str);
        printf(
"%4d ",statinfo->st_nlink);
        printf(
"%-8s ",uid_to_name(statinfo->st_uid));
        printf(
"%-8s ",gid_to_name(statinfo->st_gid));
        printf(
"%8d ",statinfo->st_size);
        printf(
"%.12s ",4+ctime(&statinfo->st_mtime));//sub from 4 to 12 letters
        printf("%s\n",filename);
}
void mode_to_letters(int mode,char mode_str[])
{
        strcpy(mode_str,
"----------");
        
if(S_ISDIR(mode)) mode_str[0]='d';
        
if(S_ISCHR(mode)) mode_str[0]='c';
        
if(S_ISBLK(mode)) mode_str[0]='b';

        
if(S_IRUSR & mode) mode_str[1]='r';
        
if(S_IWUSR & mode) mode_str[2]='w';
        
if(S_IXUSR & mode) mode_str[3]='x';
        
if(S_IRGRP & mode) mode_str[4]='r';
        
if(S_IWGRP & mode) mode_str[5]='w';
        
if(S_IXGRP & mode) mode_str[6]='x';
        
if(S_IROTH & mode) mode_str[7]='r';
        
if(S_IWOTH & mode) mode_str[8]='w';
        
if(S_IXOTH & mode) mode_str[9]='x';
}
#include
<pwd.h>
char *uid_to_name(uid_t uid)
{
        
struct passwd *getpwuid(),*pwd;
        
char *name_str;
        
if((pwd=getpwuid(uid))==NULL)
        {
                sprintf(name_str,
"%d",uid); //redirct output
                return name_str;
        }
        
else
                
return pwd->pw_name;
}
#include
<grp.h>
char *gid_to_name(gid_t gid)
{
        
struct group *getgrgid(),*gr;
        
char *name_str;
        
if((gr=getgrgid(gid))==NULL)
                sprintf(name_str,
"%d",gid); //redirect output
        else
                
return gr->gr_name;
        
return name_str;
}

 

posted on 2009-04-05 14:28  ringwang  阅读(479)  评论(0编辑  收藏  举报