У меня есть домашняя работа, чтобы написать программу на C, которая действует как команда Linux ls -al. Я знаю, что в Интернете есть много примеров программ, которые делают то, что мне нужно, но у меня есть определенная проблема, к которой я не могу найти решение. Я также хочу упомянуть, что я новичок в программировании на С. Вот мой код: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/главная/имя пользователя/Загрузки /» Я получаю это:
32727 0 Sun May 8 07:09:04 4461391 selection_sort.c
Как вы можете видеть, программа может Получите правильную информацию о пользователе, размере файла и году. Также эта информация появляется благодаря else-случаю инструкции if (pwd! = 0). Если у меня нет другого случая, программа печатает только файлы, для которых он может получить правильную информацию. Также, если я удаляю этот оператор if, а также оператор if:
if ((stat(current_directory->d_name, &my_stat)) == 0)
У меня возникает ошибка сегментации.
Так что мои вопросы: 1.Что я делаю неправильно. Я знаю, что я делаю что-то неправильно, потому что, как подсказка для домашней работы, у меня есть пример запуска программы, а также подсказка, что я могу использовать «stat, lstat, readlink, getpwnam, getpwuid, strftime».
2.Есть ли способ получить имя пользователя с помощью stat() и только с идентификатором пользователя, или это возможно только с помощью getpwuid?
как насчет перехода через него с помощью 'gdb'? – lispHK01
'gdb' - хорошая идея, но может первоначально указывать на нарушение прав доступа, существенно ниже по течению от фактической причины проблемы. 'strace', вероятно, будет еще более эффективным, так как он покажет ENOENT по вызову stat(). –
каждый элемент каталога должен быть проверен, чтобы определить, является ли это вспомогательной директорией или концом списка каталогов или обычного файла или специального файла или ссылки, и т. Д. – user3629249