summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/backup-files.c50
-rw-r--r--quilt.changes9
2 files changed, 44 insertions, 15 deletions
diff --git a/lib/backup-files.c b/lib/backup-files.c
index fe40a8a..c4ae56f 100644
--- a/lib/backup-files.c
+++ b/lib/backup-files.c
@@ -413,38 +413,58 @@ foreachdir_rec(const char *path, struct stat *st,
DIR *dir;
struct dirent *dp;
int failed = 0;
- char *p = malloc_nofail(PATH_MAX);
+
+ struct path {
+ char *name;
+ struct path *next;
+ };
+ struct path *paths = NULL, *last_path = NULL;
if (access(path, R_OK|X_OK) || !(dir = opendir(path)))
return walk(path, NULL);
while ((dp = readdir(dir))) {
+ struct path *p;
+ size_t size;
+
if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, ".."))
continue;
- if (strlen(path) + 1 + strlen(dp->d_name) + 1 > PATH_MAX) {
- fprintf(stderr, "%s/%s: name too long\n", path,
- dp->d_name);
- failed = -1;
- goto out;
- }
- sprintf(p, "%s/%s", path, dp->d_name);
-
- if (lstat(p, st))
+
+ p = malloc_nofail(sizeof(*p));
+ if (!last_path)
+ paths = p;
+ else
+ last_path->next = p;
+ p->next = NULL;
+ last_path = p;
+
+ size = strlen(path) + 1 + strlen(dp->d_name) + 1;
+ p->name = malloc_nofail(size);
+ sprintf(p->name, "%s/%s", path, dp->d_name);
+ }
+ if (closedir(dir) != 0)
+ failed = -1;
+
+ while (paths != NULL) {
+ struct path *next;
+
+ if (lstat(paths->name, st))
continue; /* file has disappeared meanwhile */
if (S_ISDIR(st->st_mode)) {
- failed = foreachdir_rec(p, st, walk);
+ failed = foreachdir_rec(paths->name, st, walk);
if (failed)
goto out;
} else {
- failed = walk(p, st);
+ failed = walk(paths->name, st);
if (failed)
goto out;
}
+ next = paths->next;
+ free(paths->name);
+ free(paths);
+ paths = next;
}
- if (closedir(dir) != 0)
- failed = -1;
out:
- free(p);
return failed;
}
diff --git a/quilt.changes b/quilt.changes
index ffe62c9..a9637ca 100644
--- a/quilt.changes
+++ b/quilt.changes
@@ -1,4 +1,13 @@
-------------------------------------------------------------------
+Mon Jun 15 16:12:30 CEST 2009 - agruen@suse.de
+
+- Some filesystems / operating systems may miss files in readdir()
+ loops when the directory is modified at the same time (e.g.,
+ http://support.apple.com/kb/TA21420). Avoid running into this
+ problem in backup-files.c by reading all files before processing
+ them.
+
+-------------------------------------------------------------------
Sun Apr 5 16:05:05 CEST 2009 - agruen@suse.de
- Push command: don't imply --force when --merge is given so that