]> pd.if.org Git - pdutils/commitdiff
implemented pwd
authorNathan Wagner <nw@hydaspes.if.org>
Sun, 26 Apr 2015 00:13:36 +0000 (00:13 +0000)
committerNathan Wagner <nw@hydaspes.if.org>
Thu, 30 Apr 2015 02:28:44 +0000 (02:28 +0000)
utils/pwd/pwd.c [new file with mode: 0644]

diff --git a/utils/pwd/pwd.c b/utils/pwd/pwd.c
new file mode 100644 (file)
index 0000000..41e2ff4
--- /dev/null
@@ -0,0 +1,94 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+#include <unistd.h>
+#include <limits.h>
+#include <string.h>
+
+static int has_dot_or_dotdot(char *path) {
+       if (!path) return 0;
+
+       while (*path) {
+               if (*path == '/') {
+                       path++;
+                       continue;
+               }
+               if (*path == '.') {
+                       path++;
+                       if (*path == '.') path++;
+                       switch (path[0]) {
+                               case '/':
+                               case 0:
+                                       return 1;
+                               default:
+                                       break;
+                       }
+               }
+               while (*path && *path != '/') {
+                       path++;
+               }
+       }
+       return 0;
+}
+
+static void fillcwd(char *s, size_t n) {
+       if (!getcwd(s, n)) {
+               switch (errno) {
+                       case ERANGE:
+                               fprintf(stderr, "pwd: path too long\n");
+                               exit(1);
+                       default:
+                               perror("pwd");
+                               exit(1);
+               }
+       }
+}
+
+int main(int ac, char *av[]) {
+       int cleansym = 0;
+       char cwd[PATH_MAX];
+       char *pwd;
+       char *envpwd;
+       int arg;
+
+       for (arg=1; arg < ac; arg++) {
+               if (av[arg][0] == '-') {
+                      if (av[arg][1] == 'P' && av[arg][2] == 0) {
+                              cleansym = 1;
+                      } else if (av[arg][1] == 'L' && av[arg][2] == 0) {
+                              cleansym = 0;
+                      }
+               } else {
+                       fprintf(stderr, "usage: pwd [-L|-P]\n");
+                       exit(1);
+               }
+       }
+
+       if (!getcwd(cwd, sizeof cwd)) {
+               switch (errno) {
+                       case ERANGE:
+                               fprintf(stderr, "pwd: path too long\n");
+                               exit(1);
+                       default:
+                               perror("pwd");
+                               exit(1);
+               }
+       }
+       pwd = cwd;
+
+       if (!cleansym) {
+               envpwd = getenv("PWD");
+               if (envpwd && !has_dot_or_dotdot(envpwd)) {
+                       if (chdir(envpwd) != -1) {
+                               fillcwd(cwd, sizeof cwd);
+                               if (strcmp(cwd, envpwd)) {
+                                       pwd = envpwd;
+                               }
+                       }
+               }
+       }
+
+       printf("%s\n", pwd);
+       return 0;
+}
+