diff options
-rw-r--r-- | common/sysutils.c | 70 | ||||
-rw-r--r-- | common/sysutils.h | 2 | ||||
-rw-r--r-- | g10/keyring.c | 4 | ||||
-rw-r--r-- | kbx/keybox-update.c | 4 | ||||
-rw-r--r-- | kbx/keybox-util.c | 66 | ||||
-rw-r--r-- | kbx/keybox.h | 2 |
6 files changed, 77 insertions, 71 deletions
diff --git a/common/sysutils.c b/common/sysutils.c index a0addd11d..c7df8722a 100644 --- a/common/sysutils.c +++ b/common/sysutils.c @@ -618,6 +618,76 @@ gnupg_remove (const char *fname) } +/* Wrapper for rename(2) to handle Windows peculiarities. If + * BLOCK_SIGNALS is not NULL and points to a variable set to true, all + * signals will be blocked by calling gnupg_block_all_signals; the + * caller needs to call gnupg_unblock_all_signals if that variable is + * still set to true on return. */ +gpg_error_t +gnupg_rename_file (const char *oldname, const char *newname, int *block_signals) +{ + gpg_error_t err = 0; + + if (block_signals && *block_signals) + gnupg_block_all_signals (); + +#ifdef HAVE_DOSISH_SYSTEM + { + int wtime = 0; + + gnupg_remove (newname); + again: + if (rename (oldname, newname)) + { + if (GetLastError () == ERROR_SHARING_VIOLATION) + { + /* Another process has the file open. We do not use a + * lock for read but instead we wait until the other + * process has closed the file. This may take long but + * that would also be the case with a dotlock approach for + * read and write. Note that we don't need this on Unix + * due to the inode concept. + * + * So let's wait until the rename has worked. The retry + * intervals are 50, 100, 200, 400, 800, 50ms, ... */ + if (!wtime || wtime >= 800) + wtime = 50; + else + wtime *= 2; + + if (wtime >= 800) + log_info (_("waiting for file '%s' to become accessible ...\n"), + oldname); + + Sleep (wtime); + goto again; + } + err = my_error_from_syserror (); + } + } +#else /* Unix */ + { +#ifdef __riscos__ + gnupg_remove (newname); +#endif + if (rename (oldname, newname) ) + err = my_error_from_syserror (); + } +#endif /* Unix */ + + if (block_signals && *block_signals && err) + { + gnupg_unblock_all_signals (); + *block_signals = 0; + } + + if (err) + log_error (_("renaming '%s' to '%s' failed: %s\n"), + oldname, newname, gpg_strerror (err)); + return err; +} + + #ifndef HAVE_W32_SYSTEM static mode_t modestr_to_mode (const char *modestr) diff --git a/common/sysutils.h b/common/sysutils.h index 0847da7ea..fef6ba13e 100644 --- a/common/sysutils.h +++ b/common/sysutils.h @@ -61,6 +61,8 @@ FILE *gnupg_tmpfile (void); void gnupg_reopen_std (const char *pgmname); void gnupg_allow_set_foregound_window (pid_t pid); int gnupg_remove (const char *fname); +gpg_error_t gnupg_rename_file (const char *oldname, const char *newname, + int *block_signals); int gnupg_mkdir (const char *name, const char *modestr); int gnupg_chmod (const char *name, const char *modestr); char *gnupg_mkdtemp (char *template); diff --git a/g10/keyring.c b/g10/keyring.c index 091151b2e..f1281e98e 100644 --- a/g10/keyring.c +++ b/g10/keyring.c @@ -1351,12 +1351,12 @@ rename_tmp_file (const char *bakfname, const char *tmpfname, const char *fname) /* First make a backup file. */ block = 1; - rc = keybox_file_rename (fname, bakfname, &block); + rc = gnupg_rename_file (fname, bakfname, &block); if (rc) goto fail; /* then rename the file */ - rc = keybox_file_rename (tmpfname, fname, NULL); + rc = gnupg_rename_file (tmpfname, fname, NULL); if (block) { gnupg_unblock_all_signals (); diff --git a/kbx/keybox-update.c b/kbx/keybox-update.c index dcf8b2e23..31171dea4 100644 --- a/kbx/keybox-update.c +++ b/kbx/keybox-update.c @@ -122,13 +122,13 @@ rename_tmp_file (const char *bakfname, const char *tmpfname, if (!secret) { block = 1; - rc = keybox_file_rename (fname, bakfname, &block); + rc = gnupg_rename_file (fname, bakfname, &block); if (rc) goto leave; } /* Then rename the file. */ - rc = keybox_file_rename (tmpfname, fname, NULL); + rc = gnupg_rename_file (tmpfname, fname, NULL); if (block) { gnupg_unblock_all_signals (); diff --git a/kbx/keybox-util.c b/kbx/keybox-util.c index aacd0a431..486753c0d 100644 --- a/kbx/keybox-util.c +++ b/kbx/keybox-util.c @@ -147,73 +147,9 @@ keybox_tmp_names (const char *filename, int for_keyring, return 0; } - -/* Wrapper for rename(2) to handle Windows peculiarities. If - * BLOCK_SIGNALS is not NULL and points to a variable set to true, all - * signals will be blocked by calling gnupg_block_all_signals; the - * caller needs to call gnupg_unblock_all_signals if that variable is - * still set to true on return. */ gpg_error_t keybox_file_rename (const char *oldname, const char *newname, int *block_signals) { - gpg_error_t err = 0; - - if (block_signals && *block_signals) - gnupg_block_all_signals (); - -#ifdef HAVE_DOSISH_SYSTEM - { - int wtime = 0; - - gnupg_remove (newname); - again: - if (rename (oldname, newname)) - { - if (GetLastError () == ERROR_SHARING_VIOLATION) - { - /* Another process has the file open. We do not use a - * lock for read but instead we wait until the other - * process has closed the file. This may take long but - * that would also be the case with a dotlock approach for - * read and write. Note that we don't need this on Unix - * due to the inode concept. - * - * So let's wait until the rename has worked. The retry - * intervals are 50, 100, 200, 400, 800, 50ms, ... */ - if (!wtime || wtime >= 800) - wtime = 50; - else - wtime *= 2; - - if (wtime >= 800) - log_info ("waiting for file '%s' to become accessible ...\n", - oldname); - - Sleep (wtime); - goto again; - } - err = gpg_error_from_syserror (); - } - } -#else /* Unix */ - { -#ifdef __riscos__ - gnupg_remove (newname); -#endif - if (rename (oldname, newname) ) - err = gpg_error_from_syserror (); - } -#endif /* Unix */ - - if (block_signals && *block_signals && err) - { - gnupg_unblock_all_signals (); - *block_signals = 0; - } - - if (err) - log_error ("renaming '%s' to '%s' failed: %s\n", - oldname, newname, gpg_strerror (err)); - return err; + return gnupg_rename_file (oldname, newname, block_signals); } diff --git a/kbx/keybox.h b/kbx/keybox.h index a248bf05f..5c2824a7f 100644 --- a/kbx/keybox.h +++ b/kbx/keybox.h @@ -134,8 +134,6 @@ void keybox_set_malloc_hooks ( void *(*new_alloc_func)(size_t n), gpg_error_t keybox_tmp_names (const char *filename, int for_keyring, char **r_bakname, char **r_tmpname); -gpg_error_t keybox_file_rename (const char *oldname, const char *newname, - int *block_signals); #ifdef __cplusplus |