1 #include <ccan/talloc/talloc.h>
2 #include <ccan/grab_file/grab_file.h>
3 #include <ccan/noerr/noerr.h>
4 #include <ccan/read_write_all/read_write_all.h>
15 static char *tmpdir = NULL;
16 static unsigned int count;
18 char *talloc_basename(const void *ctx, const char *dir)
20 char *p = strrchr(dir, '/');
24 return talloc_strdup(ctx, p+1);
27 char *talloc_dirname(const void *ctx, const char *dir)
29 char *p = strrchr(dir, '/');
32 return talloc_strdup(ctx, ".");
33 return talloc_strndup(ctx, dir, p - dir);
36 char *talloc_getcwd(const void *ctx)
41 /* *This* is why people hate C. */
43 cwd = talloc_array(ctx, char, len);
44 while (!getcwd(cwd, len)) {
45 if (errno != ERANGE) {
49 cwd = talloc_realloc(ctx, cwd, char, len *= 2);
54 /* Returns output if command fails. */
55 char *run_command(const void *ctx, const char *fmt, ...)
62 cmd = talloc_vasprintf(ctx, fmt, ap);
65 /* Ensure stderr gets to us too. */
66 cmd = talloc_asprintf_append(cmd, " 2>&1");
68 pipe = popen(cmd, "r");
70 return talloc_asprintf(ctx, "Failed to run '%s'", cmd);
72 contents = grab_fd(cmd, fileno(pipe), NULL);
73 if (pclose(pipe) != 0)
74 return talloc_asprintf(ctx, "Running '%s':\n%s",
81 static int unlink_all(char *dir)
83 char cmd[strlen(dir) + sizeof("rm -rf ")];
84 sprintf(cmd, "rm -rf %s", dir);
86 warn("Could not remove temporary work in %s", dir);
90 char *temp_file(const void *ctx, const char *extension)
92 /* For first call, create dir. */
94 tmpdir = getenv("TMPDIR");
97 tmpdir = talloc_asprintf(talloc_autofree_context(),
99 tmpdir, getpid(), random());
100 if (mkdir(tmpdir, 0700) != 0) {
101 if (errno == EEXIST) {
106 err(1, "mkdir %s failed", tmpdir);
108 talloc_set_destructor(tmpdir, unlink_all);
111 return talloc_asprintf(ctx, "%s/%u%s", tmpdir, count++, extension);
114 bool move_file(const char *oldname, const char *newname)
121 /* Simple case: rename works. */
122 if (rename(oldname, newname) == 0)
125 /* Try copy and delete: not atomic! */
126 contents = grab_file(NULL, oldname, &size);
130 fd = open(newname, O_WRONLY|O_CREAT|O_TRUNC, 0666);
136 ret = write_all(fd, contents, size);
146 talloc_free(contents);