【发布时间】:2015-07-11 16:27:18
【问题描述】:
我有作业要编写一个 C 程序,它的作用类似于 Linux 的“ls -al”命令。我知道互联网上有很多示例程序,它们正在做我需要的事情,但我有一个特定的问题,我找不到解决方案。我还想提一下,我是 C 编程的新手。这是我的代码:
#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <time.h>
#include <pwd.h>
int list_dir(const char *dirname) {
struct dirent* current_directory;
struct stat my_stat;
struct tm lt;
struct passwd *pwd; // For User-ID
DIR* directory = opendir(dirname);
if(directory == NULL) {
printf("list_dir : %s : %s \n", dirname, strerror(errno));
return 0;
}
printf("Directory : %s\n", dirname);
printf("\n");
while( (current_directory = readdir(directory) ) ) {
stat(current_directory->d_name, &my_stat);
if ( (stat(current_directory->d_name, &my_stat) ) == 0 ) {
pwd = getpwuid(my_stat.st_uid); // Get User-ID
}
// Last Modified
time_t t = my_stat.st_mtime;
localtime_r(&t, <);
char timebuf[80];
strftime(timebuf, sizeof(timebuf), "%c", <);
if (pwd != 0) {
printf("%s \t %ld \t %s \t %s", pwd->pw_name, (long)my_stat.st_size, timebuf, current_directory->d_name);
printf("\n");
} else {
printf("%d \t %ld \t %s \t %s", my_stat.st_uid, (long)my_stat.st_size, timebuf, current_directory->d_name);
printf("\n");
}
}
closedir(directory);
return 0;
}
int main(int argc, char* argv[]) {
if ( argc == 1 ) {
return list_dir ( "." );
} else {
int ret = 0;
for (int i = 1; i < argc; i += 1 ) {
if ( list_dir ( argv[i] ) != 0 ) {
ret = 1;
}
}
return ret;
}
}
程序必须显示与“ls -al”相同的内容(没有权限)。到目前为止一切顺利,如果我用“gcc -std=gnu99 -o list_dir list_dir.c”编译它并用“./list_dir”执行程序,我得到与“ls -al”相同的结果,它看起来像这样:
username 1599 Fri May 1 20:43:57 2015 list_dir.c
但是,如果我使用以下内容运行程序:“./list_dir /home/username/Downloads/”,我会得到这个:
32727 0 Sun May 8 07:09:04 4461391 selection_sort.c
如您所见,程序无法获取有关用户名、文件大小和年份的正确信息。由于 if(pwd != 0) 语句的 else 情况,此信息也出现了。如果我没有 else 情况,程序只会打印出可以获取正确信息的文件。另外,如果我删除了这个 if 语句和 if 语句:
if ( (stat(current_directory->d_name, &my_stat) ) == 0 )
我遇到了分段错误。
所以我的问题是: 1.我做错了什么。我知道我做错了什么,因为作为家庭作业的提示,我有一个程序运行示例,还提示我可以使用“stat、lstat、readlink、getpwnam、getpwuid、strftime”。
2.有什么方法可以通过 stat() 和 User-ID 获取用户名,还是只能通过 getpwuid 获取?
【问题讨论】:
-
用
gdb单步执行怎么样? -
gdb是个好主意,但最初可能表明存在问题实际原因下游的访问冲突。strace可能会更有效,因为它会在 stat() 调用中显示 ENOENT。 -
需要检查每个目录项,判断是子目录还是目录列表的末尾还是普通文件还是特殊文件还是链接等
-
stat() 失败时代码没有处理条件
-
为什么这个语句:'#include
' 列出了两次?