commit bd456465521b7cc55684a21531b27c712faa4138
parent 5be17e6aac924783632031feecb1442dc0f75f3d
Author: phoebos <ben@bvnf.space>
Date: Mon, 20 Sep 2021 21:33:21 +0100
ls: add
Diffstat:
M | Makefile | | | 1 | + |
A | ls.c | | | 74 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
2 files changed, 75 insertions(+), 0 deletions(-)
diff --git a/Makefile b/Makefile
@@ -4,6 +4,7 @@ BINS = \
cat \
echo \
false \
+ ls \
tee \
true \
diff --git a/ls.c b/ls.c
@@ -0,0 +1,74 @@
+#include <dirent.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+enum {
+ FLAG_1 = 1 << 0
+};
+
+int
+ls(const char *path, int flags) {
+ struct stat st;
+ if (lstat(path, &st) == -1) {
+ fprintf(stderr, "ls: %s: %s\n", path, strerror(errno));
+ return 1;
+ }
+ if (S_ISDIR(st.st_mode)) {
+ /* directory */
+ DIR *dir = opendir(path);
+ if (dir == NULL) {
+ fprintf(stderr, "ls: %s: %s\n", path, strerror(errno));
+ return 1;
+ }
+
+ struct dirent *dp;
+ while ((dp = readdir(dir)) != NULL) {
+ printf("%s", dp->d_name);
+
+ if (flags & FLAG_1)
+ putc('\n', stdout);
+ else
+ putc(' ', stdout);
+ }
+ } else {
+ /* file */
+ printf("%s", path);
+ if (flags & FLAG_1)
+ putc('\n', stdout);
+ else
+ putc(' ', stdout);
+ }
+ return 0;
+}
+
+int
+main(int argc, char **argv) {
+ int c, flags, ret_val;
+ flags = ret_val = 0;
+
+ while ((c = getopt(argc, argv, "1l")) != -1) {
+ switch (c) {
+ case '1':
+ case 'l':
+ flags |= FLAG_1;
+ break;
+ }
+ }
+ argv += optind - 1;
+
+ if(!isatty(1))
+ flags |= FLAG_1;
+
+ if (argc == optind)
+ ret_val = ls(".", flags);
+ else while (*++argv)
+ ret_val = ls(*argv, flags);
+
+ if (!flags & FLAG_1)
+ puts(""); /* final newline */
+
+ return ret_val;
+}