diff options
author | José Bollo <jose.bollo@iot.bzh> | 2015-12-10 16:39:05 +0100 |
---|---|---|
committer | José Bollo <jose.bollo@iot.bzh> | 2015-12-10 16:39:05 +0100 |
commit | f3d64b7c741677cd28e2a11deed67196cd02b46a (patch) | |
tree | 57b6ee3ca5a206d78a39dbcdae49cac5a75ae59a /src/wgtpkg-workdir.c | |
parent | 63f8720a3e610c0dc37bda3138d2e8de98ec1a78 (diff) |
added info retrieval
Change-Id: I6f91b15e87308cf01db4ddafa3c2715c251f5fe5
Diffstat (limited to 'src/wgtpkg-workdir.c')
-rw-r--r-- | src/wgtpkg-workdir.c | 94 |
1 files changed, 70 insertions, 24 deletions
diff --git a/src/wgtpkg-workdir.c b/src/wgtpkg-workdir.c index 0c184a5..12cfa24 100644 --- a/src/wgtpkg-workdir.c +++ b/src/wgtpkg-workdir.c @@ -14,27 +14,26 @@ limitations under the License. */ +#define _GNU_SOURCE #include <unistd.h> #include <string.h> #include <dirent.h> #include <syslog.h> #include <errno.h> +#include <fcntl.h> +#include <sys/types.h> #include <sys/stat.h> #include "wgtpkg.h" -#ifndef PREDIR -#define PREDIR "./" -#endif - static int mode = 0700; static char workdir[PATH_MAX]; /* removes recursively the content of a directory */ -static int clean_dir() +static int clean_dirfd(int dirfd) { - int cr; + int cr, fd; DIR *dir; struct dirent *ent; struct { @@ -42,16 +41,16 @@ static int clean_dir() char spare[PATH_MAX]; } entry; - dir = opendir("."); + dir = fdopendir(dirfd); if (dir == NULL) { - syslog(LOG_ERR, "opendir failed in clean_dir"); + syslog(LOG_ERR, "opendir failed in clean_dirfd"); return -1; } cr = -1; for (;;) { if (readdir_r(dir, &entry.entry, &ent) != 0) { - syslog(LOG_ERR, "readdir_r failed in clean_dir"); + syslog(LOG_ERR, "readdir_r failed in clean_dirfd"); goto error; } if (ent == NULL) @@ -59,25 +58,25 @@ static int clean_dir() if (ent->d_name[0] == '.' && (ent->d_name[1] == 0 || (ent->d_name[1] == '.' && ent->d_name[2] == 0))) continue; - cr = unlink(ent->d_name); + cr = unlinkat(dirfd, ent->d_name, 0); if (!cr) continue; if (errno != EISDIR) { - syslog(LOG_ERR, "unlink of %s failed in clean_dir", ent->d_name); + syslog(LOG_ERR, "unlink of %s failed in clean_dirfd", ent->d_name); goto error; } - if (chdir(ent->d_name)) { - syslog(LOG_ERR, "enter directory %s failed in clean_dir", ent->d_name); + fd = openat(dirfd, ent->d_name, O_DIRECTORY|O_RDONLY); + if (fd < 0) { + syslog(LOG_ERR, "opening directory %s failed in clean_dirfd", ent->d_name); goto error; } - cr = clean_dir(); + cr = clean_dirfd(fd); + close(fd); if (cr) goto error; - if (chdir("..")) - goto error; - cr = rmdir(ent->d_name); + cr = unlinkat(dirfd, ent->d_name, AT_REMOVEDIR); if (cr) { - syslog(LOG_ERR, "rmdir of %s failed in clean_dir", ent->d_name); + syslog(LOG_ERR, "rmdir of %s failed in clean_dirfd", ent->d_name); goto error; } } @@ -87,6 +86,21 @@ error: return cr; } +/* removes recursively the content of a directory */ +static int clean_dir(const char *directory) +{ + int fd, rc; + + fd = openat(AT_FDCWD, directory, O_DIRECTORY|O_RDONLY); + if (fd < 0) { + syslog(LOG_ERR, "opening directory %s failed in clean_dir", directory); + return fd; + } + rc = clean_dirfd(fd); + close(fd); + return rc; +} + /* removes the content of the working directory */ int enter_workdir(int clean) { @@ -94,7 +108,7 @@ int enter_workdir(int clean) if (rc) syslog(LOG_ERR, "entring workdir %s failed", workdir); else if (clean) - rc = clean_dir(); + rc = clean_dir(workdir); return rc; } @@ -103,7 +117,7 @@ void remove_workdir() { enter_workdir(1); chdir(".."); - unlink(workdir); + rmdir(workdir); } int set_workdir(const char *name, int create) @@ -116,6 +130,7 @@ int set_workdir(const char *name, int create) length = strlen(name); if (length >= sizeof workdir) { syslog(LOG_ERR, "workdir name too long"); + errno = EINVAL; return -1; } @@ -133,16 +148,24 @@ int set_workdir(const char *name, int create) } else if (!S_ISDIR(s.st_mode)) { syslog(LOG_ERR, "%s isn't a directory", name); + errno = ENOTDIR; return -1; } memcpy(workdir, name, 1+length); return 0; } -/* install the widgets of the list */ -int make_workdir(int reuse) +int make_workdir_base(const char *root, const char *prefix, int reuse) { - int i; + int i, n, r, l; + + n = snprintf(workdir, sizeof workdir, "%s/%s", root, prefix); + if (n >= sizeof workdir) { + syslog(LOG_ERR, "workdir prefix too long"); + errno = EINVAL; + return -1; + } + r = (int)(sizeof workdir) - n; /* create a temporary directory */ for (i = 0 ; ; i++) { @@ -150,7 +173,12 @@ int make_workdir(int reuse) syslog(LOG_ERR, "exhaustion of workdirs"); return -1; } - sprintf(workdir, PREDIR "PACK%d", i); + l = snprintf(workdir + n, r, "%d", i); + if (l >= r) { + syslog(LOG_ERR, "computed workdir too long"); + errno = EINVAL; + return -1; + } if (!mkdir(workdir, mode)) break; if (errno != EEXIST) { @@ -164,3 +192,21 @@ int make_workdir(int reuse) return 0; } +int make_workdir(int reuse) +{ + return make_workdir_base(".", "PACK", reuse); +} + +int workdirfd() +{ + int result = open(workdir, O_PATH|O_DIRECTORY); + if (result < 0) + syslog(LOG_ERR, "can't get fd for workdir %.*s: %m", PATH_MAX, workdir); + return result; +} + +int move_workdir(const char *dest, int parents, int force) +{ + +} + |