您的位置:首页 > 运维架构 > Linux

C语言实现的linux下ls命令

2015-03-30 10:43 148 查看
用C语言实现linux下的ls -l命令。与文件相关的结构体、函数等等知识请看"stat结构体以及文件相关函数"

[cpp] view
plaincopy

#include <stdio.h>

#include <sys/types.h>

#include <dirent.h>

#include <sys/stat.h>

#include <string.h>

#include <unistd.h>

#include <pwd.h>

#include <grp.h>

void do_ls(char *dirname);

void dostat(char *filename);

void show_file_info(char *filename, struct stat *info_p);

void mode_to_letters(int mode, char * str);

char *uid_to_name(uid_t uid);

char *gid_to_name(gid_t gid);

int main(int argc, char **argv)

{

if (argc == 1)

{

do_ls( "." );

}

else

{

while ( --argc )

{

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

chdir(*argv); //切换到指定目录后再显示该目录的内容

do_ls( *argv );

chdir(""); //再回到当前工作目录来

}

}

return 0;

}

void do_ls( char * dirname )

{

DIR *dir_ptr;

struct dirent *direntp;

/*

struct dirent

{

ino_t d_nio;

ff_t d_off;

signed short int d_reclen;

unsigned char d_type;

har d_name[256];

}

d_ino:目录进入点的inode

d_off:目录文件开头至此目录进入点的位移

d_reclen:d_name的长度,不包含NULL字符

d_type:d_ame所指文件类型

d_name:文件名

*/

/*

opendir函数用来打开参数name指定的目录,

并返回DIR *形态的目录流

*/

if ( ( dir_ptr = opendir( dirname ) ) == NULL )

{

fprintf(stderr,"ls1: cannot open %s, not a directory. treat as a file shown below:\n", dirname);

dostat( dirname ); //如果不是目录就当作文件来显示其属性

}

else

{

/*

readdir返回参数dir目录流的下个目录进入点

*/

while ( ( direntp = readdir( dir_ptr ) ) != NULL )

{

dostat( direntp->d_name );/*逐个显示目录里文件信息*/

}

closedir(dir_ptr);

}

}

void dostat( char *filename )

{

struct stat info;

if ( stat(filename, &info) == -1 ) /*取文件信息失败*/

{

perror( filename );

}

else /*显示文件信息*/

{

show_file_info( filename, &info );

}

}

void show_file_info(char *filename, struct stat *info_p)

{

char modestr[11];

mode_to_letters(info_p->st_mode, modestr);

printf("%s" , modestr);

//st_nlink连接该文件的硬链接数,刚建立的文件值为1

printf("%4d " , (int) info_p->st_nlink);

printf("%-8s " , uid_to_name(info_p->st_uid));

printf("%-8s " , gid_to_name(info_p->st_gid));

printf("%8ld " , (long)info_p->st_size);

printf("%.12s ", 4+ctime(&info_p->st_mtime));

printf("%s\n" , filename);

}

void mode_to_letters(int mode, char * str)

{

strcpy(str, "----------"); /* default=无参数 */

if (S_ISDIR(mode))

str[0] = 'd'; /* 目录 */

if (S_ISCHR(mode))

str[0] = 'c'; /* 字符设备 */

if (S_ISBLK(mode))

str[0] = 'b'; /* 块设备 */

if (mode & S_IRUSR)

str[1] = 'r'; /* 用户权限 */

if (mode & S_IWUSR)

str[2] = 'w';

if (mode & S_IXUSR)

str[3] = 'x';

if (mode & S_IRGRP)

str[4] = 'r'; /* 组权限 */

if (mode & S_IWGRP)

str[5] = 'w';

if (mode & S_IXGRP)

str[6] = 'x';

if (mode & S_IROTH)

str[7] = 'r'; /* 其人的权限 */

if (mode & S_IWOTH)

str[8] = 'w';

if (mode & S_IXOTH)

str[9] = 'x';

}

char *uid_to_name(uid_t uid)

{

struct passwd *pw_ptr;

static char numstr[10];

//获取用户ID

if ((pw_ptr = getpwuid(uid)) == NULL)

{

sprintf(numstr,"%d", uid);

return numstr;

}

else

{

return pw_ptr->pw_name ;

}

}

char *gid_to_name( gid_t gid )

{

struct group *grp_ptr;

static char numstr[10];

//获取组ID

if ((grp_ptr = getgrgid(gid)) == NULL)

{

sprintf(numstr,"%d", gid);

return numstr;

}

else

{

return grp_ptr->gr_name;

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: