path.c 1005 B

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. /*
  2. * I'm tired of doing "vsnprintf()" etc just to open a
  3. * file, so here's a "return static buffer with printf"
  4. * interface for paths.
  5. *
  6. * It's obviously not thread-safe. Sue me. But it's quite
  7. * useful for doing things like
  8. *
  9. * f = open(mkpath("%s/%s.perf", base, name), O_RDONLY);
  10. *
  11. * which is what it's designed for.
  12. */
  13. #include "cache.h"
  14. #include "util.h"
  15. #include <limits.h>
  16. static char bad_path[] = "/bad-path/";
  17. /*
  18. * One hack:
  19. */
  20. static char *get_pathname(void)
  21. {
  22. static char pathname_array[4][PATH_MAX];
  23. static int idx;
  24. return pathname_array[3 & ++idx];
  25. }
  26. static char *cleanup_path(char *path)
  27. {
  28. /* Clean it up */
  29. if (!memcmp(path, "./", 2)) {
  30. path += 2;
  31. while (*path == '/')
  32. path++;
  33. }
  34. return path;
  35. }
  36. char *mkpath(const char *fmt, ...)
  37. {
  38. va_list args;
  39. unsigned len;
  40. char *pathname = get_pathname();
  41. va_start(args, fmt);
  42. len = vsnprintf(pathname, PATH_MAX, fmt, args);
  43. va_end(args);
  44. if (len >= PATH_MAX)
  45. return bad_path;
  46. return cleanup_path(pathname);
  47. }