Reputation: 9208
I am trying to implement a "ls" as a back to basic training. I know I can use opendir()
and readdir()
to do the basic listing.
For sorting - I have no option, but to add each entry into a an array - and sort. For filtering - or globbing - I assume I can manually do this in my code. But I am looking for "not trashing the disk" - and let the OS filter this for me. Also - filtering "$234*.a*" is not trivial.
Question: How can I list all "*.txt" files in a directory in good old C? (Unix/Posix only, that is OK).
Sources for inspiration: https://github.com/dosbox-staging/dosbox-staging/blob/master/src/shell/shell_cmds.cpp#L656 https://github.com/mirror/busybox/blob/master/coreutils/ls.c#L1206
Upvotes: 0
Views: 920
Reputation: 141698
For filtering - or globbing - I assume I can manually do this in my code
Do not reinvent the wheel - glob and fnmatch and wordexp are standard.
How can I list all "*.txt"
The expansion of *.txt
globbing is done by your shell as part of filename expansion and are spitted into separate arguments before executing the ls
command. Expanding globbing expressions is not part of ls
. Supporting globbing in ls
would be a non-standard extension.
To list files in a directory, use scandir (with alphasort
). A perfect example of scandir
is in linux man pages scandir:
#define _DEFAULT_SOURCE
#include <dirent.h>
#include <stdio.h>
#include <stdlib.h>
int
main(void)
{
struct dirent **namelist;
int n;
n = scandir(".", &namelist, NULL, alphasort);
if (n == -1) {
perror("scandir");
exit(EXIT_FAILURE);
}
while (n--) {
printf("%s\n", namelist[n]->d_name);
free(namelist[n]);
}
free(namelist);
exit(EXIT_SUCCESS);
}
A ls
program would iterate for each argument, see if it's a file - if it is, list it with permissions (one call to stat
+ formatting). If an argument is a dir - it would use scandir
then stat
for each file + formatting. Note that the output format of ls is actually specified in some cases (but still leaves much freedom to implementations).
How can I list all "*.txt" files in a directory in good old C?
There's another example in man-pages glob. The code would be just simple:
glob_t globbuf = {0};
glob("*.txt", 0, NULL, &globbuf);
for (char **file = globbuf.gl_pathv; *file != NULL; ++file) {
printf("%s\n", *file);
}
globfree(&globbuf);
The POSIX links and linux-man pages project are great for studing - linux-man pages has that SEE ALSO
section below that is great for discovering functions. Also see GNU manual.
Upvotes: 1