学习编写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;
}