testsuite portability fixes
authorJ. Ali Harlow <ali@juiblex.co.uk>
Mon, 1 Sep 2014 11:19:32 +0000 (12:19 +0100)
committerJ. Ali Harlow <ali@juiblex.co.uk>
Mon, 1 Sep 2014 11:19:32 +0000 (12:19 +0100)
librazor/atomic-actions.c
librazor/atomic-emulate.c
po/POTFILES.in
src/test-driver.c
test/Makefile.am

index f545856..df06432 100644 (file)
@@ -489,7 +489,7 @@ struct atomic_action *atomic_action_do(struct razor_atomic *atomic,
                if (razor_atomic_in_error_state(atomic)) {
                        atomic_action_undo(atomic, done);
                        done = NULL;
-                       atomic_action_free(actions);
+                       atomic_action_free(a);
                }
        }
 
index 1ba8f96..ab020d1 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012  J. Ali Harlow <ali@juiblex.co.uk>
+ * Copyright (C) 2012, 2014  J. Ali Harlow <ali@juiblex.co.uk>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -29,6 +29,7 @@
 #include <fcntl.h>
 #include <dirent.h>
 #include <errno.h>
+#include <unistd.h>
 #include "razor-internal.h"
 
 /*
@@ -119,21 +120,70 @@ RAZOR_EXPORT void razor_atomic_destroy(struct razor_atomic *atomic)
        free(atomic);
 }
 
+#ifndef MSWIN_API
+static char *absolute_path(const char *path)
+{
+       int len;
+       char *result, *subpath, *p, *s, *t;
+
+       result = realpath(path, NULL);
+
+       if (!result && errno == ENOENT) {
+               p = strdup(path);
+               s = strrchr(p, '/');
+
+               while (s) {
+                       if (s == p) {
+                               result = strdup("/");
+                               break;
+                       }
+
+                       *s = '\0';
+                       subpath = realpath(p, NULL);
+
+                       if (subpath) {
+                               *s = '/';
+                               len = strlen(subpath);
+                               result = malloc(len + strlen(s) + 1);
+                               memcpy(result, subpath, len);
+                               strcpy(result + len, s);
+                               break;
+                       } else if (errno != ENOENT)
+                               break;
+
+                       t = strrchr(p, '/');
+                       *s = '/';
+                       s = t;
+               }
+
+               if (!s)
+                       result = realpath(".", NULL);
+
+               free(p);
+       }
+
+       return result;
+}
+#endif
+
 /*
  * We need a toplevel directory in which to hold temporary files
  * before they are committed. Since we can generally assume that
- * we have write permissions anywhere on the disk in question,
- * the best location is in the relevant root directory. The most
- * common case where this assumption fails is when testing, when
- * the current directory is a good choice.
- * It might be even better to find a mount point above path instead
- * but this is hard to do, and probably not worth the effort.
+ * we have write permissions anywhere on the filesystem in
+ * question, the best location is at the relevant mount point.
+ * The most common case where this assumption fails is when
+ * testing, when the current directory is a good choice.
  */
 
 static int
 razor_atomic_set_toplevel_from_path(struct razor_atomic *atomic,
                                    const char *path)
 {
+#ifndef MSWIN_API
+       dev_t filesystem;
+       struct stat buf;
+#endif
+
        if (razor_atomic_in_error_state(atomic))
                return -1;
 
@@ -183,7 +233,66 @@ razor_atomic_set_toplevel_from_path(struct razor_atomic *atomic,
                free(buf);
        }
 #else
-       atomic->toplevel = strdup("/.atomic-XXXXXX");
+       {
+               /*
+                * Find the mount point (assuming we can write to the
+                * whole filesystem). Otherwise stop at the first
+                * unwritable directory and take one step back.
+                */
+               char *s, *abspath, saved;
+               int len;
+
+               abspath = absolute_path(path);
+               if (!abspath) {
+                       atomic->error = razor_error_new_str(path,
+                                                           strerror(errno));
+                       return -1;
+               }
+
+               if (stat(abspath, &buf) < 0) {
+                       atomic->error = razor_error_new_str(abspath,
+                                                           strerror(errno));
+                       free(abspath);
+                       return -1;
+               }
+               filesystem = buf.st_dev;
+
+               len = strlen(abspath);
+               while(len > 1 && (s = strrchr(abspath, '/'))) {
+                       if (s == abspath) {
+                               saved = s[1];
+                               s[1] = '\0';
+                               len = s + 1 - abspath;
+                       } else {
+                               s[0] = '\0';
+                               len = s - abspath;
+                       }
+
+                       if (stat(abspath, &buf) < 0) {
+                               atomic->error =
+                                 razor_error_new_str(abspath, strerror(errno));
+                               free(abspath);
+                               return -1;
+                       }
+
+                       if (buf.st_dev != filesystem || access(abspath, W_OK)) {
+                               if (s == abspath)
+                                       s[1] = saved;
+                               else
+                                       s[0] = '/';
+                               len = strlen(abspath);
+                               break;
+                       }
+               }
+
+               if (len == 1)
+                       len = 0;        /* Avoid an unslightly double slash. */
+               atomic->toplevel = malloc(len + strlen("/.atomic-XXXXXX") + 1);
+               memcpy(atomic->toplevel, abspath, len);
+               strcpy(atomic->toplevel + len, "/.atomic-XXXXXX");
+
+               free(abspath);
+       }
 #endif
 
        if (!mkdtemp(atomic->toplevel)) {
@@ -193,6 +302,24 @@ razor_atomic_set_toplevel_from_path(struct razor_atomic *atomic,
                if (err == EACCES) {
                        char *s = strdup("atomic-XXXXXX");
 
+#ifndef MSWIN_API
+                       if (stat(".", &buf) < 0) {
+                               atomic->error =
+                                 razor_error_new_str(".", strerror(errno));
+                               free(s);
+                               free(atomic->toplevel);
+                               atomic->toplevel = NULL;
+                               return -1;
+                       }
+                       if (buf.st_dev != filesystem)
+                               /*
+                                * Don't use a different filesystem. It will
+                                * only fail later on (in rename) and cause
+                                * an unhelpful error message (EXDEV).
+                                */
+                               free(s);
+                       else
+#endif
                        if (mkdtemp(s)) {
                                free(atomic->toplevel);
                                atomic->toplevel = s;
index b8ab93d..c83b566 100644 (file)
@@ -1,3 +1 @@
-gl/error.c
 gl/fnmatch_loop.c
-gl/xalloc-die.c
index d64c06e..85fbf9b 100644 (file)
@@ -18,6 +18,7 @@
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
+#include "config.h"
 #include <stdio.h>
 #include <string.h>
 #include <stdarg.h>
index 93ef076..2a6ccc2 100644 (file)
@@ -43,7 +43,7 @@ base/repodata/primary.xml.gz: zsh.spec zsh2.spec zip.spec zap.spec \
        mkdir -p base/rpms
        mv rpmbuild/RPMS/noarch/*.rpm base/rpms
        rm -rf rpmbuild
-       createrepo -o base base/rpms
+       createrepo --simple-md-filenames -o base base/rpms
 
 updates/repodata/primary.xml.gz:       zip.spec Makefile
        rm -rf rpmbuild updates
@@ -53,7 +53,7 @@ updates/repodata/primary.xml.gz:      zip.spec Makefile
        mkdir -p updates/rpms
        mv rpmbuild/RPMS/noarch/*.rpm updates/rpms
        rm -rf rpmbuild
-       createrepo -o updates updates/rpms
+       createrepo --simple-md-filenames -o updates updates/rpms
 
 primary.xml.gz:        base/repodata/primary.xml.gz
        cp base/repodata/primary.xml.gz base/repodata/filelists.xml.gz .