1# ex:ts=8 sw=4: 2# $OpenBSD: Temp.pm,v 1.14 2009/04/19 14:58:32 espie Exp $ 3# 4# Copyright (c) 2003-2005 Marc Espie <espie@openbsd.org> 5# 6# Permission to use, copy, modify, and distribute this software for any 7# purpose with or without fee is hereby granted, provided that the above 8# copyright notice and this permission notice appear in all copies. 9# 10# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 18use strict; 19use warnings; 20package OpenBSD::Temp; 21 22use File::Temp; 23use OpenBSD::Paths; 24 25our $tempbase = $ENV{'PKG_TMPDIR'} || OpenBSD::Paths->vartmp; 26 27my $dirs = {}; 28my $files = {}; 29 30sub cleanup 31{ 32 my $caught; 33 my $h = sub { $caught = shift; }; 34 { 35 require File::Path; 36 37 local $SIG{'INT'} = $h; 38 local $SIG{'QUIT'} = $h; 39 local $SIG{'HUP'} = $h; 40 local $SIG{'KILL'} = $h; 41 local $SIG{'TERM'} = $h; 42 43 while (my ($name, $pid) = each %$files) { 44 unlink($name) if $pid == $$; 45 } 46 while (my ($dir, $pid) = each %$dirs) { 47 File::Path::rmtree([$dir]) if $pid == $$; 48 } 49 } 50 if (defined $caught) { 51 kill $caught, $$; 52 } 53} 54 55END { 56 cleanup(); 57} 58 59my $handler = sub { 60 my ($sig) = @_; 61 cleanup(); 62 $SIG{$sig} = 'DEFAULT'; 63 kill $sig, $$; 64}; 65 66$SIG{'INT'} = $handler; 67$SIG{'QUIT'} = $handler; 68$SIG{'HUP'} = $handler; 69$SIG{'KILL'} = $handler; 70$SIG{'TERM'} = $handler; 71 72sub dir 73{ 74 my $caught; 75 my $h = sub { $caught = shift; }; 76 my $dir; 77 78 { 79 local $SIG{'INT'} = $h; 80 local $SIG{'QUIT'} = $h; 81 local $SIG{'HUP'} = $h; 82 local $SIG{'KILL'} = $h; 83 local $SIG{'TERM'} = $h; 84 $dir = permanent_dir($tempbase, "pkginfo"); 85 $dirs->{$dir} = $$; 86 } 87 if (defined $caught) { 88 kill $caught, $$; 89 } 90 return "$dir/"; 91} 92 93sub file 94{ 95 my $caught; 96 my $h = sub { $caught = shift; }; 97 my ($fh, $file); 98 99 { 100 local $SIG{'INT'} = $h; 101 local $SIG{'QUIT'} = $h; 102 local $SIG{'HUP'} = $h; 103 local $SIG{'KILL'} = $h; 104 local $SIG{'TERM'} = $h; 105 ($fh, $file) = permanent_file($tempbase, "pkgout"); 106 $files->{$file} = $$; 107 } 108 if (defined $caught) { 109 kill $caught, $$; 110 } 111 return $file; 112} 113 114sub permanent_file 115{ 116 my ($dir, $stem) = @_; 117 my $template = "$stem.XXXXXXXXXX"; 118 if (defined $dir) { 119 $template = "$dir/$template"; 120 } 121 return File::Temp::mkstemp($template); 122} 123 124sub permanent_dir 125{ 126 my ($dir, $stem) = @_; 127 my $template = "$stem.XXXXXXXXXX"; 128 if (defined $dir) { 129 $template = "$dir/$template"; 130 } 131 return File::Temp::mkdtemp($template); 132} 133 1341; 135