linux开发之ls -l命令实现
效果
大致思路
首先,程序需要通过参数接受一个文件名。接着通过stat函数获取文件的信息,通过处理,进行合适的输出。
转换时间戳可以用localtime函数来进行。
判断文件类型时候要按位与S_IFMT
。判断权限时候,也要按位与对应的宏。
具体流程
- 判断程序用法是否正确
- 通过stas函数获取文件信息
- 将信息依次存到最终结果中
代码
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <pwd.h>
#include <grp.h>
#include <time.h>
int main(int argc, char *argv[]) {
if(argc < 2) {
printf("usage: %s filename\n", argv[0]);
return -1;
}
// 获取文件信息
struct stat st;
int ret = stat(argv[1], &st);
if(ret == -1) {
perror(argv[1]);
return -1;
}
// 记录文件类型以及权限
char prime[11] = {0};
// 文件类型
switch(st.st_mode & S_IFMT) {
case S_IFSOCK:
prime[0] = 's';
break;
case S_IFLNK:
prime[0] = 'l';
break;
case S_IFREG:
prime[0] = '-';
break;
case S_IFBLK:
prime[0] = 'b';
break;
case S_IFDIR:
prime[0] = 'd';
break;
case S_IFCHR:
prime[0] = 'c';
break;
case S_IFIFO:
prime[0] = 'p';
break;
case S_IFMT:
break;
default:
prime[0] = '?';
}
// 所有者权限
prime[1] = st.st_mode & S_IRUSR ? 'r' : '-';
prime[2] = st.st_mode & S_IWUSR ? 'w' : '-';
prime[3] = st.st_mode & S_IXUSR ? 'x' : '-';
// 所在组权限
prime[4] = st.st_mode & S_IRGRP ? 'r' : '-';
prime[5] = st.st_mode & S_IWGRP ? 'w' : '-';
prime[6] = st.st_mode & S_IXGRP ? 'x' : '-';
// 其他人权限
prime[7] = st.st_mode & S_IROTH ? 'r' : '-';
prime[8] = st.st_mode & S_IWOTH ? 'w' : '-';
prime[9] = st.st_mode & S_IXOTH ? 'x' : '-';
// 硬链接数量
unsigned long int linknum = st.st_nlink;
// 所有者
char *file_user = getpwuid(st.st_uid)->pw_name;
// 所在组
char *file_group = getgrgid(st.st_gid)->gr_name;
// 文件大小
long int file_size = st.st_size;
// 获取时间
struct tm *time = localtime(&st.st_mtim.tv_sec);
char time1[256] = {0};
const char * months[12] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sepr", "Oct", "Nov", "Dec"};
sprintf(time1, "%s %d %d:%d", months[time->tm_mon], time->tm_mday, time->tm_hour, time->tm_min);
char buf[1024];
sprintf(buf, "%s %lu %s %s %ld %s %s", prime, linknum, file_user, file_group, file_size, time1, argv[1]);
puts(buf);
return 0;
}
不忘初心方得始终