[pve-devel] [RFC PATCH common] Tools: tempfile and tempfile_contents

Wolfgang Bumiller w.bumiller at proxmox.com
Mon Apr 4 14:43:56 CEST 2016


---
This might be useful for the ssh-key code: since ssh-keygen apparently
needs seekable files (iow. doesn't work with pipes) we need a place
to temporarily store keys. This code currently is a bit more flexible
than necessary - the basic usage is as follows:

my ($filename, $handle) = tempfile_contents($my_data);

As long as the $handle exists the file will be accessible.
The $filename points to `/proc/$PID/fd/$fileno`. It is never linked
into the file system (and cannot be unless the allow_links option is
set.)

 src/PVE/Tools.pm | 34 +++++++++++++++++++++++++++++++++-
 1 file changed, 33 insertions(+), 1 deletion(-)

diff --git a/src/PVE/Tools.pm b/src/PVE/Tools.pm
index d6b501e..40dfc5a 100644
--- a/src/PVE/Tools.pm
+++ b/src/PVE/Tools.pm
@@ -75,7 +75,8 @@ use constant {CLONE_NEWNS   => 0x00020000,
               CLONE_NEWPID  => 0x20000000,
               CLONE_NEWNET  => 0x40000000};
 
-use constant O_PATH => 0x00200000;
+use constant {O_PATH    => 0x00200000,
+              O_TMPFILE => 0x00410000}; # This includes O_DIRECTORY
 
 sub run_with_timeout {
     my ($timeout, $code, @param) = @_;
@@ -1213,4 +1214,35 @@ sub sync_mountpoint {
     return $result;
 }
 
+sub tempfile {
+    my ($perm, %opts) = @_;
+
+    # default permissions are stricter than with file_set_contents
+    $perm = 0600 if !defined($perm);
+
+    my $dir = $opts{dir} // '/tmp';
+    my $mode = $opts{mode} // O_RDWR;
+    $mode |= O_EXCL if !$opts{allow_links};
+
+    my $fh = IO::File->new($dir, $mode | O_TMPFILE, $perm)
+	or die "failed to create tempfile: $!\n";
+    return $fh;
+}
+
+sub tempfile_contents {
+    my ($data, $perm, %opts) = @_;
+
+    my $fh = tempfile($perm, %opts);
+    eval {
+	die "unable to write to tempfile: $!\n" if !print {$fh} $data;
+	die "unable to flush to tempfile: $!\n" if !defined($fh->flush());
+    };
+    if (my $err = $@) {
+	close $fh;
+	die $err;
+    }
+
+    return ("/proc/$$/fd/".$fh->fileno, $fh);
+}
+
 1;
-- 
2.1.4




More information about the pve-devel mailing list