]> Dogcows Code - chaz/p5-File-KDBX/blobdiff - lib/File/KDBX/Key/File.pm
Don't open already-open files on Windows
[chaz/p5-File-KDBX] / lib / File / KDBX / Key / File.pm
index 5949d4c8afa2ea3147de65bd3a869cd1fbfd909e..0b6093f985771182f1d9f048f695223c39e27f99 100644 (file)
@@ -9,16 +9,46 @@ use Crypt::Misc 0.029 qw(decode_b64 encode_b64);
 use Crypt::PRNG qw(random_bytes);
 use File::KDBX::Constants qw(:key_file);
 use File::KDBX::Error;
-use File::KDBX::Util qw(:erase trim);
+use File::KDBX::Util qw(:class :erase trim);
 use Ref::Util qw(is_ref is_scalarref);
 use Scalar::Util qw(openhandle);
 use XML::LibXML::Reader;
 use namespace::clean;
 
-use parent 'File::KDBX::Key';
+extends 'File::KDBX::Key';
 
 our $VERSION = '999.999'; # VERSION
 
+=attr type
+
+    $type = $key->type;
+
+Get the type of key file. Can be one of from L<File::KDBX::Constants/":key_file">:
+
+=for :list
+* C<KEY_FILE_TYPE_BINARY>
+* C<KEY_FILE_TYPE_HEX>
+* C<KEY_FILE_TYPE_XML>
+* C<KEY_FILE_TYPE_HASHED>
+
+=attr version
+
+    $version = $key->version;
+
+Get the file version. Only applies to XML key files.
+
+=attr filepath
+
+    $filepath = $key->filepath;
+
+Get the filepath to the key file, if known.
+
+=cut
+
+has 'type',     is => 'ro';
+has 'version',  is => 'ro';
+has 'filepath', is => 'ro';
+
 =method load
 
     $key = $key->load($filepath);
@@ -97,42 +127,6 @@ sub reload {
     return $self;
 }
 
-=attr type
-
-    $type = $key->type;
-
-Get the type of key file. Can be one of:
-
-=for :list
-* C<KEY_FILE_TYPE_BINARY>
-* C<KEY_FILE_TYPE_HEX>
-* C<KEY_FILE_TYPE_XML>
-* C<KEY_FILE_TYPE_HASHED>
-
-=cut
-
-sub type { $_[0]->{type} }
-
-=attr version
-
-    $version = $key->version;
-
-Get the file version. Only applies to XML key files.
-
-=cut
-
-sub version { $_[0]->{version} }
-
-=attr filepath
-
-    $filepath = $key->filepath;
-
-Get the filepath to the key file, if known.
-
-=cut
-
-sub filepath { $_[0]->{filepath} }
-
 =method save
 
     $key->save;
@@ -146,6 +140,7 @@ Write a key file. Available options:
 * C<filepath> - Where to save the file (default: value of L</filepath>)
 * C<fh> - IO handle to write to (overrides C<filepath>, one of which must be defined)
 * C<raw_key> - Raw key (default: value of L</raw_key>)
+* C<atomic> - Write to the filepath atomically (default: true)
 
 =cut
 
@@ -162,18 +157,24 @@ sub save {
     my $version     = $args{version} // $self->version // 2;
     my $filepath    = $args{filepath} // $self->filepath;
     my $fh          = $args{fh};
+    my $atomic      = $args{atomic} // 1;
 
     my $filepath_temp;
     if (!openhandle($fh)) {
         $filepath or throw 'Must specify where to safe the key file to';
 
-        require File::Temp;
-        ($fh, $filepath_temp) = eval { File::Temp::tempfile("${filepath}-XXXXXX", CLEANUP => 1) };
-        if (!$fh or my $err = $@) {
-            $err //= 'Unknown error';
-            throw sprintf('Open file failed (%s): %s', $filepath_temp, $err),
-                error       => $err,
-                filepath    => $filepath_temp;
+        if ($atomic) {
+            require File::Temp;
+            ($fh, $filepath_temp) = eval { File::Temp::tempfile("${filepath}-XXXXXX", UNLINK => 1) };
+            if (!$fh or my $err = $@) {
+                $err //= 'Unknown error';
+                throw sprintf('Open file failed (%s): %s', $filepath_temp, $err),
+                    error       => $err,
+                    filepath    => $filepath_temp;
+            }
+        }
+        else {
+            open($fh, '>:raw', $filepath) or throw "Open file failed ($filepath): $!", filepath => $filepath;
         }
     }
 
This page took 0.031674 seconds and 4 git commands to generate.