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;
}
}
[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;
}
}
相关文章推荐
- linux网络编程:用C语言实现的聊天程序(同步通信)
- C语言实现迷宫求解
- 两数互换(c语言编程能实现)
- C语言实现牛顿迭代法解方程
- C语言实现栈(基于链表)
- 寻找最大的K个数 (C语言实现)
- Objective-C基于C语言闭包Block的实现
- (六)linux下c语言实现静态库的开发
- AES加密的C语言实现
- CSP考试 2013年12月第5题 I’m stuck! C语言实现
- C语言模式实现C++继承和多态
- PAT1003. 我要通过!(C语言实现,多种解法)
- PAT 3-05 求链式线性表的倒数第K项(C语言实现)
- c语言简单递归/非递归实现二分查找
- 双向循环链表实现文件C语言
- 用C语言实现“智障”的棋盘游戏
- 利用C语言中的函数实现文件的Copy
- 【数据结构】c语言链表实现报数问题
- 关于C++类库KYLib: 用C语言实现平衡二叉树(AVL tree)的源码
- 基于C语言的状态机实现技术