擴展基礎 ls,支援 -l 長格式輸出:類型、權限、鏈接數、擁有者、組、大小、修改時間、文件名。
struct stat {
mode_t st_mode; // 文件類型+權限位
nlink_t st_nlink; // 硬鏈接數
uid_t st_uid; // 用戶ID
gid_t st_gid; // 組ID
off_t st_size; // 大小(字節)
time_t st_mtime; // 最後修改時間
};
S_ISDIR/REG/LNK/CHR/BLK/FIFO/SOCK 宏判斷 st_mode。S_IRUSR/WUSR/IXUSR/GRP/OTH 位掩碼提取 rwx 三組。getpwuid(uid)->pw_name、getgrgid(gid)->gr_name。ctime(&st_mtime) 返回 "Wed Dec 31 18:00:00 2024\n",截取 [4..15] 去掉星期與年份。
#include <sys/stat.h>
#include <pwd.h>
#include <grp.h>
#include <time.h>
#include <string.h>
void show_attr(const char *name) {
struct stat sb;
if (stat(name, &sb) == -1) { perror("stat"); return; }
char type = '?';
if (S_ISLNK(sb.st_mode)) type = 'l';
else if (S_ISREG(sb.st_mode)) type = '-';
else if (S_ISDIR(sb.st_mode)) type = 'd';
else if (S_ISCHR(sb.st_mode)) type = 'c';
else if (S_ISBLK(sb.st_mode)) type = 'b';
else if (S_ISFIFO(sb.st_mode)) type = 'p';
else if (S_ISSOCK(sb.st_mode)) type = 's';
char perm[10] = "---------";
if (sb.st_mode & S_IRUSR) perm[0] = 'r';
if (sb.st_mode & S_IWUSR) perm[1] = 'w';
if (sb.st_mode & S_IXUSR) perm[2] = 'x';
if (sb.st_mode & S_IRGRP) perm[3] = 'r';
if (sb.st_mode & S_IWGRP) perm[4] = 'w';
if (sb.st_mode & S_IXGRP) perm[5] = 'x';
if (sb.st_mode & S_IROTH) perm[6] = 'r';
if (sb.st_mode & S_IWOTH) perm[7] = 'w';
if (sb.st_mode & S_IXOTH) perm[8] = 'x';
struct passwd *pw = getpwuid(sb.st_uid);
struct group *gr = getgrgid(sb.st_gid);
if (!pw || !gr) { perror("getpwuid/getgrgid"); return; }
char timebuf[13];
strncpy(timebuf, ctime(&sb.st_mtime) + 4, 12);
timebuf[12] = '\0';
printf("%c%s %2lu %-8s %-8s %6ld %s %s\n",
type, perm, (unsigned long)sb.st_nlink,
pw->pw_name, gr->gr_name,
(long)sb.st_size, timebuf, name);
}
int main(int argc, char *argv[]) {
int show_long = 0;
if (argc > 1 && strcmp(argv[1], "-l") == 0) show_long = 1;
DIR *dp = opendir(".");
struct dirent *ep;
while ((ep = readdir(dp))) {
if (show_long) show_attr(ep->d_name);
else printf("%s ", ep->d_name);
}
if (!show_long) puts("");
closedir(dp);
return 0;
}
$ ./myls -l -rw-r--r-- 1 talk8 talk8 774 Dec 16 22:24 cat.c -rw-r--r-- 1 talk8 talk8 596 Dec 13 09:59 cd.c ... $ ls -l -rw-r--r-- 1 talk8 talk8 774 Dec 16 22:24 cat.c -rw-r--r-- 1 talk8 talk8 596 Dec 13 09:59 cd.c ...
輸出格式與系統 ls -l 高度一致。