aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2023-05-04 09:47:01 +0000
committerWerner Koch <[email protected]>2023-05-04 09:47:01 +0000
commit30f1eda7d8c0459735739ecaa999364ead72c297 (patch)
treeb118bf554512507fc498f1c0f5bd929a665b3f57
parentgpgsm: Cache the non-existence of the policy file. (diff)
downloadgnupg-30f1eda7d8c0459735739ecaa999364ead72c297.tar.gz
gnupg-30f1eda7d8c0459735739ecaa999364ead72c297.zip
kbx: Improve keybox_set_flags
* kbx/keybox-defs.h (struct keybox_handle): Add update_mode flag. * kbx/keybox-init.c (_keybox_close_file): Clear update_mode flag. * kbx/keybox-update.c (keybox_set_flags): Avoid a second file handle but make use of the update mode. -- This is mostly useful for gpgsm because it updates some flags in the keyring quite often. Avoiding extra CreateFile calls may help to speed up things in case malware^Dantivirus software is slowing down a Windows system. The locking pattern also change, thus there is some regression risk due to this patch.
-rw-r--r--kbx/keybox-defs.h1
-rw-r--r--kbx/keybox-init.c1
-rw-r--r--kbx/keybox-update.c24
3 files changed, 21 insertions, 5 deletions
diff --git a/kbx/keybox-defs.h b/kbx/keybox-defs.h
index 51ba8cd0e..32622a632 100644
--- a/kbx/keybox-defs.h
+++ b/kbx/keybox-defs.h
@@ -77,6 +77,7 @@ struct keybox_handle {
KB_NAME kb;
int secret; /* this is for a secret keybox */
estream_t fp;
+ int update_mode; /* FP is in update mode ("r+b"). */
int eof;
int error;
int ephemeral;
diff --git a/kbx/keybox-init.c b/kbx/keybox-init.c
index 48af5c7a1..a5b7baec0 100644
--- a/kbx/keybox-init.c
+++ b/kbx/keybox-init.c
@@ -255,6 +255,7 @@ _keybox_close_file (KEYBOX_HANDLE hd)
{
es_fclose (roverhd->fp);
roverhd->fp = NULL;
+ roverhd->update_mode = 0;
}
}
log_assert (!hd->fp);
diff --git a/kbx/keybox-update.c b/kbx/keybox-update.c
index 273265635..fd37ee5b3 100644
--- a/kbx/keybox-update.c
+++ b/kbx/keybox-update.c
@@ -509,6 +509,7 @@ keybox_set_flags (KEYBOX_HANDLE hd, int what, int idx, unsigned int value)
size_t flag_pos, flag_size;
const unsigned char *buffer;
size_t length;
+ gpgrt_off_t save_off;
(void)idx; /* Not yet used. */
@@ -535,11 +536,18 @@ keybox_set_flags (KEYBOX_HANDLE hd, int what, int idx, unsigned int value)
off += flag_pos;
- _keybox_close_file (hd);
- fp = es_fopen (hd->kb->fname, "r+b");
- if (!fp)
- return gpg_error_from_syserror ();
+ if (!hd->fp || !hd->update_mode)
+ {
+ _keybox_close_file (hd);
+ fp = es_fopen (hd->kb->fname, "r+b");
+ if (!fp)
+ return gpg_error_from_syserror ();
+ hd->update_mode = 1;
+ }
+ else
+ fp = hd->fp;
+ save_off = es_ftello (fp);
ec = 0;
if (es_fseeko (fp, off, SEEK_SET))
ec = gpg_err_code_from_syserror ();
@@ -566,12 +574,18 @@ keybox_set_flags (KEYBOX_HANDLE hd, int what, int idx, unsigned int value)
}
}
- if (es_fclose (fp))
+ if (es_fflush (fp))
{
if (!ec)
ec = gpg_err_code_from_syserror ();
}
+ /* Get back to the last offset or close the file on error. */
+ if (save_off == (gpgrt_off_t)(-1) || es_fseeko (fp, save_off, SEEK_SET))
+ {
+ _keybox_close_file (hd);
+ }
+
return gpg_error (ec);
}