简体   繁体   中英

Implementing ls -R command in linux

I want to know how ls -R implemented in C language. Is it use the recursion algorithm?

Here's the relevant code-block

<includes...>
int f_recursive;        /* ls subdirectories also */
while ((ch = getopt(argc, argv, "1ABCFLRSTWabcdfghiklmnopqrstuwx")) != -1) {
    switch (ch) {
.
.
.
.
case 'R':
    f_recursive = 1;
    break;

Later, the directory listing is done recursively because of the above int flag.

See source here.

Recursing in your case might cause stackoverflow, if you do not skip the directories . and .. .

It doesn't seem like any recursion is done within ls.c though. It uses fts-functions , like fts_children to traverse the heirarchies. You could use the same.

仅出于完整性考虑,ls是GNU coreutils的一部分:www.gnu.org/software/coreutils/。

"ls" (at least the implementations that I know of) use fts_open , fts_read ... to traverse a file hierarchy. These are "non-recursive" methods which maintain a list of the visited directories internally.

Use "man fts_read" or http://linux.die.net/man/3/fts_read to get more information about these functions.

This is a simple linux ls -R implementation in C. It gives coloured output similar to ls

#include <stdio.h>
#include <dirent.h>
#include <string.h>
#define GREEN   "\x1b[32m"
#define BLUE    "\x1b[34m"
#define WHITE   "\x1b[37m"

void Usage() {
    fprintf(stderr, "\nUsage: exec [OPTION]... [DIR]...\n");
    fprintf(stderr, "List DIR's (directory) contents\n");
    fprintf(stderr, "\nOptions\n-R\tlist subdirectories recursively\n");
    return;
}

void RecDir(char *path, int flag) {
    DIR *dp = opendir(path);
    if(!dp) {
        perror(path);
        return;
    }
    struct dirent *ep;
    char newdir[512];
    printf(BLUE "\n%s :\n" WHITE, path);
    while((ep = readdir(dp)))
        if(strncmp(ep->d_name, ".", 1))
            printf(GREEN "\t%s\n" WHITE, ep->d_name);
    closedir(dp);
    dp = opendir(path);
    while((ep = readdir(dp))) if(strncmp(ep->d_name, ".", 1)) {
        if(flag && ep->d_type == 4) {
            sprintf(newdir, "%s/%s", path, ep->d_name);
            RecDir(newdir, 1);
        }
    }
    closedir(dp);
}

int main(int argc, char **argv)
{
    switch(argc) {
    case 2:
        if(strcmp(argv[1], "-R") == 0) Usage();
        else RecDir(argv[1], 0);
        break;
    case 3:
        if(strcmp(argv[1], "-R") == 0) RecDir(argv[2], 1);
        else Usage();
        break;
    default: Usage();
    }
    return 0;
}

I think this would help you.

 void listDir(char *dirName)
 {
     DIR* dir;
     struct dirent *dirEntry;
     struct stat inode;
     char name[1000];
     dir = opendir(dirName);
     if (dir == 0) {
        perror ("Eroare deschidere fisier");
        exit(1);
     }
     while ((dirEntry=readdir(dir)) != 0) {
        sprintf(name,"%s/%s",dirName,dirEntry->d_name); 
        lstat (name, &inode);

        // test the type of file
        if (S_ISDIR(inode.st_mode))
           printf("dir ");
        else if (S_ISREG(inode.st_mode))
           printf ("fis ");
        else
          if (S_ISLNK(inode.st_mode))
            printf ("lnk ");
        else;
          printf(" %s\n", dirEntry->d_name);
  }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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