--- /dev/null
+#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;
+}
+