The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

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 -inplace 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.