简体   繁体   English

Linux中的“ ls -al”程序

[英]Linux “ls -al” like program in C

I have for homework to write a C program, which is acting like the Linux "ls -al" command. 我必须写一个C程序来做家庭作业,它的作用类似于Linux的“ ls -al”命令。 I know that there are a lot of example programs over the internet, which are doing the thing that I need, but I have a specific problem, to which I can't find a solution. 我知道互联网上有很多示例程序可以满足我的需求,但是我有一个特定的问题,无法找到解决方案。 I also want to mention, that I am new to C programming. 我还想提到,我是C编程的新手。 Here is my code : 这是我的代码:

#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, &lt);
        char timebuf[80];
        strftime(timebuf, sizeof(timebuf), "%c", &lt);

        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;
     } 
} 

The program has to display the same things (without the permissions) as "ls -al". 该程序必须显示与“ ls -al”相同的内容(没有权限)。 So far so good, if I compile it with "gcc -std=gnu99 -o list_dir list_dir.c" and execute the program with "./list_dir" I am getting the same result as "ls -al" and it looks like this : 到目前为止,如果我使用“ 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

However if I run the program with something like : "./list_dir /home/username/Downloads/" I am getting this : 但是,如果我使用类似“ ./list_dir / home / username / Downloads /”的程序运行该程序,则会得到以下信息:

 32727   0   Sun May  8 07:09:04 4461391     selection_sort.c

As you can see, the program can't get the right information about the Username, the size of the file and the year. 如您所见,该程序无法获得有关用户名,文件大小和年份的正确信息。 Also this information is appearing thanks to the else case of the if(pwd != 0) statement. 由于if(pwd!= 0)语句的else情况,该信息也出现了。 If I don't have the else case, the program is printing out only the files, for which it can get the correct information. 如果我没有其他情况,则该程序仅打印出文件,可以获取正确的信息。 Also if I remove this if statement and also the if statement : 另外,如果我删除此if语句以及if语句:

 if ( (stat(current_directory->d_name, &my_stat) ) == 0 )

I am getting a segmentation fault. 我遇到了细分错误。

So my questions are : 1.What am I doing wrong. 所以我的问题是:1.我在做什么错。 I know that I am doing something wrong, because as a hint for the homework I have an example run of the program and also a hint that I can use "stat, lstat, readlink, getpwnam, getpwuid, strftime". 我知道我做错了,因为作为作业的提示,我有一个示例程序运行,并且还提示我可以使用“ stat,lstat,readlink,getpwnam,getpwuid,strftime”。

2.Is there any way to get the username with stat() and with the User-ID only, or it's only possible with getpwuid? 2.是否有任何方法可以通过stat()和用户ID来获取用户名,或者只能通过getpwuid来获取用户名?

Here, 这里,

    if ( (stat(current_directory->d_name, &my_stat) ) == 0 ) {
       pwd = getpwuid(my_stat.st_uid); // Get User-ID
    }

What happens if stat() fails? 如果stat()失败怎么办? pwd would have uninitialized value or incorrect value set from previous iteration. pwd将具有未初始化的值或先前迭代设置的不正确的值。

The reason why stat would fail, current_directory->d_name contains only the file name whereas stat expects a fullpath. stat失败的原因, current_directory->d_name仅包含文件名,而stat需要完整路径。 So you need to prepend the directory name to the file and pass it to stat() . 因此,您需要在文件名前添加目录名,并将其传递给stat() You are only passing the filename right now. 您现在仅传递文件名。

Something like: 就像是:

   char buf[1024];
   errno = 0;
   snprintf(buf, sizeof buf, "%s/%s", dirname, current_directory->d_name);
   if ( (stat(buf, &my_stat) ) == 0 ) {
     ...
   }
   else {
      printf("%s: %s\n", buf, strerror(errno));
      // exit here or continue to the next entry in the directory 
      //depending how you wish to handle failure
   }

and handle the error in case stat() fails. 并在stat()失败的情况下处理错误。

You also have one other stat() inside the loop which doesn't do anything. 循环中还有一个stat() ,它什么也没做。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM