2013-12-08 94 views
1

我需要用C語言實現ls程序。 而我想找到一種不使用<dirent.h>庫的方法。使用C/C++中的文件描述符實現Linux「ls -l」

我可以在Linux C中使用文件描述符獲取目錄中的文件列表嗎?

謝謝。

+2

是不是'ls'已經用C寫的? –

+0

是的,但它使用dirent庫。我想用純文件描述符來做到這一點,當然,如果可能的話。 – davitp

+1

dirent庫也是C. – ceving

回答

1

這取決於你的意思是「沒有任何圖書館」。

從最硬的意義上說,您可以使用程序集來手動讀取您的磁盤,但這會非常困難且不可移植。

接下來,您可以使用程序集來進行Linux系統調用。但是,內核只是一個大型圖書館。

你可能意思是:沒有任何庫,除了C stdlib。 我相信這是不可能的。

1

如果我理解正確,您不希望使用glibc提供的函數,並且希望直接使用內核提供的系統調用來讀取目錄的內容。這意味着直接使用文件描述符。您可以像平常一樣使用系統調用open()或openat()像往常一樣打開一個目錄。

而要讀取目錄的內容,您可以使用getdents()系統調用來讀取目錄的條目。這些函數在收件人的手冊頁中有一個示例用法。

-1

嘿希望這個命令將幫助您:

execlp("ls","ls","-l",NULL); 
4

作爲一名學生,我最近不得不在ECE巴黎工程學院我的系統編程類做完全一樣的工作。

這是我的一段代碼。我沒有測試過它,但它應該可以正常工作,並且它有很好的文檔記錄,所以你可以通過閱讀評論來理解它的每一部分。

// This is the lsd function, yet another C implement of the classic ls, using UNIX functions 

// Featuring "stat", "opendir", and "readdir" 
// Credits: Jalil Benayachi, ECE PARIS - under MIT license 
// contact [at] thejals.com 

// Also thanks to some contributors on Stackoverflow 

#include <sys/types.h> 
#include <sys/stat.h> 
#include <unistd.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <dirent.h> 
#include <time.h> 
#include <pwd.h> 
#include <grp.h> 


int main(int argc, char* argv[]) 
{ 

    //Defining the different components of the program 
     //The directory: it's the folder we're browsing (we'll use an argument (argv) in order to identify it) 
    DIR *thedirectory; 
     //The file: when a file is found in the directory readdir loop, it's going to be called this way. 
    struct dirent *thefile; 
     //The stat: It's how we'll retrieve the stats associated to the file. 
    struct stat thestat; 
     //will be used to determine the file owner & group 
    struct passwd *tf; 
    struct group *gf; 

    //Creating a placeholder for the string. 
    //We create this so later it can be properly adressed. 
    //It's reasonnable here to consider a 512 maximum lenght, as we're just going to use it to display a path to a file, 
    //but we could have used a strlen/malloc combo and declared a simple buf[] at this moment 
    char buf[512]; 

    //It's time to assign thedirectory to the argument: this way the user will be able to browse any folder simply by mentionning it 
    //when launching the lsd program. 
    thedirectory = opendir(argv[1]); 

    //If a file is found (readdir returns a NOT NULL value), the loop starts/keep going until it has listed all of them. 
    while((thefile = readdir(thedirectory)) != NULL) 
    { 
     //We sprint "thedirectory/thefile" which defines the path to our file 
     sprintf(buf, "%s/%s", argv[1], thefile->d_name); 
     //Then we use stat function in order to retrieve information about the file 
     stat(buf, &thestat); 

     //Now, we can print a few things ! 
     // Here's the right order 
     // [file type] [permissions] [number of hard links] [owner] [group] [size in bytes] [time of last modification] [filename] 

     // [file type] 
     //Let's start with the file type 
     //The stat manual is pretty complete and gives details about st_mode and S_IFMT: http://manpagesfr.free.fr/man/man2/stat.2.html 
     // 
     switch (thestat.st_mode & S_IFMT) { 
      case S_IFBLK: printf("b "); break; 
      case S_IFCHR: printf("c "); break; 
      case S_IFDIR: printf("d "); break; //It's a (sub)directory 
      case S_IFIFO: printf("p "); break; //fifo 
      case S_IFLNK: printf("l "); break; //Sym link 
      case S_IFSOCK: printf("s "); break; 
      //Filetype isn't identified 
      default:  printf("- "); break; 
       } 
     //[permissions] 
     //Same for the permissions, we have to test the different rights 
     //READ http://linux.die.net/man/2/chmod 
     printf((thestat.st_mode & S_IRUSR) ? " r" : " -"); 
     printf((thestat.st_mode & S_IWUSR) ? "w" : "-"); 
     printf((thestat.st_mode & S_IXUSR) ? "x" : "-"); 
     printf((thestat.st_mode & S_IRGRP) ? "r" : "-"); 
     printf((thestat.st_mode & S_IWGRP) ? "w" : "-"); 
     printf((thestat.st_mode & S_IXGRP) ? "x" : "-"); 
     printf((thestat.st_mode & S_IROTH) ? "r" : "-"); 
     printf((thestat.st_mode & S_IWOTH) ? "w" : "-"); 
     printf((thestat.st_mode & S_IXOTH) ? "x" : "-"); 

     // [number of hard links] 
     // Quoting: http://www.gnu.org/software/libc/manual/html_node/Attribute-Meanings.html 
     // "This count keeps track of how many directories have entries for this file. 
     // If the count is ever decremented to zero, then the file itself is discarded as soon as no process still holds it open." 
     printf("\t%d ", thestat.st_nlink); 

     //[owner] 
     // http://linux.die.net/man/3/getpwuid 
     tf = getpwuid(thestat.st_uid); 
     printf("\t%s ", tf->pw_name); 

     //[group] 
     // http://linux.die.net/man/3/getgrgid 
     gf = getgrgid(thestat.st_gid); 
     printf("\t%s ", gf->gr_name); 

     //And the easy-cheesy part 
     //[size in bytes] [time of last modification] [filename] 
     printf("%zu",thestat.st_size); 
     printf(" %s", thefile->d_name); 
     printf(" %s", ctime(&thestat.st_mtime)); 
    } 
    closedir(thedirectory); 
} 

