xref: /openbsd/usr.sbin/pkg_add/OpenBSD/Temp.pm (revision 5af055cd)
1# ex:ts=8 sw=4:
2# $OpenBSD: Temp.pm,v 1.27 2015/03/04 13:55: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;
20
21package OpenBSD::Temp;
22
23use OpenBSD::MkTemp;
24use OpenBSD::Paths;
25use OpenBSD::Error;
26
27our $tempbase = $ENV{'PKG_TMPDIR'} || OpenBSD::Paths->vartmp;
28
29my $dirs = {};
30my $files = {};
31
32my $cleanup = sub {
33	while (my ($name, $pid) = each %$files) {
34		unlink($name) if $pid == $$;
35	}
36	while (my ($dir, $pid) = each %$dirs) {
37		OpenBSD::Error->rmtree([$dir]) if $pid == $$;
38	}
39};
40
41END {
42	&$cleanup;
43}
44OpenBSD::Handler->register($cleanup);
45
46sub dir
47{
48	my $caught;
49	my $h = sub { $caught = shift; };
50	my $dir;
51
52	{
53	    local $SIG{'INT'} = $h;
54	    local $SIG{'QUIT'} = $h;
55	    local $SIG{'HUP'} = $h;
56	    local $SIG{'KILL'} = $h;
57	    local $SIG{'TERM'} = $h;
58	    $dir = permanent_dir($tempbase, "pkginfo");
59	    $dirs->{$dir} = $$;
60	}
61	if (defined $caught) {
62		kill $caught, $$;
63	}
64	return "$dir/";
65}
66
67sub file
68{
69	my $caught;
70	my $h = sub { $caught = shift; };
71	my ($fh, $file);
72
73	{
74	    local $SIG{'INT'} = $h;
75	    local $SIG{'QUIT'} = $h;
76	    local $SIG{'HUP'} = $h;
77	    local $SIG{'KILL'} = $h;
78	    local $SIG{'TERM'} = $h;
79	    ($fh, $file) = permanent_file($tempbase, "pkgout");
80	    if (defined $file) {
81		    $files->{$file} = $$;
82	    }
83	}
84	if (defined $caught) {
85		kill $caught, $$;
86	}
87	return $file;
88}
89
90sub reclaim
91{
92	my ($class, $name) = @_;
93	delete $files->{$name};
94	delete $dirs->{$name};
95}
96
97sub permanent_file
98{
99	my ($dir, $stem) = @_;
100	my $template = "$stem.XXXXXXXXXX";
101	if (defined $dir) {
102		$template = "$dir/$template";
103	}
104	return OpenBSD::MkTemp::mkstemp($template);
105}
106
107sub permanent_dir
108{
109	my ($dir, $stem) = @_;
110	my $template = "$stem.XXXXXXXXXX";
111	if (defined $dir) {
112		$template = "$dir/$template";
113	}
114	return OpenBSD::MkTemp::mkdtemp($template);
115}
116
1171;
118