commit 75094f44e6c8dc65cbf6ac9c680aae419538538d
parent 071fb3b64f2823167e31a17d6742086392c74943
Author: phoebos <ben@bvnf.space>
Date: Tue, 11 Jan 2022 22:54:42 +0000
pwd: add
Diffstat:
4 files changed, 72 insertions(+), 2 deletions(-)
diff --git a/Makefile b/Makefile
@@ -9,6 +9,7 @@ BINS = \
head \
ls \
mkdir \
+ pwd \
sort \
tee \
true \
diff --git a/PROGRESS b/PROGRESS
@@ -29,7 +29,7 @@
[ ] nl
[ ] printf
[ ] ps
-[ ] pwd
+[x] pwd [-LP]
[ ] rm
[ ] rmdir
[ ] shred
diff --git a/TODO.posix b/TODO.posix
@@ -83,7 +83,7 @@
[ ] printf
[ ] prs
[ ] ps
-[ ] pwd
+[x] pwd
[ ] renice
[ ] rm
[ ] rmdir
diff --git a/pwd.c b/pwd.c
@@ -0,0 +1,69 @@
+#include <errno.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+int
+main(int argc, char **argv) {
+ int c, flag_L = 1;
+ long size;
+ while ((c = getopt(argc, argv, "LP")) != -1) {
+ switch (c) {
+ case 'L':
+ flag_L = 1;
+ break;
+ case 'P':
+ flag_L = 0;
+ break;
+ case '?':
+ fprintf(stderr, "usage: %s [-L|-P]\n", argv[0]);
+ return 1;
+ }
+ }
+
+ if (flag_L) {
+ char *cwd = getenv("PWD");
+ if (cwd == NULL)
+ goto flag_P;
+ else if (*cwd != '/')
+ goto flag_P;
+ else if (strstr(cwd, "/./") != NULL)
+ goto flag_P;
+ else if (strstr(cwd, "/../") != NULL)
+ goto flag_P;
+
+ /* POSIX.1-2017 does not specify what to do if $PWD is longer than PATH_MAX bytes;
+ * this implementation chooses to print the pathname found from PWD in this case.
+ */
+
+ puts(cwd);
+ return 0;
+ }
+
+flag_P:
+ size = pathconf(".", _PC_PATH_MAX);
+ if (size == -1)
+ size = PATH_MAX;
+
+ char *buf = NULL;
+ for (char *tmp = NULL; tmp == NULL; size += 32) {
+ buf = realloc(buf, size);
+ if (buf == NULL) {
+ perror("pwd");
+ return 1;
+ }
+
+ errno = 0;
+ tmp = getcwd(buf, size);
+ if (tmp == NULL && errno != ERANGE) {
+ perror("pwd");
+ return 1;
+ }
+ }
+
+ puts(buf);
+ free(buf);
+ return 0;
+}