diff options
-rw-r--r-- | lib/backup-files.c | 50 | ||||
-rw-r--r-- | quilt.changes | 9 |
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 |