The Perl Toolchain Summit 2025 Needs You: You can help 🙏 Learn more

our $DATE = '2018-09-22'; # DATE
our $VERSION = '0.034'; # VERSION
use strict;
use Exporter qw(import);
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
=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