linux高级编程——ls命令c语言实现

我用的时sentos

#include <stdio.h>

#include <sys/types.h>

#include <dirent.h>

#include <sys/stat.h>

#include <pwd.h>

#include <grp.h>

#include <unistd.h>

 

void power(int m, char s[])

{

    strcpy(s, "----------");//首先将表示权限的字符串进行初始化

    if(S_ISDIR(m))//利用宏判断此文件是否是一个目录

        {

        s[0]='d';//是则将其表示为有目录属性

        }

    if(S_ISCHR(m))//是否是字符设备

        {

        s[0]='c';

        }

    if(S_ISBLK(m))//是否是块设备

        {

        s[0]='b';

        }

    if((m&S_IRUSR))//检测mode,判断文件所有者是否有读权限

        {

        s[1]='r';

        }

    if((m&S_IWUSR))//文件所有者是否有写权限

        {

        s[2]='w';

        }

    if((m&S_IXUSR))//文件所有者是否有执行权限

        {

        s[3]='x';

        }

    if((m&S_IRGRP))//用户组是否有读权限

        {

        s[4]='r';

        }

    if((m&S_IWGRP))//用户组是否有写权限

        {

        s[5]='w';

        }

    if((m&S_IXGRP))//用户组是否有执行权限

        {

        s[6]='x';

        }

    if((m&S_IROTH))//其他用户是否有读权限

        {

        s[7]='r';

        }

    if((m&S_IWOTH))//其他用户是否有写权限

        {

        s[8]='w';

        }

    if((m&S_IXOTH))//其他用户是否有执行权限

        {

        s[9]='x';

        }

}

char* uname(uid_t uid)

{

    struct passwd* getpwuid(),* pw;//保存寻找到的用户信息

    static char str[10];//保存用户名或者uid

    if((pw=getpwuid(uid))==NULL)//通过用户名寻找密码,即寻找该用户,并利用该用户创建pw

        {

        sprintf(str,"%d",uid);//没找到则将uid格式化后存入str中并且返回该数组

        return str;//返回uid

        }

    else

        {

        return pw->pw_name;//否则返回用户名

        }

}

 

char* gname(gid_t gid)

{

    struct group* getgrgid(),* g;//保存组信息

    static char str[10];//保存组名或者gid

    if((g=getgrgid(gid))==NULL)//通过gid寻找组

        {

        sprintf(str,"%d",gid);//没找到则将gid格式化后存入numstr

        return str;//返回gid

        }

    else

        {

        return g->gr_name;//找到则返回组名

        }

}

void ifdir(char dirname[])

{

    DIR* dir;

    struct dirent* dire;//存储目录中的文件信息

    if((dir=opendir(dirname))==NULL)//如果目录为空则显示错误信息,并利用dirname创建dir结构

        {

        fprintf(stderr, "can not open %s \n", dirname);

        }

    else

        {

        while((dire=readdir(dir))!=NULL)//只要目录中还有文件

                {

            creastat(dire->d_name);//传送文件名

                }

        close(dir);//关闭目录指针

        }

}

 

void creastat(char* fname)

{

    struct stat sta;

//用传送过来的文件名初始化stat结构

    if(stat(fname,&sta)==-1)//失败

        {

        perror(fname);//显示错误信息

        }

    else//成功则开始获取并显示文件信息

        {

        show(fname, &sta);

        }

}

void show(char* fname, struct stat* sta)

{

    char* uname(), *ctime(), *gname(), *filemode();

    char powe[11];//存储用户权限的字符串

    power(sta->st_mode, powe);//判断文件权限,并存入modestr

    printf("%s", powe);//显示文件各种权限

    printf(" %4d", (int)sta->st_nlink);//连接此文件的连接数

    printf(" %-8s", uname(sta->st_uid));//显示用户名

    printf(" %-8s", gname(sta->st_gid));//显示组名

    printf(" %8ld", (long)sta->st_size);//显示文件大小

    printf(" %.12s",ctime(&sta->st_mtime));//最近修改的时间

    printf(" %s\n", fname);//文件名

}

int main(int ac,char* av[])//ac获得命令行参数个数,av保存参数地址

{

    if(ac==1)

        {

        ifdir(".");//传入当前目录

        }

    else

        {

        while(--ac)

                {

            printf("%s: \n",++*av);

            ifdir(*av);//传入当前目录

                }

        }

}

下面时运行结果


以下时代码中使用的数据结构与宏的总结

2.重要数据结构的总结:

        

        struct stat {

 

        mode_t     st_mode;       //文件对应的模式,文件,目录等

 

        ino_t      st_ino;       //inode节点号

 

        dev_t      st_dev;        //设备号码

 

        dev_t      st_rdev;       //特殊设备号码

 

        nlink_t    st_nlink;      //文件的连接数

 

        uid_t      st_uid;        //文件所有者

 

        gid_t      st_gid;        //文件所有者对应的组

 

        off_t      st_size;       //普通文件,对应的文件字节数

 

        time_t     st_atime;      //文件最后被访问的时间

 

        time_t     st_mtime;      //文件内容最后被修改的时间

 

        time_t     st_ctime;      //文件状态改变时间

 

        blksize_t st_blksize;    //文件内容对应的块大小

 

        blkcnt_t   st_blocks;     //伟建内容对应的块数量

 

      };保存文件相关信息

 

 struct dirent   

    {   

      long d_ino; /* inode number 索引节点号 */  

        off_t d_off; /* offset to this dirent 在目录文件中的偏移 */  

        unsigned short d_reclen; /* length of this d_name 文件名长 */  

        unsigned char d_type; /* the type of d_name 文件类型 */       

        char d_name [NAME_MAX+1]; /* file name (null-terminated) 文件名,最长255字符 */  

    }  该结构可以只想目录也可以只想普通文件,但在上述实现代码中是指向目录

       

  struct passwd  

{  

    char * pw_name; /* 用户名*/  

    char * pw_passwd; /* 密码 */  

    __uid_t pw_uid; /* 用户id */  

    __gid_t pw_gid; /* id */  

    char * pw_gecos; /* 描述*/  

    char * pw_dir; /* 主目录 */  

    char * pw_shell; /* 所属进程shell*/  

};  保存某一个用户的信息 struct group保存用户组信息,与这个结构体类似

 

3.重要宏总结

 

S_ISDIR(st_mode):是否是一个目录

S_ISCHR(st_mode):是否是一个字符设备.

S_ISBLK(st_mode):是否是一个块设备

 

S_IRUSR//文件所有者是否有读权限

S_IWUSR//文件所有者是否有写权限

S_IXUSR//文件所有者是否有执行权限

 

S_IRGRP//用户组是否有读权限

S_IWGRP//用户组是否有写权限

S_IXGRP//用户组是否有执行权限


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值