xreadlink.c 1.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. /* vi: set sw=4 ts=4: */
  2. /*
  3. * xreadlink.c - safe implementation of readlink.
  4. * Returns a NULL on failure...
  5. */
  6. #include "libbb.h"
  7. /*
  8. * NOTE: This function returns a malloced char* that you will have to free
  9. * yourself. You have been warned.
  10. */
  11. char *xmalloc_readlink(const char *path)
  12. {
  13. enum { GROWBY = 80 }; /* how large we will grow strings by */
  14. char *buf = NULL;
  15. int bufsize = 0, readsize = 0;
  16. do {
  17. buf = xrealloc(buf, bufsize += GROWBY);
  18. readsize = readlink(path, buf, bufsize);
  19. if (readsize == -1) {
  20. free(buf);
  21. return NULL;
  22. }
  23. } while (bufsize < readsize + 1);
  24. buf[readsize] = '\0';
  25. return buf;
  26. }
  27. char *xmalloc_readlink_or_warn(const char *path)
  28. {
  29. char *buf = xmalloc_readlink(path);
  30. if (!buf) {
  31. /* EINVAL => "file: Invalid argument" => puzzled user */
  32. bb_error_msg("%s: cannot read link (not a symlink?)", path);
  33. }
  34. return buf;
  35. }
  36. /* UNUSED */
  37. #if 0
  38. char *xmalloc_realpath(const char *path)
  39. {
  40. #if defined(__GLIBC__) && !defined(__UCLIBC__)
  41. /* glibc provides a non-standard extension */
  42. return realpath(path, NULL);
  43. #else
  44. char buf[PATH_MAX+1];
  45. /* on error returns NULL (xstrdup(NULL) ==NULL) */
  46. return xstrdup(realpath(path, buf));
  47. #endif
  48. }
  49. #endif