我需要用C語言實現ls
程序。 而我想找到一種不使用<dirent.h>
庫的方法。使用C/C++中的文件描述符實現Linux「ls -l」
我可以在Linux C中使用文件描述符獲取目錄中的文件列表嗎?
謝謝。
我需要用C語言實現ls
程序。 而我想找到一種不使用<dirent.h>
庫的方法。使用C/C++中的文件描述符實現Linux「ls -l」
我可以在Linux C中使用文件描述符獲取目錄中的文件列表嗎?
謝謝。
這取決於你的意思是「沒有任何圖書館」。
從最硬的意義上說,您可以使用程序集來手動讀取您的磁盤,但這會非常困難且不可移植。
接下來,您可以使用程序集來進行Linux系統調用。但是,內核只是一個大型圖書館。
你可能意思是:沒有任何庫,除了C stdlib。 我相信這是不可能的。
如果我理解正確,您不希望使用glibc提供的函數,並且希望直接使用內核提供的系統調用來讀取目錄的內容。這意味着直接使用文件描述符。您可以像平常一樣使用系統調用open()或openat()像往常一樣打開一個目錄。
而要讀取目錄的內容,您可以使用getdents()系統調用來讀取目錄的條目。這些函數在收件人的手冊頁中有一個示例用法。
嘿希望這個命令將幫助您:
execlp("ls","ls","-l",NULL);
作爲一名學生,我最近不得不在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);
}
我希望這將有助於:)至於還有其他幾個同學瀏覽計算器=)
有沒有辦法像ls -al打印那樣打印文件? – Mainuddin
#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;
}
是不是'ls'已經用C寫的? –
是的,但它使用dirent庫。我想用純文件描述符來做到這一點,當然,如果可能的話。 – davitp
dirent庫也是C. – ceving