tools.c 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. #include <ccan/talloc/talloc.h>
  2. #include <ccan/grab_file/grab_file.h>
  3. #include <sys/stat.h>
  4. #include <sys/types.h>
  5. #include <string.h>
  6. #include <unistd.h>
  7. #include <stdarg.h>
  8. #include <errno.h>
  9. #include <err.h>
  10. #include "tools.h"
  11. static char *tmpdir = NULL;
  12. static unsigned int count;
  13. char *talloc_basename(const void *ctx, const char *dir)
  14. {
  15. char *p = strrchr(dir, '/');
  16. if (!p)
  17. return (char *)dir;
  18. return talloc_strdup(ctx, p+1);
  19. }
  20. char *talloc_dirname(const void *ctx, const char *dir)
  21. {
  22. char *p = strrchr(dir, '/');
  23. if (!p)
  24. return talloc_strdup(ctx, ".");
  25. return talloc_strndup(ctx, dir, p - dir);
  26. }
  27. char *talloc_getcwd(const void *ctx)
  28. {
  29. unsigned int len;
  30. char *cwd;
  31. /* *This* is why people hate C. */
  32. len = 32;
  33. cwd = talloc_array(ctx, char, len);
  34. while (!getcwd(cwd, len)) {
  35. if (errno != ERANGE) {
  36. talloc_free(cwd);
  37. return NULL;
  38. }
  39. cwd = talloc_realloc(ctx, cwd, char, len *= 2);
  40. }
  41. return cwd;
  42. }
  43. /* Returns output if command fails. */
  44. char *run_command(const void *ctx, const char *fmt, ...)
  45. {
  46. va_list ap;
  47. char *cmd, *contents;
  48. FILE *pipe;
  49. va_start(ap, fmt);
  50. cmd = talloc_vasprintf(ctx, fmt, ap);
  51. va_end(ap);
  52. /* Ensure stderr gets to us too. */
  53. cmd = talloc_asprintf_append(cmd, " 2>&1");
  54. pipe = popen(cmd, "r");
  55. if (!pipe)
  56. return talloc_asprintf(ctx, "Failed to run '%s'", cmd);
  57. contents = grab_fd(cmd, fileno(pipe), NULL);
  58. if (pclose(pipe) != 0)
  59. return talloc_asprintf(ctx, "Running '%s':\n%s",
  60. cmd, contents);
  61. talloc_free(cmd);
  62. return NULL;
  63. }
  64. static int unlink_all(char *dir)
  65. {
  66. char cmd[strlen(dir) + sizeof("rm -rf ")];
  67. sprintf(cmd, "rm -rf %s", dir);
  68. if (system(cmd) != 0)
  69. warn("Could not remove temporary work in %s", dir);
  70. return 0;
  71. }
  72. char *temp_file(const void *ctx, const char *extension)
  73. {
  74. /* For first call, create dir. */
  75. while (!tmpdir) {
  76. tmpdir = getenv("TMPDIR");
  77. if (!tmpdir)
  78. tmpdir = "/tmp";
  79. tmpdir = talloc_asprintf(talloc_autofree_context(),
  80. "%s/ccanlint-%u.%lu",
  81. tmpdir, getpid(), random());
  82. if (mkdir(tmpdir, 0700) != 0) {
  83. if (errno == EEXIST) {
  84. talloc_free(tmpdir);
  85. tmpdir = NULL;
  86. continue;
  87. }
  88. err(1, "mkdir %s failed", tmpdir);
  89. }
  90. talloc_set_destructor(tmpdir, unlink_all);
  91. }
  92. return talloc_asprintf(ctx, "%s/%u%s", tmpdir, count++, extension);
  93. }