pwd.c 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. /* vi: set sw=4 ts=4: */
  2. /*
  3. * Mini pwd implementation for busybox
  4. *
  5. * Copyright (C) 1995, 1996 by Bruce Perens <bruce@pixar.com>.
  6. *
  7. * Licensed under GPLv2 or later, see file LICENSE in this source tree.
  8. */
  9. //usage:#define pwd_trivial_usage
  10. //usage: ""
  11. //usage:#define pwd_full_usage "\n\n"
  12. //usage: "Print the full filename of the current working directory"
  13. //usage:
  14. //usage:#define pwd_example_usage
  15. //usage: "$ pwd\n"
  16. //usage: "/root\n"
  17. #include "libbb.h"
  18. /* This is a NOFORK applet. Be very careful! */
  19. static int logical_getcwd(void)
  20. {
  21. struct stat st1;
  22. struct stat st2;
  23. char *wd;
  24. char *p;
  25. wd = getenv("PWD");
  26. if (!wd || wd[0] != '/')
  27. return 0;
  28. p = wd;
  29. while (*p) {
  30. /* doing strstr(p, "/.") by hand is smaller and faster... */
  31. if (*p++ != '/')
  32. continue;
  33. if (*p != '.')
  34. continue;
  35. /* we found "/.", skip to next char */
  36. p++;
  37. if (*p == '.')
  38. p++; /* we found "/.." */
  39. if (*p == '\0' || *p == '/')
  40. return 0; /* "/./" or "/../" component: bad */
  41. }
  42. if (stat(wd, &st1) != 0)
  43. return 0;
  44. if (stat(".", &st2) != 0)
  45. return 0;
  46. if (st1.st_ino != st2.st_ino)
  47. return 0;
  48. if (st1.st_dev != st2.st_dev)
  49. return 0;
  50. puts(wd);
  51. return 1;
  52. }
  53. int pwd_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
  54. int pwd_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
  55. {
  56. char *buf;
  57. if (ENABLE_DESKTOP) {
  58. /* TODO: assume -L if $POSIXLY_CORRECT? (coreutils does that)
  59. * Rationale:
  60. * POSIX requires a default of -L, but most scripts expect -P
  61. */
  62. unsigned opt = getopt32(argv, "LP");
  63. if ((opt & 1) && logical_getcwd())
  64. return fflush_all();
  65. }
  66. buf = xrealloc_getcwd_or_warn(NULL);
  67. if (buf) {
  68. puts(buf);
  69. free(buf);
  70. return fflush_all();
  71. }
  72. return EXIT_FAILURE;
  73. }