Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add WRITE_ONLY option to open temp file with O_WRONLY #28

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Changes
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
{{$NEXT}}
- add AppVeyor CI
- Add PERMS options to create temp file with given file permissions
- Document exportable functions, constants and :tags
- Add WRITE_ONLY option to open temp file with O_WRONLY

0.2309 2019-01-06 20:29:15Z
- fix longstanding pod formatting error (issue #19, RT#109526)
Expand Down
67 changes: 65 additions & 2 deletions lib/File/Temp.pm
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,7 @@ my %FILES_CREATED_BY_OBJECT;
# Usually irrelevant on unix
# "use_exlock" => Indicates that O_EXLOCK should be used. Default is false.
# "file_permissions" => file permissions for sysopen(). Default is 0600.
# "write_only" => Indicates that O_WRONLY should be used. Default is false.

# Optionally a reference to a scalar can be passed into the function
# On error this will be used to store the reason for the error
Expand Down Expand Up @@ -506,13 +507,16 @@ sub _gettemp {
# Attempt to open the file
my $open_success = undef;
if ( $^O eq 'VMS' and $options{"unlink_on_close"} && !$KEEP_ALL) {
my $flags = $OPENFLAGS;
$flags = ($flags & ~O_RDWR) | O_WRONLY if $options{write_only};
# make it auto delete on close by setting FAB$V_DLT bit
$fh = VMS::Stdio::vmssysopen($path, $OPENFLAGS, $perms, 'fop=dlt');
$fh = VMS::Stdio::vmssysopen($path, $flags, $perms, 'fop=dlt');
$open_success = $fh;
} else {
my $flags = ( ($options{"unlink_on_close"} && !$KEEP_ALL) ?
$OPENTEMPFLAGS :
$OPENFLAGS );
$flags = ($flags & ~O_RDWR) | O_WRONLY if $options{write_only};
$flags |= $LOCKFLAG if (defined $LOCKFLAG && $options{use_exlock});
$open_success = sysopen($fh, $path, $flags, $perms);
}
Expand Down Expand Up @@ -1053,7 +1057,7 @@ that the temporary file is removed by the object destructor
if UNLINK is set to true (the default).

Supported arguments are the same as for C<tempfile>: UNLINK
(defaulting to true), DIR, EXLOCK, PERMS and SUFFIX.
(defaulting to true), DIR, EXLOCK, PERMS, WRITE_ONLY and SUFFIX.
Additionally, the filename
template is specified using the TEMPLATE option. The OPEN option
is not supported (the file is always opened).
Expand Down Expand Up @@ -1370,6 +1374,11 @@ Use C<PERMS> to change this:

($fh, $filename) = tempfile($template, PERMS => 0666);

Normally, the temporary filehandle is opened for both reading
and writing. To open for writing only, use C<WRITE_ONLY>.

($fh, $filename) = tempfile($template, WRITE_ONLY => 1);

Options can be combined as required.

Will croak() if there is an error.
Expand All @@ -1384,6 +1393,8 @@ EXLOCK flag available since 0.19.

PERMS flag available since 0.24.

WRITE_ONLY flag available since 0.24.

=cut

sub tempfile {
Expand All @@ -1402,6 +1413,7 @@ sub tempfile {
"TMPDIR" => 0, # Place tempfile in tempdir if template specified
"EXLOCK" => 0, # Open file with O_EXLOCK
"PERMS" => undef, # File permissions
"WRITE_ONLY" => 0, # Open file with O_WRONLY
);

# Check to see whether we have an odd or even number of arguments
Expand Down Expand Up @@ -1485,6 +1497,7 @@ sub tempfile {
"ErrStr" => \$errstr,
"use_exlock" => $options{EXLOCK},
"file_permissions" => $options{PERMS},
"write_only" => $options{WRITE_ONLY},
) );

# Set up an exit handler that can do whatever is right for the
Expand Down Expand Up @@ -2333,6 +2346,56 @@ Current API available since 0.15.

=back

=head1 EXPORTS

These functions are not exported by default but may be exported
individually:

tempfile
tempdir
unlink0
cleanup

The functions and constants in these export tags are exported by
default:

=over

=item :POSIX

Exports the L<POSIX functions|"POSIX FUNCTIONS">:

tmpnam
tmpfile

=item :mktemp

Exports the L<mktemp functions|"MKTEMP FUNCTIONS">:

mktemp
mkstemp
mkstemps
mkdtemp

=item :seekable

Exports the seek constants:

SEEK_SET
SEEK_CUR
SEEK_END

=back

So these two are equivalent:

use File::Temp;
use File::Temp qw/ :POSIX :mktemp :seekable /;

Use an empty list to export nothing:

use File::Temp ();

=head1 PACKAGE VARIABLES

These functions control the global state of the package.
Expand Down
32 changes: 30 additions & 2 deletions t/tempfile.t
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# Test for File::Temp - tempfile function

use strict;
use Test::More tests => 30;
use Test::More tests => 35;
use File::Spec;
use Cwd qw/ cwd /;

Expand Down Expand Up @@ -95,8 +95,36 @@ push(@files, File::Spec->rel2abs($tempfile));
DIR => $tempdir,
);


ok( (-f $tempfile ), "Local tempfile in tempdir exists");
{
# Catch warning when reading from write-only filehandle
# or writing to read-only filehandle.
my $e;
local $SIG{__WARN__} = sub { $e++ };
print $fh 42;
<$fh>;
ok( !$e, "...and filehandle opened for reading and writing" );
}
push(@files, File::Spec->rel2abs($tempfile));

# Test tempfile
# ..and write-only this time
($fh, $tempfile) = tempfile(
DIR => $tempdir,
WRITE_ONLY => 1,
);

ok( (-f $tempfile ), "Local WRITE_ONLY tempfile in tempdir exists");
{
# Catch warning when reading from write-only filehandle
# or writing to read-only filehandle.
my $e;
local $SIG{__WARN__} = sub { $e++ };
print $fh 42;
ok( !$e, "...and filehandle opened for writing" );
<$fh>;
ok( $e, "...but not reading" );
}
push(@files, File::Spec->rel2abs($tempfile));

# Test tempfile
Expand Down