From: Frank Lahm Date: Mon, 26 Mar 2012 09:06:38 +0000 (+0200) Subject: Merge remote branch 'sf/branch-allea' into branch-allea X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?p=netatalk.git;a=commitdiff_plain;h=8e89b0cc792ec9a91267fc310eb2d4fd00be53f2;hp=bb6fd82ff3029d84c62ecedbcacc2f3578f8d487 Merge remote branch 'sf/branch-allea' into branch-allea --- diff --git a/etc/cnid_dbd/cnid_metad.c b/etc/cnid_dbd/cnid_metad.c index d6fbcb06..b140fd09 100644 --- a/etc/cnid_dbd/cnid_metad.c +++ b/etc/cnid_dbd/cnid_metad.c @@ -288,36 +288,41 @@ static int set_dbdir(const char *dbdir, const char *vpath) EC_INIT; int status; struct stat st; - bstring oldpath, newpath, cmd = NULL; + bstring oldpath, newpath; + char *cmd_argv[4]; + + LOG(log_note, logtype_cnid, "set_dbdir: volume: %s, db path: %s", vpath, dbdir); EC_NULL_LOG( oldpath = bformat("%s/%s/", vpath, DBHOME) ); EC_NULL_LOG( newpath = bformat("%s/%s/", dbdir, DBHOME) ); if (lstat(dbdir, &st) < 0 && mkdir(dbdir, 0755) < 0) { LOG(log_error, logtype_cnid, "set_dbdir: mkdir failed for %s", dbdir); - return -1; + EC_FAIL; } if (lstat(bdata(oldpath), &st) == 0 && lstat(bdata(newpath), &st) != 0 && errno == ENOENT) { /* There's an .AppleDB in the volume root, we move it */ - EC_NULL_LOG( cmd = bformat("mv '%s' '%s'", bdata(oldpath), dbdir) ); - LOG(log_debug, logtype_cnid, "set_dbdir: cmd: %s", bdata(cmd)); - if (WEXITSTATUS(system(bdata(cmd))) != 0) { + cmd_argv[0] = "mv"; + cmd_argv[1] = bdata(oldpath); + cmd_argv[2] = (char *)dbdir; + cmd_argv[3] = NULL; + if (run_cmd("mv", cmd_argv) != 0) { LOG(log_error, logtype_cnid, "set_dbdir: moving CNID db from \"%s\" to \"%s\" failed", bdata(oldpath), dbdir); EC_FAIL; } + } if (lstat(bdata(newpath), &st) < 0 && mkdir(bdata(newpath), 0755 ) < 0) { LOG(log_error, logtype_cnid, "set_dbdir: mkdir failed for %s", bdata(newpath)); - return -1; + EC_FAIL; } EC_CLEANUP: bdestroy(oldpath); bdestroy(newpath); - bdestroy(cmd); EC_EXIT; } diff --git a/include/atalk/util.h b/include/atalk/util.h index 7fbae2df..25067af0 100644 --- a/include/atalk/util.h +++ b/include/atalk/util.h @@ -181,6 +181,7 @@ extern char *stripped_slashes_basename(char *p); extern int lchdir(const char *dir); extern void randombytes(void *buf, int n); extern int daemonize(int nochdir, int noclose); +extern int run_cmd(const char *cmd, char **cmd_argv); /****************************************************************** * cnid.c diff --git a/libatalk/util/unix.c b/libatalk/util/unix.c index 7d66fb61..56c3e168 100644 --- a/libatalk/util/unix.c +++ b/libatalk/util/unix.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -41,6 +42,7 @@ #include #include #include +#include /* close all FDs >= a specified value */ static void closeall(int fd) @@ -51,6 +53,55 @@ static void closeall(int fd) close(fd++); } +/*! + * Run command in a child and wait for it to finish + */ +int run_cmd(const char *cmd, char **cmd_argv) +{ + EC_INIT; + pid_t pid, wpid; + sigset_t sigs, oldsigs; + int status = 0; + + sigfillset(&sigs); + pthread_sigmask(SIG_SETMASK, &sigs, &oldsigs); + + if ((pid = fork()) < 0) { + LOG(log_error, logtype_default, "run_cmd: fork: %s", strerror(errno)); + return -1; + } + + if (pid == 0) { + /* child */ + closeall(3); + execvp("mv", cmd_argv); + } + + /* parent */ + while ((wpid = waitpid(pid, &status, 0)) < 0) { + if (errno == EINTR) + continue; + break; + } + if (wpid != pid) { + LOG(log_error, logtype_default, "waitpid(%d): %s", (int)pid, strerror(errno)); + EC_FAIL; + } + + if (WIFEXITED(status)) + status = WEXITSTATUS(status); + else if (WIFSIGNALED(status)) + status = WTERMSIG(status); + + LOG(log_note, logtype_default, "run_cmd(\"%s\"): status: %d", cmd, status); + +EC_CLEANUP: + if (status != 0) + ret = status; + pthread_sigmask(SIG_SETMASK, &oldsigs, NULL); + EC_EXIT; +} + /*! * Daemonize *