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;
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值