diff -up patch-2.5.4/util.c.posix-backup patch-2.5.4/util.c --- patch-2.5.4/util.c.posix-backup 2008-06-16 10:22:52.000000000 +0100 +++ patch-2.5.4/util.c 2008-06-16 11:30:27.000000000 +0100 @@ -109,37 +109,40 @@ move_file (char const *from, int volatil memory_fatal (); } - if (to_errno) + if (strcmp (bakname, "/dev/null") != 0) { - int fd; + if (to_errno) + { + int fd; - if (debug & 4) - say ("Creating empty unreadable file %s\n", quotearg (bakname)); + if (debug & 4) + say ("Creating empty unreadable file %s\n", quotearg (bakname)); - try_makedirs_errno = ENOENT; - unlink (bakname); - while ((fd = creat (bakname, 0)) < 0) - { - if (errno != try_makedirs_errno) - pfatal ("Can't create file %s", quotearg (bakname)); - makedirs (bakname); - try_makedirs_errno = 0; + try_makedirs_errno = ENOENT; + unlink (bakname); + while ((fd = creat (bakname, 0)) < 0) + { + if (errno != try_makedirs_errno) + pfatal ("Can't create file %s", quotearg (bakname)); + makedirs (bakname); + try_makedirs_errno = 0; + } + if (close (fd) != 0) + pfatal ("Can't close file %s", quotearg (bakname)); } - if (close (fd) != 0) - pfatal ("Can't close file %s", quotearg (bakname)); - } - else - { - if (debug & 4) - say ("Renaming file %s to %s\n", - quotearg_n (0, to), quotearg_n (1, bakname)); - while (rename (to, bakname) != 0) + else { - if (errno != try_makedirs_errno) - pfatal ("Can't rename file %s to %s", - quotearg_n (0, to), quotearg_n (1, bakname)); - makedirs (bakname); - try_makedirs_errno = 0; + if (debug & 4) + say ("Renaming file %s to %s\n", + quotearg_n (0, to), quotearg_n (1, bakname)); + while (rename (to, bakname) != 0) + { + if (errno != try_makedirs_errno) + pfatal ("Can't rename file %s to %s", + quotearg_n (0, to), quotearg_n (1, bakname)); + makedirs (bakname); + try_makedirs_errno = 0; + } } } diff -up patch-2.5.4/backupfile.c.posix-backup patch-2.5.4/backupfile.c --- patch-2.5.4/backupfile.c.posix-backup 2008-06-16 11:27:55.000000000 +0100 +++ patch-2.5.4/backupfile.c 2008-06-16 11:44:05.000000000 +0100 @@ -23,6 +23,8 @@ # include #endif +#define XTERN extern +#include #include #include @@ -118,11 +120,15 @@ static int version_number PARAMS ((const char * find_backup_file_name (const char *file, enum backup_type backup_type) { + static char **previous_files = NULL; + static int previous_files_allocated = 0; + size_t backup_suffix_size_max; size_t file_len = strlen (file); size_t numbered_suffix_size_max = INT_STRLEN_BOUND (int) + 4; char *s; const char *suffix = simple_backup_suffix; + int used_version = 0; /* Allow room for simple or `.~N~' backups. */ backup_suffix_size_max = strlen (simple_backup_suffix) + 1; @@ -147,12 +153,66 @@ find_backup_file_name (const char *file, char *numbered_suffix = s + (file_len + backup_suffix_size_max); sprintf (numbered_suffix, ".~%d~", highest_backup + 1); suffix = numbered_suffix; + used_version = 1; } strcpy (s, file); } #endif /* HAVE_DIR */ - addext (s, suffix, '~'); + if (used_version == 0) + { + /* If we have already written a ".orig" backup file during + this run, don't overwrite it. */ + if (previous_files_allocated != 0) + { + int i; + for (i = 0; previous_files[i] != NULL; i++) + { + if (!strcmp (previous_files[i], s)) + { + strcpy (s, "/dev/null"); + break; + } + } + + if (previous_files[i] == NULL) + { + if (i == previous_files_allocated - 1) + { + char **old_previous_files = previous_files; + previous_files = realloc (previous_files, + 2 * previous_files_allocated * + sizeof (const char *)); + if (previous_files) + previous_files_allocated *= 2; + else + { + for (i = 0; old_previous_files[i] != NULL; i++) + free (old_previous_files[i]); + free (old_previous_files); + previous_files_allocated = 0; + } + } + + if (i < previous_files_allocated - 1) + { + previous_files[i] = strdup (s); + previous_files[i + 1] = NULL; + } + } + } + else + { + previous_files_allocated = 2; + previous_files = malloc (previous_files_allocated * + sizeof (const char *)); + previous_files[0] = strdup (s); + previous_files[1] = NULL; + } + } + + if (strcmp (s, "/dev/null") != 0) + addext (s, suffix, '~'); } return s; }