Linux和QUOT; LS -al"就像在C程序 [英] Linux "ls -al" like program in C

查看:144
本文介绍了Linux和QUOT; LS -al"就像在C程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有功课写一个C程序,它表现得像在Linux的ls -al命令。我知道,有很多在互联网上的示例程序,这是做了我需要的东西,但我有一个具体的问题,对此我无法找到一个解决方案。我也想提一提,我是新来的C语言编程。这里是我的code:

I have for homework to write a C program, which is acting like the Linux "ls -al" command. 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. 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;
     } 
} 

该方案有作为的ls -al,显示同样的事情(没有权限)。到目前为止好,如果我用的gcc -std = gnu99 -o list_dir list_dir.c编译它,并用./list_dir我得到同样的结果为LS -al执行程序,它看起来像这样

The program has to display the same things (without the permissions) as "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 :

 username    1599    Fri May  1 20:43:57 2015    list_dir.c

但是,如果我运行程序的东西,如:./list_dir /家/用户名/下载/我得到这样的:

However if I run the program with something like : "./list_dir /home/username/Downloads/" I am getting this :

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

如你所见,该程序无法获取有关用户名,该文件和今年的规模将正确的信息。另外这个信息出现得益于如果其他的情况下(PWD!= 0)语句。如果我没有别的情况下,该程序被打印出仅文件,它可以得到正确的信息。另外,如果我要是去掉这句话,也是if语句:

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 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 ( (stat(current_directory->d_name, &my_stat) ) == 0 )

我得到一个分段错误。

I am getting a segmentation fault.

所以我的问题是:
1.什么我做错了。我知道我做错了什么,因为作为家庭作业我有程序的例子运行,同时,我可以用统计,LSTAT,执行的readlink,getpwnam,getpwuid,的strftime暗示暗示。

So my questions are : 1.What am I doing wrong. 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".

2.Is有什么办法让与统计(用户名),并与用户ID唯一,或者它只能使用getpwuid?

2.Is there any way to get the username with stat() and with the User-ID only, or it's only possible with getpwuid?

推荐答案

在这里,

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

如果 STAT()失败,会发生什么? PWD 将有未初始化值或从previous迭代中设置不正确的值。

What happens if stat() fails? pwd would have uninitialized value or incorrect value set from previous iteration.

之所以统计会失败, current_directory-&GT; d_name 只包含文件名,而统计期望一个完整路径。所以,你需要prePEND的目录名文件,并把它传递给 STAT()。你只传递文件名现在。

The reason why stat would fail, current_directory->d_name contains only the file name whereas stat expects a fullpath. So you need to prepend the directory name to the file and pass it to stat(). You are only passing the filename right now.

是这样的:

   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
   }

和的情况下,处理错误 STAT()失败。

and handle the error in case stat() fails.

您也有一个其他 STAT()循环而没有做任何事情里面。

You also have one other stat() inside the loop which doesn't do anything.

这篇关于Linux和QUOT; LS -al&QUOT;就像在C程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