我希望這將有助於:)至於還有其他幾個同學瀏覽計算器=)

+0

有沒有辦法像ls -al打印那樣打印文件? – Mainuddin

0
#include <unistd.h> 
#include <stdio.h> 
#include <sys/stat.h> 
#include <sys/types.h> 
#include<stdlib.h> 
#include<dirent.h> 
#include<time.h> 
#include<pwd.h> 
#include <grp.h> 
int main(int argc, char **argv) 
{ 
    struct passwd *pw; 
    struct group *gp; 
    DIR *mydir; 
    char *c; 
    int i; 
    struct dirent *myfile; 
    struct stat fileStat; 
    mydir=opendir("."); 
    stat(".",&fileStat); 
    while((myfile=readdir(mydir))!=NULL) 
    { 
    stat(myfile->d_name,&fileStat); 
    printf((S_ISDIR(fileStat.st_mode)) ? "d" : "-"); 
    printf((fileStat.st_mode & S_IRUSR) ? "r" : "-"); 
    printf((fileStat.st_mode & S_IWUSR) ? "w" : "-"); 
    printf((fileStat.st_mode & S_IXUSR) ? "x" : "-"); 
    printf((fileStat.st_mode & S_IRGRP) ? "r" : "-"); 
    printf((fileStat.st_mode & S_IWGRP) ? "w" : "-"); 
    printf((fileStat.st_mode & S_IXGRP) ? "x" : "-"); 
    printf((fileStat.st_mode & S_IROTH) ? "r" : "-"); 
    printf((fileStat.st_mode & S_IWOTH) ? "w" : "-"); 
    printf((fileStat.st_mode & S_IXOTH) ? "x" : "-"); 
    printf(" "); 
    printf("%d ",fileStat.st_nlink); 
    pw=getpwuid(fileStat.st_uid); 
    printf("%s ",pw->pw_name); 
    gp=getgrgid(fileStat.st_gid); 
    printf("%s ",gp->gr_name); 
    printf("%4d ",fileStat.st_size); 
    c=ctime(&fileStat.st_mtime); 
    for(i=4;i<=15;i++) 
     printf("%c",c[i]); 
    printf(" "); 
    printf("%s\n",myfile->d_name); 
    } 
    closedir(mydir); 
    return 0; 
}