我是C语言的新手,我很难找到代码中的问题所在。
它似乎在我拥有该程序的当前文件夹中正常工作,但如果我尝试列出父目录的内容,我无法正确获取文件信息。
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>
#include <unistd.h>
#include <sys/stat.h>
#include <limits.h>
#include <string.h>
#include <pwd.h>
#include <grp.h>
#include <time.h>
char TypeFile (mode_t m)
{
switch (m&S_IFMT) {
case S_IFSOCK: return 's'; /*socket */
case S_IFLNK: return 'l'; /*symbolic link*/
case S_IFREG: return '-'; /* normal file*/
case S_IFBLK: return 'b'; /*block device*/
case S_IFDIR: return 'd'; /*directory */
case S_IFCHR: return 'c'; /*char device*/
case S_IFIFO: return 'p'; /*pipe*/
default: return '?'; /*unknown*/
}
}
char * Permissions (mode_t m)
{
static char p[12];
strcpy (p,"---------- ");
p[0]=TypeFile(m);
if (m&S_IRUSR) p[1]='r'; /*owner*/
if (m&S_IWUSR) p[2]='w';
if (m&S_IXUSR) p[3]='x';
if (m&S_IRGRP) p[4]='r'; /*group*/
if (m&S_IWGRP) p[5]='w';
if (m&S_IXGRP) p[6]='x';
if (m&S_IROTH) p[7]='r'; /*other*/
if (m&S_IWOTH) p[8]='w';
if (m&S_IXOTH) p[9]='x';
if (m&S_ISUID) p[3]='s'; /*setuid, setgid, stickybit*/
if (m&S_ISGID) p[6]='s';
if (m&S_ISVTX) p[9]='t';
return (p);
}
char * dateFormat (char *str, time_t val) {
strftime(str, 36, "%b %e %k:%M ", localtime(&val));
return str;
}
int main (int argc, char *argv[]){
/* Variables */
DIR *dirp;
struct dirent *direntp;
struct stat perm;
struct passwd *owner;
struct group *gr;
char path[PATH_MAX + 1];
/* Open dir */
if (argc == 1){ dirp = opendir("."); }
else { dirp = opendir(argv[1]); }
if (dirp == NULL){
printf("Error: Can't open dir \n");
exit(1);
}
/* Read dir content */
char dat[36];
while ((direntp = readdir(dirp)) != NULL) {
realpath(direntp->d_name,path);
lstat(path,&perm);
if (direntp->d_name[0] == '.') { continue; }
printf("%10ld\t%4s\t", direntp->d_ino, Permissions(perm.st_mode));
printf("%4u\t", perm.st_nlink);
if ((owner= getpwuid(perm.st_uid)) != NULL) {
printf("%4s\t", owner->pw_name);
}
else {
printf("%4d\t", perm.st_uid);
}
if ((group = getgrgid(perm.st_gid)) != NULL) {
printf("%4s\t", group->gr_name);
}
else {
printf("%4d\t", perm.st_gid);
}
printf("%4ld\t", perm.st_size);
printf("%4s\t%4s\n", dateFormat(dat,perm.st_mtime),direntp->d_name);
}
/* Close */
closedir(dirp);
return 0;
}
这将是当前目录中的输出:
165277 -rw-rw-r-- 1 me me 4356 Oct 17 19:48 test.c
147877 -rw-rw-r-- 1 me me 4413 Oct 17 19:48 test.c~
157723 -rw-rw-r-- 1 me me 95981 Sep 15 16:50 Doc.pdf
157722 -rwxrwxr-x 1 me me 12176 Oct 17 20:20 a.out
157720 -rw-rw-r-- 1 me me 617 Sep 22 19:47 other.c
如果我尝试列出父目录(..):
,这就是输出163899 ?--------- 0 root root 0 Jan 1 1:00 b
163900 ?--------- 0 root root 0 Jan 1 1:00 ship
297613 drwxrwxr-x 4 me me 4096 Oct 16 21:38 A.pdf
我怎么能解决这个问题?提前谢谢。
答案 0 :(得分:1)
问题在于,当您将相对文件名提供给realpath()
时,它会将其相对于当前工作目录进行规范化。请注意,direntp->d_name
仅包含文件的基本名称,如果您../
,则不包含任何opendir("..")
。有两种方法可以修复您的程序:
if (argc > 1) chdir(argv[1]);
后使用opendir()
。realpath()
,而是在将其传递给"/"
之前自行连接argv [1],direntp->d_name
和lstat()
。