xref: /third_party/toybox/toys/posix/pwd.c (revision 0f66f451)
10f66f451Sopenharmony_ci/* pwd.c - Print working directory.
20f66f451Sopenharmony_ci *
30f66f451Sopenharmony_ci * Copyright 2006 Rob Landley <rob@landley.net>
40f66f451Sopenharmony_ci *
50f66f451Sopenharmony_ci * See http://opengroup.org/onlinepubs/9699919799/utilities/pwd.html
60f66f451Sopenharmony_ci
70f66f451Sopenharmony_ciUSE_PWD(NEWTOY(pwd, ">0LP[-LP]", TOYFLAG_BIN|TOYFLAG_MAYFORK))
80f66f451Sopenharmony_ci
90f66f451Sopenharmony_ciconfig PWD
100f66f451Sopenharmony_ci  bool "pwd"
110f66f451Sopenharmony_ci  default y
120f66f451Sopenharmony_ci  help
130f66f451Sopenharmony_ci    usage: pwd [-L|-P]
140f66f451Sopenharmony_ci
150f66f451Sopenharmony_ci    Print working (current) directory.
160f66f451Sopenharmony_ci
170f66f451Sopenharmony_ci    -L	Use shell's path from $PWD (when applicable)
180f66f451Sopenharmony_ci    -P	Print canonical absolute path
190f66f451Sopenharmony_ci*/
200f66f451Sopenharmony_ci
210f66f451Sopenharmony_ci#define FOR_pwd
220f66f451Sopenharmony_ci#include "toys.h"
230f66f451Sopenharmony_ci
240f66f451Sopenharmony_civoid pwd_main(void)
250f66f451Sopenharmony_ci{
260f66f451Sopenharmony_ci  char *s, *pwd = getcwd(0, 0), *PWD;
270f66f451Sopenharmony_ci
280f66f451Sopenharmony_ci  // Only use $PWD if it's an absolute path alias for cwd with no "." or ".."
290f66f451Sopenharmony_ci  if (!FLAG(P) && (s = PWD = getenv("PWD"))) {
300f66f451Sopenharmony_ci    struct stat st1, st2;
310f66f451Sopenharmony_ci
320f66f451Sopenharmony_ci    while (*s == '/') {
330f66f451Sopenharmony_ci      if (*(++s) == '.') {
340f66f451Sopenharmony_ci        if (s[1] == '/' || !s[1]) break;
350f66f451Sopenharmony_ci        if (s[1] == '.' && (s[2] == '/' || !s[2])) break;
360f66f451Sopenharmony_ci      }
370f66f451Sopenharmony_ci      while (*s && *s != '/') s++;
380f66f451Sopenharmony_ci    }
390f66f451Sopenharmony_ci    if (!*s && s != PWD) s = PWD;
400f66f451Sopenharmony_ci    else s = 0;
410f66f451Sopenharmony_ci
420f66f451Sopenharmony_ci    // If current directory exists, make sure it matches.
430f66f451Sopenharmony_ci    if (s && pwd)
440f66f451Sopenharmony_ci        if (stat(pwd, &st1) || stat(PWD, &st2) || st1.st_ino != st2.st_ino ||
450f66f451Sopenharmony_ci            st1.st_dev != st2.st_dev) s = 0;
460f66f451Sopenharmony_ci  } else s = 0;
470f66f451Sopenharmony_ci
480f66f451Sopenharmony_ci  // If -L didn't give us a valid path, use cwd.
490f66f451Sopenharmony_ci  if (s || (s = pwd)) puts(s);
500f66f451Sopenharmony_ci  free(pwd);
510f66f451Sopenharmony_ci  if (!s) perror_exit("xgetcwd");
520f66f451Sopenharmony_ci}
53