summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ls.c48
1 files changed, 42 insertions, 6 deletions
diff --git a/ls.c b/ls.c
index c507523..fe6ae76 100644
--- a/ls.c
+++ b/ls.c
@@ -4,7 +4,20 @@
#include <unistd.h>
-int ls(const char * path)
+struct options
+{
+ unsigned int skip_dots:1;
+ unsigned int skip_self_and_up:1;
+};
+
+
+struct options defaults = {
+ .skip_dots = 1,
+ .skip_self_and_up = 1,
+};
+
+
+int ls(const char * path, struct options opts)
{
DIR * dir;
if (NULL == (dir = opendir(path))) {
@@ -12,8 +25,16 @@ int ls(const char * path)
return 1;
}
struct dirent * entry;
- while (NULL != (entry = readdir(dir)))
+ while (NULL != (entry = readdir(dir))) {
+ const unsigned int is_dot = '.' == entry->d_name[0];
+ if (opts.skip_dots && is_dot)
+ continue;
+ const unsigned int is_self = is_dot && 0 == entry->d_name[1];
+ const unsigned int is_up = is_dot && '.' == entry->d_name[1];
+ if (opts.skip_self_and_up && (is_self || is_up))
+ continue;
printf("%s\n", entry->d_name);
+ }
closedir(dir);
return 0;
}
@@ -21,10 +42,25 @@ int ls(const char * path)
int main(int argc, char * argv[])
{
+ int opt;
+ struct options opts = defaults;
+ while (-1 != (opt = getopt(argc, argv, "aA"))) {
+ switch (opt) {
+ case 'a':
+ opts.skip_self_and_up = 0;
+ // fall-through
+ case 'A':
+ opts.skip_dots = 0;
+ break;
+ default:
+ dprintf(2, "Usage: %s [-aA] [file...]\n", argv[0]);
+ return 1;
+ }
+ }
int res = 0;
- if (argc == 1)
- res |= ls(".");
- for (int i = 1; i < argc; ++i)
- res |= ls(argv[i]);
+ if (optind >= argc)
+ res |= ls(".", opts);
+ for (int i = optind; i < argc; ++i)
+ res |= ls(argv[i], opts);
return res;
}