—package
File::Util::Tempdir;
our
$DATE
=
'2018-09-22'
;
# DATE
our
$VERSION
=
'0.034'
;
# VERSION
use
strict;
use
warnings;
our
@EXPORT_OK
=
qw(get_tempdir get_user_tempdir)
;
sub
get_tempdir {
if
($^O eq
'MSWin32'
) {
for
(
qw/TMP TEMP TMPDIR TEMPDIR/
) {
return
$ENV
{
$_
}
if
defined
$ENV
{
$_
};
}
for
(
"C:\\TMP"
,
"C:\\TEMP"
) {
return
$_
if
-d;
}
}
else
{
for
(
qw/TMPDIR TEMPDIR TMP TEMP/
) {
return
$ENV
{
$_
}
if
defined
$ENV
{
$_
};
}
for
(
"/tmp"
,
"/var/tmp"
) {
return
$_
if
-d;
}
}
die
"Can't find any temporary directory"
;
}
sub
get_user_tempdir {
if
($^O eq
'MSWin32'
) {
return
get_tempdir();
}
else
{
my
$dir
=
$ENV
{XDG_RUNTIME_DIR} ?
$ENV
{XDG_RUNTIME_DIR} : get_tempdir();
my
@st
=
stat
(
$dir
);
die
"Can't stat tempdir '$dir': $!"
unless
@st
;
return
$dir
if
$st
[4] == $> && !(
$st
[2] & 022);
my
$i
= 0;
while
(1) {
my
$subdir
=
"$dir/$>"
. (
$i
?
".$i"
:
""
);
my
@stsub
=
stat
(
$subdir
);
my
$is_dir
= -d _;
if
(!
@stsub
) {
mkdir
$subdir
, 0700 or
die
"Can't mkdir '$subdir': $!"
;
return
$subdir
;
}
elsif
(
$is_dir
&&
$stsub
[4] == $> && !(
$stsub
[2] & 022)) {
return
$subdir
;
}
else
{
$i
++;
}
}
}
}
1;
# ABSTRACT: Cross-platform way to get system-wide & user private temporary directory
__END__
=pod
=encoding UTF-8
=head1 NAME
File::Util::Tempdir - Cross-platform way to get system-wide & user private temporary directory
=head1 VERSION
This document describes version 0.034 of File::Util::Tempdir (from Perl distribution File-Util-Tempdir), released on 2018-09-22.
=head1 SYNOPSIS
use File::Util::Tempdir qw(get_tempdir get_user_tempdir);
my $tmpdir = get_tempdir(); # => e.g. "/tmp"
my $mytmpdir = get_user_tempdir(); # => e.g. "/run/user/1000", or "/tmp/1000"
=head1 DESCRIPTION
=head1 FUNCTIONS
None are exported by default, but they are exportable.
=head2 get_tempdir
Usage:
my $dir = get_tempdir();
A cross-platform way to get system-wide temporary directory.
On Windows: it first looks for one of these environment variables in this order
and return the first value that is set: C<TMP>, C<TEMP>, C<TMPDIR>, C<TEMPDIR>.
If none are set, will look at these directories in this order and return the
first value that is set: C<C:\TMP>, C<C:\TEMP>. If none are set, will die.
On Unix: it first looks for one of these environment variables in this order and
return the first value that is set: C<TMPDIR>, C<TEMPDIR>, C<TMP>, C<TEMP>. If
none are set, will look at these directories in this order and return the first
value that is set: C</tmp>, C</var/tmp>. If none are set, will die.
=head2 get_user_tempdir
Usage:
my $dir = get_user_tempdir();
Get user's private temporary directory.
When you use world-writable temporary directory like F</tmp>, you usually need
to create randomly named temporary files, such as those created by
L<File::Temp>. If you try to create a temporary file with guessable name, other
users can intercept this and you can either: 1) fail to create/write your
temporary file; 2) be tricked to read malicious data; 3) be tricked to write to
other location (e.g. via symlink).
This routine is like L</"get_tempdir"> except: on Unix, it will look for
C<XDG_RUNTIME_DIR> first (which on a Linux system with systemd will have value
like C</run/user/1000> which points to a RAM-based tmpfs). Also,
C<get_user_tempdir> will first check that the temporary directory is: 1) owned
by the running user; 2) not group- and world-writable. If not, it will create a
subdirectory named C<$EUID> (C<< $> >>) with permission mode 0700 and return
that. If that subdirectory already exists and is not owned by the user or is
group-/world-writable, will try C<$EUID.1> and so on.
It will die on failure.
=head1 HOMEPAGE
Please visit the project's homepage at L<https://metacpan.org/release/File-Util-Tempdir>.
=head1 SOURCE
Source repository is at L<https://github.com/perlancar/perl-File-Util-Tempdir>.
=head1 BUGS
Please report any bugs or feature requests on the bugtracker website L<https://rt.cpan.org/Public/Dist/Display.html?Name=File-Util-Tempdir>
When submitting a bug or request, please include a test-file or a
patch to an existing test-file that illustrates the bug or desired
feature.
=head1 SEE ALSO
L<File::Spec> has C<tmpdir> function. It also tries to look at environment
variables, e.g. on Unix it will look at C<TMPDIR> (but not C<TEMPDIR>) and
then falls back to C</tmp> (but not C</var/tmp>).
L<File::HomeDir>, a cross-platform way to get user's home directory and a few
other related directories.
L<File::Temp> to create a temporary directory.
for the specification of C<XDG_RUNTIME_DIR>.
=head1 AUTHOR
perlancar <perlancar@cpan.org>
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2018, 2016 by perlancar@cpan.org.
This is free software; you can redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself.
=cut