dirname.c 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. /* $OpenBSD: dirname.c,v 1.13 2005/08/08 08:05:33 espie Exp $ */
  2. /*
  3. * Copyright (c) 1997, 2004 Todd C. Miller <Todd.Miller@courtesan.com>
  4. *
  5. * Permission to use, copy, modify, and distribute this software for any
  6. * purpose with or without fee is hereby granted, provided that the above
  7. * copyright notice and this permission notice appear in all copies.
  8. *
  9. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  10. * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  11. * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  12. * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  13. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  14. * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  15. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  16. */
  17. /* OPENBSD ORIGINAL: lib/libc/gen/dirname.c */
  18. #include "includes.h"
  19. #ifndef HAVE_DIRNAME
  20. #include <errno.h>
  21. #include <string.h>
  22. #include <sys/param.h>
  23. char *
  24. dirname(const char *path)
  25. {
  26. static char dname[MAXPATHLEN];
  27. size_t len;
  28. const char *endp;
  29. /* Empty or NULL string gets treated as "." */
  30. if (path == NULL || *path == '\0') {
  31. dname[0] = '.';
  32. dname[1] = '\0';
  33. return (dname);
  34. }
  35. /* Strip any trailing slashes */
  36. endp = path + strlen(path) - 1;
  37. while (endp > path && *endp == '/')
  38. endp--;
  39. /* Find the start of the dir */
  40. while (endp > path && *endp != '/')
  41. endp--;
  42. /* Either the dir is "/" or there are no slashes */
  43. if (endp == path) {
  44. dname[0] = *endp == '/' ? '/' : '.';
  45. dname[1] = '\0';
  46. return (dname);
  47. } else {
  48. /* Move forward past the separating slashes */
  49. do {
  50. endp--;
  51. } while (endp > path && *endp == '/');
  52. }
  53. len = endp - path + 1;
  54. if (len >= sizeof(dname)) {
  55. errno = ENAMETOOLONG;
  56. return (NULL);
  57. }
  58. memcpy(dname, path, len);
  59. dname[len] = '\0';
  60. return (dname);
  61. }
  62. #endif