NAME
clobber - pragma to optionally prevent over-writing files
SYNOPSIS
BEGIN{ no clobber }
#These fail if /tmp/xyzzy exists
open(HNDL, '> /tmp/xyzzy');
# open(HNDL, '>', /tmp/xyzzy');
#sysopen(HNDL, '/tmp/xyzzy', O_WRONLY|O_CREAT);
#It's clobberin' time
do{
use clobber; open(HNDL, '>/tmp/xyzzy');
}
DESCRIPTION
Do you occasionally get +> and +< mixed up, or accidentally leave off an > in the mode of an open
? Want to run some relatively trustworthy code--such as some spaghetti monster you created in the days of yore--but can't be bothered to check it's semantics? Or perhaps you'd like to add a level of protection to operations on user-supplied files without coding the logic yourself.
Yes? Then this pragma could help you from blowing away valuable data, similar to the noclobber variable of some shells or -i option of mv
. This behavior can be controlled at the block level, as demonstrated in the "SYNOPSIS".
All modes restrict rename
to mimic the -i option of mv
.
If a backup extension is not supplied for perl's -i
nplace edit mode, it is set to ~
The protections afforded to open
and <sysopen> are configurable:
Default protection
This includes modes that truncate or allow modification of data.
open
-
> | +> | +<
sysopen
-
O_WRONLY | O_RDWR | O_TRUNC
Lax protection
This only includes modes that explicitly truncate.
open
-
> | +>
sysopen
-
O_TRUNC
You may loosen clobber's reigns by passing :lax to (un)import, for a usage similar similar to strict:
no clobber;
...
{
use clobber ':lax';
...
}
DIAGNOSTICS
The pragma may throw the following exceptions:
- %s: File exists
-
We saved data!
- Failed to parse EXPR of 2-arg open: %s
-
The pragma could not figure out what mode was used, and decided to bail for safety.
This shouldn't happen.
ENVIRONMENT
You may disable clobber protection at compile-time by setting the environment variable clobber.pm to 1. This allows you to include clobber.pm in PERL5OPT as -M-clobber for general protection, but override it as needed for programs invoked via a pipeline.
CAVEATS
As noted in the "DESCRIPTION", this is meant to be used with code which is generally believed to be safe, and is a layer of protection against human error, not malicious intent. I know it could have prevented many 1-liner-enabled, self-inflicted gunshot wounds of the foot in the past.
Any number of other actions could result in data loss including the invocation of external programs via pipe-opens
, qx
, or system
(with or without shell redirection) and calls to fuctions implemented in XS.
NOTES
Requires Perl 5.6 or higher. the basic premise could be implemented in 5.005, but we translate (nearly) every 2-arg open to 3-arg for 'simplicity'/safety/shits-n-giggles; the exceptions are dups and fdopens for Perl 5.6, where 3-arg open doesn't grok these modes.
TODO
- Tests
-
If interactive ask to run the more complex tests, with timeout to skip the initial query.
- :quiet mode to continue despite failed command?
-
Not by default. Other bad things may happen if a filehandle is not available, but file renaming may be okay. Should it threfore default to carp?
- wrap other data-damaging functions in a :strict mode?
-
e.g; truncate, unlink, and calls to external commands.
AUTHOR
Jerrad Pierce <JPIERCE circle-a CPAN full-stop ORG>
LICENSE
Thou shalt not claim ownership of unmodified materials.
Thou shalt not claim whole ownership of modified materials.
Thou shalt grant the indemnity of the provider of materials.
Thou shalt use and dispense freely without other restrictions.
Or, if you prefer:
This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself, either Perl version 5.0 or, at your option, any later version of Perl 5 you may have available.