diff options
Diffstat (limited to 'lib/Temp/File-Temp-0.12')
-rw-r--r-- | lib/Temp/File-Temp-0.12/ChangeLog | 143 | ||||
-rw-r--r-- | lib/Temp/File-Temp-0.12/MANIFEST | 11 | ||||
-rw-r--r-- | lib/Temp/File-Temp-0.12/Makefile | 734 | ||||
-rw-r--r-- | lib/Temp/File-Temp-0.12/Makefile.PL | 17 | ||||
-rw-r--r-- | lib/Temp/File-Temp-0.12/README | 161 | ||||
-rw-r--r-- | lib/Temp/File-Temp-0.12/Temp.pm | 1863 | ||||
-rw-r--r-- | lib/Temp/File-Temp-0.12/blib/arch/auto/File/Temp/.exists | 0 | ||||
-rw-r--r-- | lib/Temp/File-Temp-0.12/blib/lib/auto/File/Temp/.exists | 0 | ||||
-rw-r--r-- | lib/Temp/File-Temp-0.12/blib/man3/.exists | 0 | ||||
-rw-r--r-- | lib/Temp/File-Temp-0.12/blib/man3/File::Temp.3pm | 681 | ||||
-rwxr-xr-x | lib/Temp/File-Temp-0.12/misc/benchmark.pl | 42 | ||||
-rw-r--r-- | lib/Temp/File-Temp-0.12/misc/results.txt | 33 | ||||
-rw-r--r-- | lib/Temp/File-Temp-0.12/pm_to_blib | 0 | ||||
-rwxr-xr-x | lib/Temp/File-Temp-0.12/t/mktemp.t | 110 | ||||
-rwxr-xr-x | lib/Temp/File-Temp-0.12/t/posix.t | 77 | ||||
-rwxr-xr-x | lib/Temp/File-Temp-0.12/t/security.t | 136 | ||||
-rw-r--r-- | lib/Temp/File-Temp-0.12/t/tempfile.t | 140 |
17 files changed, 4148 insertions, 0 deletions
diff --git a/lib/Temp/File-Temp-0.12/ChangeLog b/lib/Temp/File-Temp-0.12/ChangeLog new file mode 100644 index 0000000..1b716ca --- /dev/null +++ b/lib/Temp/File-Temp-0.12/ChangeLog @@ -0,0 +1,143 @@ +2001-02-22 Tim Jenness <timj@jach.hawaii.edu> + + --- RELEASE V0.12 --- + + * t/posix.t: The unlink0 tests now skip on failure + + * t/mktemp.t: The unlink0 tests now skip on failure + + * Temp.pm (tmpfile): tmpfile returns undef on failure rather than + croaking. + +2001-02-21 Timothy Jenness <t.jenness@jach.hawaii.edu> + + * Temp.pm: + -Add fix for CGI::Carp + [Thanks to John Labovitz <johnl@valiha.inside.sealabs.com>] + - Use error string to propogate reason rather than a carp + +2000-11-24 Tim Jenness <timj@jach.hawaii.edu> + + --- RELEASE V0.11 ---- + + * t/tempfile.t: Add a test to make sure the file is present after + close and another to use tempfile in a scalar context. + + * Temp.pm: Fix bug on NT with O_TEMPORARY causing the file to be + removed before the program exits. + + ---- RELEASE V0.10 ---- + + * Temp.pm: Incorporate fixes up to bleedperl 7825. Cross platform + fixes. + + * t/security.t: Incorporate fixes from bleedperl 7825 - adds more + cross platform support and more skips on the basis that this is + not testing your system security, just the module. + +2000-08-16 Tim Jenness <timj@jach.hawaii.edu> + + * Temp.pm (_gettemp): Dont use VMS::Stdio if we want the file + to remain after closing. + +2000-08-15 Tim Jenness <timj@jach.hawaii.edu> + + * Temp.pm (_can_do_level): cygwin patch + +2000-08-14 Tim Jenness <timj@jach.hawaii.edu> + + * Temp.pm: Add OPENTEMPFLAGS to support UNLINK=>0 + More tweaks to VMS support (now uses VMS::Stdio) + +2000-07-26 Tim Jenness <timj@jach.hawaii.edu> + + * Release V0.09 to CPAN + + * README: Update for V0.09 + +2000-07-25 Tim Jenness <timj@jach.hawaii.edu> + + * t/security.t: OS/2 can not do the security tests. + + * Temp.pm: Add Support for VMS and OS/2 + +2000-05-15 Tim Jenness <timj@jach.hawaii.edu> + + * Release V0.08 to CPAN + + * t/mktemp.t: Skip the test for unlink0 if it fails since in most + cases this indicates an NFS problem. + + * Temp.pm (_can_do_level): Add check to make sure an OS can handle + the required safe level + (safe_level): Check the level can be supported before allowing it + to change + (END): Change order of cleanup so that files are removed ahead of + temp dirs (since files may be in the temp dirs) + +2000-05-08 Tim Jenness <timj@jach.hawaii.edu> + + * Temp.pm: Reorganize END block + + * t/tempfile.t: Correct tests for new position of END{} block + + * t/security.t: Correct tests for new position of END{} block + + * t/posix.t: add # to print output + + * t/tempfile.t: Add # to print output + + * t/mktemp.t: Add # to print output + + * t/security.t: Add # to print output + +2000-04-28 Tim Jenness <timj@jach.hawaii.edu> + + * Temp.pm: Calculate OPENFLAGS outside of subroutine. This + improves speed of the commands by nearly a factor of 3. + (_replace_XX): Inline the character replacement code rather than + using _randchar subroutine. Improves performance by an additional 8%. + +2000-04-27 Tim Jenness <t.jenness@jach.hawaii.edu> + + * t/posix.t: Add explicit autoflush on filehandle + + * t/mktemp.t: Add explicit autoflush on filehandle + + * Temp.pm: (unlink0): Disallow HIGH and MEDIUM tests if running + perl 5.005 or earlier. + + * t/security.t: Specify perl version to allow for tests + + * Add support for perl 5.005 (remove 'our' and auto-vivifying file + handles). VERSION NUMBER NOW 0.07 + + * README: Update in preparation for V0.06 + + * Temp.pm (_deferred_unlink): Add new internal routine to centralise the + configuring of END blocks. This also fixes a bug where only the + first file was being unlinked in the END block (due to scoping). + + (_can_unlink_opened_file): Rename from _can_unlink. Will now + return false if running on Windows. + + (_is_verysafe): If _PC_CHOWN_RESTRICTED is not available assume + that "chown giveaway" is possible anyway. + + (unlink0): If can not unlink an open file, simply defer removal + until later. + + (_gettemp): Add O_NOINHERIT and O_TEMPORARY flags to sysopen if + they are available (Thanks to Tom Christiansen for this) + + * t/mktemp.t: Add test + + * t/posix.t: Add test + + * t/security.t: Add test + + * t/tempfile.t: Add test + +2000-03-14 Tim Jenness <t.jenness@jach.hawaii.edu> + + * Release v0.05 to CPAN diff --git a/lib/Temp/File-Temp-0.12/MANIFEST b/lib/Temp/File-Temp-0.12/MANIFEST new file mode 100644 index 0000000..295d5fb --- /dev/null +++ b/lib/Temp/File-Temp-0.12/MANIFEST @@ -0,0 +1,11 @@ +MANIFEST +Makefile.PL +README +Temp.pm +t/mktemp.t +t/posix.t +t/tempfile.t +t/security.t +ChangeLog +misc/benchmark.pl +misc/results.txt diff --git a/lib/Temp/File-Temp-0.12/Makefile b/lib/Temp/File-Temp-0.12/Makefile new file mode 100644 index 0000000..deb9438 --- /dev/null +++ b/lib/Temp/File-Temp-0.12/Makefile @@ -0,0 +1,734 @@ +# This Makefile is for the File::Temp extension to perl. +# +# It was generated automatically by MakeMaker version +# 6.17 (Revision: 1.133) from the contents of +# Makefile.PL. Don't edit this file, edit Makefile.PL instead. +# +# ANY CHANGES MADE HERE WILL BE LOST! +# +# MakeMaker ARGV: () +# +# MakeMaker Parameters: + +# ABSTRACT_FROM => q[Temp.pm] +# AUTHOR => q[Tim Jenness <t.jenness@jach.hawaii.edu>] +# NAME => q[File::Temp] +# PREREQ_PM => { Fcntl=>q[1.03], File::Spec=>q[0.8], File::Path=>undef } +# VERSION_FROM => q[Temp.pm] +# dist => { COMPRESS=>q[gzip -9f] } + +# --- MakeMaker post_initialize section: + + +# --- MakeMaker const_config section: + +# These definitions are from config.sh (via /usr/lib/perl5/5.8.5/i686-linux/Config.pm) + +# They may have been overridden via Makefile.PL or on the command line +AR = ar +CC = gcc +CCCDLFLAGS = -fPIC +CCDLFLAGS = -rdynamic +DLEXT = so +DLSRC = dl_dlopen.xs +LD = gcc +LDDLFLAGS = -shared -L/usr/local/lib +LDFLAGS = -L/usr/local/lib +LIBC = /lib/libc-2.3.4.so +LIB_EXT = .a +OBJ_EXT = .o +OSNAME = linux +OSVERS = 2.6.10-gentoo-r4 +RANLIB = : +SITELIBEXP = /usr/lib/perl5/site_perl/5.8.5 +SITEARCHEXP = /usr/lib/perl5/site_perl/5.8.5/i686-linux +SO = so +EXE_EXT = +FULL_AR = /usr/bin/ar +VENDORARCHEXP = /usr/lib/perl5/vendor_perl/5.8.5/i686-linux +VENDORLIBEXP = /usr/lib/perl5/vendor_perl/5.8.5 + + +# --- MakeMaker constants section: +AR_STATIC_ARGS = cr +DIRFILESEP = / +NAME = File::Temp +NAME_SYM = File_Temp +VERSION = 0.12 +VERSION_MACRO = VERSION +VERSION_SYM = 0_12 +DEFINE_VERSION = -D$(VERSION_MACRO)=\"$(VERSION)\" +XS_VERSION = 0.12 +XS_VERSION_MACRO = XS_VERSION +XS_DEFINE_VERSION = -D$(XS_VERSION_MACRO)=\"$(XS_VERSION)\" +INST_ARCHLIB = blib/arch +INST_SCRIPT = blib/script +INST_BIN = blib/bin +INST_LIB = blib/lib +INST_MAN1DIR = blib/man1 +INST_MAN3DIR = blib/man3 +MAN1EXT = 1 +MAN3EXT = 3pm +INSTALLDIRS = site +DESTDIR = +PREFIX = +PERLPREFIX = /usr +SITEPREFIX = /usr +VENDORPREFIX = /usr +INSTALLPRIVLIB = $(PERLPREFIX)/lib/perl5/5.8.5 +DESTINSTALLPRIVLIB = $(DESTDIR)$(INSTALLPRIVLIB) +INSTALLSITELIB = $(SITEPREFIX)/lib/perl5/site_perl/5.8.5 +DESTINSTALLSITELIB = $(DESTDIR)$(INSTALLSITELIB) +INSTALLVENDORLIB = $(VENDORPREFIX)/lib/perl5/vendor_perl/5.8.5 +DESTINSTALLVENDORLIB = $(DESTDIR)$(INSTALLVENDORLIB) +INSTALLARCHLIB = $(PERLPREFIX)/lib/perl5/5.8.5/i686-linux +DESTINSTALLARCHLIB = $(DESTDIR)$(INSTALLARCHLIB) +INSTALLSITEARCH = $(SITEPREFIX)/lib/perl5/site_perl/5.8.5/i686-linux +DESTINSTALLSITEARCH = $(DESTDIR)$(INSTALLSITEARCH) +INSTALLVENDORARCH = $(VENDORPREFIX)/lib/perl5/vendor_perl/5.8.5/i686-linux +DESTINSTALLVENDORARCH = $(DESTDIR)$(INSTALLVENDORARCH) +INSTALLBIN = $(PERLPREFIX)/bin +DESTINSTALLBIN = $(DESTDIR)$(INSTALLBIN) +INSTALLSITEBIN = $(SITEPREFIX)/bin +DESTINSTALLSITEBIN = $(DESTDIR)$(INSTALLSITEBIN) +INSTALLVENDORBIN = $(VENDORPREFIX)/bin +DESTINSTALLVENDORBIN = $(DESTDIR)$(INSTALLVENDORBIN) +INSTALLSCRIPT = $(PERLPREFIX)/bin +DESTINSTALLSCRIPT = $(DESTDIR)$(INSTALLSCRIPT) +INSTALLMAN1DIR = $(PERLPREFIX)/share/man/man1 +DESTINSTALLMAN1DIR = $(DESTDIR)$(INSTALLMAN1DIR) +INSTALLSITEMAN1DIR = $(SITEPREFIX)/share/man/man1 +DESTINSTALLSITEMAN1DIR = $(DESTDIR)$(INSTALLSITEMAN1DIR) +INSTALLVENDORMAN1DIR = $(VENDORPREFIX)/share/man/man1 +DESTINSTALLVENDORMAN1DIR = $(DESTDIR)$(INSTALLVENDORMAN1DIR) +INSTALLMAN3DIR = $(PERLPREFIX)/share/man/man3 +DESTINSTALLMAN3DIR = $(DESTDIR)$(INSTALLMAN3DIR) +INSTALLSITEMAN3DIR = $(SITEPREFIX)/share/man/man3 +DESTINSTALLSITEMAN3DIR = $(DESTDIR)$(INSTALLSITEMAN3DIR) +INSTALLVENDORMAN3DIR = $(VENDORPREFIX)/share/man/man3 +DESTINSTALLVENDORMAN3DIR = $(DESTDIR)$(INSTALLVENDORMAN3DIR) +PERL_LIB = /usr/lib/perl5/5.8.5 +PERL_ARCHLIB = /usr/lib/perl5/5.8.5/i686-linux +LIBPERL_A = libperl.a +FIRST_MAKEFILE = Makefile +MAKEFILE_OLD = $(FIRST_MAKEFILE).old +MAKE_APERL_FILE = $(FIRST_MAKEFILE).aperl +PERLMAINCC = $(CC) +PERL_INC = /usr/lib/perl5/5.8.5/i686-linux/CORE +PERL = /usr/bin/perl5.8.5 +FULLPERL = /usr/bin/perl5.8.5 +ABSPERL = $(PERL) +PERLRUN = $(PERL) +FULLPERLRUN = $(FULLPERL) +ABSPERLRUN = $(ABSPERL) +PERLRUNINST = $(PERLRUN) "-I$(INST_ARCHLIB)" "-I$(INST_LIB)" +FULLPERLRUNINST = $(FULLPERLRUN) "-I$(INST_ARCHLIB)" "-I$(INST_LIB)" +ABSPERLRUNINST = $(ABSPERLRUN) "-I$(INST_ARCHLIB)" "-I$(INST_LIB)" +PERL_CORE = 0 +PERM_RW = 644 +PERM_RWX = 755 + +MAKEMAKER = /usr/lib/perl5/5.8.5/ExtUtils/MakeMaker.pm +MM_VERSION = 6.17 +MM_REVISION = 1.133 + +# FULLEXT = Pathname for extension directory (eg Foo/Bar/Oracle). +# BASEEXT = Basename part of FULLEXT. May be just equal FULLEXT. (eg Oracle) +# PARENT_NAME = NAME without BASEEXT and no trailing :: (eg Foo::Bar) +# DLBASE = Basename part of dynamic library. May be just equal BASEEXT. +FULLEXT = File/Temp +BASEEXT = Temp +PARENT_NAME = File +DLBASE = $(BASEEXT) +VERSION_FROM = Temp.pm +OBJECT = +LDFROM = $(OBJECT) +LINKTYPE = dynamic + +# Handy lists of source code files: +XS_FILES = +C_FILES = +O_FILES = +H_FILES = +MAN1PODS = +MAN3PODS = Temp.pm + +# Where is the Config information that we are using/depend on +CONFIGDEP = $(PERL_ARCHLIB)$(DIRFILESEP)Config.pm $(PERL_INC)$(DIRFILESEP)config.h + +# Where to build things +INST_LIBDIR = $(INST_LIB)/File +INST_ARCHLIBDIR = $(INST_ARCHLIB)/File + +INST_AUTODIR = $(INST_LIB)/auto/$(FULLEXT) +INST_ARCHAUTODIR = $(INST_ARCHLIB)/auto/$(FULLEXT) + +INST_STATIC = +INST_DYNAMIC = +INST_BOOT = + +# Extra linker info +EXPORT_LIST = +PERL_ARCHIVE = +PERL_ARCHIVE_AFTER = + + +TO_INST_PM = Temp.pm + +PM_TO_BLIB = Temp.pm \ + $(INST_LIB)/File/Temp.pm + + +# --- MakeMaker platform_constants section: +MM_Unix_VERSION = 1.42 +PERL_MALLOC_DEF = -DPERL_EXTMALLOC_DEF -Dmalloc=Perl_malloc -Dfree=Perl_mfree -Drealloc=Perl_realloc -Dcalloc=Perl_calloc + + +# --- MakeMaker tool_autosplit section: +# Usage: $(AUTOSPLITFILE) FileToSplit AutoDirToSplitInto +AUTOSPLITFILE = $(PERLRUN) -e 'use AutoSplit; autosplit($$ARGV[0], $$ARGV[1], 0, 1, 1)' + + + +# --- MakeMaker tool_xsubpp section: + + +# --- MakeMaker tools_other section: +SHELL = /bin/sh +CHMOD = chmod +CP = cp +MV = mv +NOOP = $(SHELL) -c true +NOECHO = @ +RM_F = rm -f +RM_RF = rm -rf +TEST_F = test -f +TOUCH = touch +UMASK_NULL = umask 0 +DEV_NULL = > /dev/null 2>&1 +MKPATH = $(PERLRUN) "-MExtUtils::Command" -e mkpath +EQUALIZE_TIMESTAMP = $(PERLRUN) "-MExtUtils::Command" -e eqtime +ECHO = echo +ECHO_N = echo -n +UNINST = 0 +VERBINST = 0 +MOD_INSTALL = $(PERLRUN) -MExtUtils::Install -e 'install({@ARGV}, '\''$(VERBINST)'\'', 0, '\''$(UNINST)'\'');' +DOC_INSTALL = $(PERLRUN) "-MExtUtils::Command::MM" -e perllocal_install +UNINSTALL = $(PERLRUN) "-MExtUtils::Command::MM" -e uninstall +WARN_IF_OLD_PACKLIST = $(PERLRUN) "-MExtUtils::Command::MM" -e warn_if_old_packlist + + +# --- MakeMaker makemakerdflt section: +makemakerdflt: all + $(NOECHO) $(NOOP) + + +# --- MakeMaker dist section: +TAR = tar +TARFLAGS = cvf +ZIP = zip +ZIPFLAGS = -r +COMPRESS = gzip -9f +SUFFIX = .gz +SHAR = shar +PREOP = $(NOECHO) $(NOOP) +POSTOP = $(NOECHO) $(NOOP) +TO_UNIX = $(NOECHO) $(NOOP) +CI = ci -u +RCS_LABEL = rcs -Nv$(VERSION_SYM): -q +DIST_CP = best +DIST_DEFAULT = tardist +DISTNAME = File-Temp +DISTVNAME = File-Temp-0.12 + + +# --- MakeMaker macro section: + + +# --- MakeMaker depend section: + + +# --- MakeMaker cflags section: + + +# --- MakeMaker const_loadlibs section: + + +# --- MakeMaker const_cccmd section: + + +# --- MakeMaker post_constants section: + + +# --- MakeMaker pasthru section: + +PASTHRU = LIB="$(LIB)"\ + LIBPERL_A="$(LIBPERL_A)"\ + LINKTYPE="$(LINKTYPE)"\ + PREFIX="$(PREFIX)"\ + OPTIMIZE="$(OPTIMIZE)"\ + PASTHRU_DEFINE="$(PASTHRU_DEFINE)"\ + PASTHRU_INC="$(PASTHRU_INC)" + + +# --- MakeMaker special_targets section: +.SUFFIXES: .xs .c .C .cpp .i .s .cxx .cc $(OBJ_EXT) + +.PHONY: all config static dynamic test linkext manifest + + + +# --- MakeMaker c_o section: + + +# --- MakeMaker xs_c section: + + +# --- MakeMaker xs_o section: + + +# --- MakeMaker top_targets section: +all :: pure_all manifypods + $(NOECHO) $(NOOP) + + +pure_all :: config pm_to_blib subdirs linkext + $(NOECHO) $(NOOP) + +subdirs :: $(MYEXTLIB) + $(NOECHO) $(NOOP) + +config :: $(FIRST_MAKEFILE) $(INST_LIBDIR)$(DIRFILESEP).exists + $(NOECHO) $(NOOP) + +config :: $(INST_ARCHAUTODIR)$(DIRFILESEP).exists + $(NOECHO) $(NOOP) + +config :: $(INST_AUTODIR)$(DIRFILESEP).exists + $(NOECHO) $(NOOP) + +$(INST_AUTODIR)/.exists :: /usr/lib/perl5/5.8.5/i686-linux/CORE/perl.h + $(NOECHO) $(MKPATH) $(INST_AUTODIR) + $(NOECHO) $(EQUALIZE_TIMESTAMP) /usr/lib/perl5/5.8.5/i686-linux/CORE/perl.h $(INST_AUTODIR)/.exists + + -$(NOECHO) $(CHMOD) $(PERM_RWX) $(INST_AUTODIR) + +$(INST_LIBDIR)/.exists :: /usr/lib/perl5/5.8.5/i686-linux/CORE/perl.h + $(NOECHO) $(MKPATH) $(INST_LIBDIR) + $(NOECHO) $(EQUALIZE_TIMESTAMP) /usr/lib/perl5/5.8.5/i686-linux/CORE/perl.h $(INST_LIBDIR)/.exists + + -$(NOECHO) $(CHMOD) $(PERM_RWX) $(INST_LIBDIR) + +$(INST_ARCHAUTODIR)/.exists :: /usr/lib/perl5/5.8.5/i686-linux/CORE/perl.h + $(NOECHO) $(MKPATH) $(INST_ARCHAUTODIR) + $(NOECHO) $(EQUALIZE_TIMESTAMP) /usr/lib/perl5/5.8.5/i686-linux/CORE/perl.h $(INST_ARCHAUTODIR)/.exists + + -$(NOECHO) $(CHMOD) $(PERM_RWX) $(INST_ARCHAUTODIR) + +config :: $(INST_MAN3DIR)$(DIRFILESEP).exists + $(NOECHO) $(NOOP) + + +$(INST_MAN3DIR)/.exists :: /usr/lib/perl5/5.8.5/i686-linux/CORE/perl.h + $(NOECHO) $(MKPATH) $(INST_MAN3DIR) + $(NOECHO) $(EQUALIZE_TIMESTAMP) /usr/lib/perl5/5.8.5/i686-linux/CORE/perl.h $(INST_MAN3DIR)/.exists + + -$(NOECHO) $(CHMOD) $(PERM_RWX) $(INST_MAN3DIR) + +help: + perldoc ExtUtils::MakeMaker + + +# --- MakeMaker linkext section: + +linkext :: $(LINKTYPE) + $(NOECHO) $(NOOP) + + +# --- MakeMaker dlsyms section: + + +# --- MakeMaker dynamic section: + +dynamic :: $(FIRST_MAKEFILE) $(INST_DYNAMIC) $(INST_BOOT) + $(NOECHO) $(NOOP) + + +# --- MakeMaker dynamic_bs section: + +BOOTSTRAP = + + +# --- MakeMaker dynamic_lib section: + + +# --- MakeMaker static section: + +## $(INST_PM) has been moved to the all: target. +## It remains here for awhile to allow for old usage: "make static" +static :: $(FIRST_MAKEFILE) $(INST_STATIC) + $(NOECHO) $(NOOP) + + +# --- MakeMaker static_lib section: + + +# --- MakeMaker manifypods section: + +POD2MAN_EXE = $(PERLRUN) "-MExtUtils::Command::MM" -e pod2man "--" +POD2MAN = $(POD2MAN_EXE) + + +manifypods : pure_all \ + Temp.pm \ + Temp.pm + $(NOECHO) $(POD2MAN) --section=3 --perm_rw=$(PERM_RW)\ + Temp.pm $(INST_MAN3DIR)/File::Temp.$(MAN3EXT) + + + + +# --- MakeMaker processPL section: + + +# --- MakeMaker installbin section: + + +# --- MakeMaker subdirs section: + +# none + +# --- MakeMaker clean_subdirs section: +clean_subdirs : + $(NOECHO) $(NOOP) + + +# --- MakeMaker clean section: + +# Delete temporary files but do not touch installed files. We don't delete +# the Makefile here so a later make realclean still has a makefile to use. + +clean :: clean_subdirs + -$(RM_RF) ./blib $(MAKE_APERL_FILE) $(INST_ARCHAUTODIR)/extralibs.all $(INST_ARCHAUTODIR)/extralibs.ld perlmain.c tmon.out mon.out so_locations pm_to_blib *$(OBJ_EXT) *$(LIB_EXT) perl.exe perl perl$(EXE_EXT) $(BOOTSTRAP) $(BASEEXT).bso $(BASEEXT).def lib$(BASEEXT).def $(BASEEXT).exp $(BASEEXT).x core core.*perl.*.? *perl.core core.[0-9] core.[0-9][0-9] core.[0-9][0-9][0-9] core.[0-9][0-9][0-9][0-9] core.[0-9][0-9][0-9][0-9][0-9] + -$(MV) $(FIRST_MAKEFILE) $(MAKEFILE_OLD) $(DEV_NULL) + + +# --- MakeMaker realclean_subdirs section: +realclean_subdirs : + $(NOECHO) $(NOOP) + + +# --- MakeMaker realclean section: + +# Delete temporary files (via clean) and also delete installed files +realclean purge :: clean realclean_subdirs + $(RM_RF) $(INST_AUTODIR) $(INST_ARCHAUTODIR) + $(RM_RF) $(DISTVNAME) + $(RM_F) $(MAKEFILE_OLD) $(FIRST_MAKEFILE) $(INST_LIB)/File/Temp.pm + + +# --- MakeMaker metafile section: +metafile : + $(NOECHO) $(ECHO) '# http://module-build.sourceforge.net/META-spec.html' > META.yml + $(NOECHO) $(ECHO) '#XXXXXXX This is a prototype!!! It will change in the future!!! XXXXX#' >> META.yml + $(NOECHO) $(ECHO) 'name: File-Temp' >> META.yml + $(NOECHO) $(ECHO) 'version: 0.12' >> META.yml + $(NOECHO) $(ECHO) 'version_from: Temp.pm' >> META.yml + $(NOECHO) $(ECHO) 'installdirs: site' >> META.yml + $(NOECHO) $(ECHO) 'requires:' >> META.yml + $(NOECHO) $(ECHO) ' Fcntl: 1.03' >> META.yml + $(NOECHO) $(ECHO) ' File::Path: ' >> META.yml + $(NOECHO) $(ECHO) ' File::Spec: 0.8' >> META.yml + $(NOECHO) $(ECHO) '' >> META.yml + $(NOECHO) $(ECHO) 'distribution_type: module' >> META.yml + $(NOECHO) $(ECHO) 'generated_by: ExtUtils::MakeMaker version 6.17' >> META.yml + + +# --- MakeMaker metafile_addtomanifest section: +metafile_addtomanifest: + $(NOECHO) $(PERLRUN) -MExtUtils::Manifest=maniadd -e 'eval { maniadd({q{META.yml} => q{Module meta-data (added by MakeMaker)}}) } ' \ + -e ' or print "Could not add META.yml to MANIFEST: $${'\''@'\''}\n"' + + +# --- MakeMaker dist_basics section: +distclean :: realclean distcheck + $(NOECHO) $(NOOP) + +distcheck : + $(PERLRUN) "-MExtUtils::Manifest=fullcheck" -e fullcheck + +skipcheck : + $(PERLRUN) "-MExtUtils::Manifest=skipcheck" -e skipcheck + +manifest : + $(PERLRUN) "-MExtUtils::Manifest=mkmanifest" -e mkmanifest + +veryclean : realclean + $(RM_F) *~ *.orig */*~ */*.orig + + + +# --- MakeMaker dist_core section: + +dist : $(DIST_DEFAULT) $(FIRST_MAKEFILE) + $(NOECHO) $(PERLRUN) -l -e 'print '\''Warning: Makefile possibly out of date with $(VERSION_FROM)'\''' \ + -e ' if -e '\''$(VERSION_FROM)'\'' and -M '\''$(VERSION_FROM)'\'' < -M '\''$(FIRST_MAKEFILE)'\'';' + +tardist : $(DISTVNAME).tar$(SUFFIX) + $(NOECHO) $(NOOP) + +uutardist : $(DISTVNAME).tar$(SUFFIX) + uuencode $(DISTVNAME).tar$(SUFFIX) $(DISTVNAME).tar$(SUFFIX) > $(DISTVNAME).tar$(SUFFIX)_uu + +$(DISTVNAME).tar$(SUFFIX) : distdir + $(PREOP) + $(TO_UNIX) + $(TAR) $(TARFLAGS) $(DISTVNAME).tar $(DISTVNAME) + $(RM_RF) $(DISTVNAME) + $(COMPRESS) $(DISTVNAME).tar + $(POSTOP) + +zipdist : $(DISTVNAME).zip + $(NOECHO) $(NOOP) + +$(DISTVNAME).zip : distdir + $(PREOP) + $(ZIP) $(ZIPFLAGS) $(DISTVNAME).zip $(DISTVNAME) + $(RM_RF) $(DISTVNAME) + $(POSTOP) + +shdist : distdir + $(PREOP) + $(SHAR) $(DISTVNAME) > $(DISTVNAME).shar + $(RM_RF) $(DISTVNAME) + $(POSTOP) + + +# --- MakeMaker distdir section: +distdir : metafile metafile_addtomanifest + $(RM_RF) $(DISTVNAME) + $(PERLRUN) "-MExtUtils::Manifest=manicopy,maniread" \ + -e "manicopy(maniread(),'$(DISTVNAME)', '$(DIST_CP)');" + + + +# --- MakeMaker dist_test section: + +disttest : distdir + cd $(DISTVNAME) && $(ABSPERLRUN) Makefile.PL + cd $(DISTVNAME) && $(MAKE) $(PASTHRU) + cd $(DISTVNAME) && $(MAKE) test $(PASTHRU) + + +# --- MakeMaker dist_ci section: + +ci : + $(PERLRUN) "-MExtUtils::Manifest=maniread" \ + -e "@all = keys %{ maniread() };" \ + -e "print(qq{Executing $(CI) @all\n}); system(qq{$(CI) @all});" \ + -e "print(qq{Executing $(RCS_LABEL) ...\n}); system(qq{$(RCS_LABEL) @all});" + + +# --- MakeMaker install section: + +install :: all pure_install doc_install + +install_perl :: all pure_perl_install doc_perl_install + +install_site :: all pure_site_install doc_site_install + +install_vendor :: all pure_vendor_install doc_vendor_install + +pure_install :: pure_$(INSTALLDIRS)_install + +doc_install :: doc_$(INSTALLDIRS)_install + +pure__install : pure_site_install + $(NOECHO) $(ECHO) INSTALLDIRS not defined, defaulting to INSTALLDIRS=site + +doc__install : doc_site_install + $(NOECHO) $(ECHO) INSTALLDIRS not defined, defaulting to INSTALLDIRS=site + +pure_perl_install :: + $(NOECHO) $(MOD_INSTALL) \ + read $(PERL_ARCHLIB)/auto/$(FULLEXT)/.packlist \ + write $(DESTINSTALLARCHLIB)/auto/$(FULLEXT)/.packlist \ + $(INST_LIB) $(DESTINSTALLPRIVLIB) \ + $(INST_ARCHLIB) $(DESTINSTALLARCHLIB) \ + $(INST_BIN) $(DESTINSTALLBIN) \ + $(INST_SCRIPT) $(DESTINSTALLSCRIPT) \ + $(INST_MAN1DIR) $(DESTINSTALLMAN1DIR) \ + $(INST_MAN3DIR) $(DESTINSTALLMAN3DIR) + $(NOECHO) $(WARN_IF_OLD_PACKLIST) \ + $(SITEARCHEXP)/auto/$(FULLEXT) + + +pure_site_install :: + $(NOECHO) $(MOD_INSTALL) \ + read $(SITEARCHEXP)/auto/$(FULLEXT)/.packlist \ + write $(DESTINSTALLSITEARCH)/auto/$(FULLEXT)/.packlist \ + $(INST_LIB) $(DESTINSTALLSITELIB) \ + $(INST_ARCHLIB) $(DESTINSTALLSITEARCH) \ + $(INST_BIN) $(DESTINSTALLSITEBIN) \ + $(INST_SCRIPT) $(DESTINSTALLSCRIPT) \ + $(INST_MAN1DIR) $(DESTINSTALLSITEMAN1DIR) \ + $(INST_MAN3DIR) $(DESTINSTALLSITEMAN3DIR) + $(NOECHO) $(WARN_IF_OLD_PACKLIST) \ + $(PERL_ARCHLIB)/auto/$(FULLEXT) + +pure_vendor_install :: + $(NOECHO) $(MOD_INSTALL) \ + read $(VENDORARCHEXP)/auto/$(FULLEXT)/.packlist \ + write $(DESTINSTALLVENDORARCH)/auto/$(FULLEXT)/.packlist \ + $(INST_LIB) $(DESTINSTALLVENDORLIB) \ + $(INST_ARCHLIB) $(DESTINSTALLVENDORARCH) \ + $(INST_BIN) $(DESTINSTALLVENDORBIN) \ + $(INST_SCRIPT) $(DESTINSTALLSCRIPT) \ + $(INST_MAN1DIR) $(DESTINSTALLVENDORMAN1DIR) \ + $(INST_MAN3DIR) $(DESTINSTALLVENDORMAN3DIR) + +doc_perl_install :: + $(NOECHO) $(ECHO) Appending installation info to $(DESTINSTALLARCHLIB)/perllocal.pod + -$(NOECHO) $(MKPATH) $(DESTINSTALLARCHLIB) + -$(NOECHO) $(DOC_INSTALL) \ + "Module" "$(NAME)" \ + "installed into" "$(INSTALLPRIVLIB)" \ + LINKTYPE "$(LINKTYPE)" \ + VERSION "$(VERSION)" \ + EXE_FILES "$(EXE_FILES)" \ + >> $(DESTINSTALLARCHLIB)/perllocal.pod + +doc_site_install :: + $(NOECHO) $(ECHO) Appending installation info to $(DESTINSTALLARCHLIB)/perllocal.pod + -$(NOECHO) $(MKPATH) $(DESTINSTALLARCHLIB) + -$(NOECHO) $(DOC_INSTALL) \ + "Module" "$(NAME)" \ + "installed into" "$(INSTALLSITELIB)" \ + LINKTYPE "$(LINKTYPE)" \ + VERSION "$(VERSION)" \ + EXE_FILES "$(EXE_FILES)" \ + >> $(DESTINSTALLARCHLIB)/perllocal.pod + +doc_vendor_install :: + $(NOECHO) $(ECHO) Appending installation info to $(DESTINSTALLARCHLIB)/perllocal.pod + -$(NOECHO) $(MKPATH) $(DESTINSTALLARCHLIB) + -$(NOECHO) $(DOC_INSTALL) \ + "Module" "$(NAME)" \ + "installed into" "$(INSTALLVENDORLIB)" \ + LINKTYPE "$(LINKTYPE)" \ + VERSION "$(VERSION)" \ + EXE_FILES "$(EXE_FILES)" \ + >> $(DESTINSTALLARCHLIB)/perllocal.pod + + +uninstall :: uninstall_from_$(INSTALLDIRS)dirs + +uninstall_from_perldirs :: + $(NOECHO) $(UNINSTALL) $(PERL_ARCHLIB)/auto/$(FULLEXT)/.packlist + +uninstall_from_sitedirs :: + $(NOECHO) $(UNINSTALL) $(SITEARCHEXP)/auto/$(FULLEXT)/.packlist + +uninstall_from_vendordirs :: + $(NOECHO) $(UNINSTALL) $(VENDORARCHEXP)/auto/$(FULLEXT)/.packlist + + +# --- MakeMaker force section: +# Phony target to force checking subdirectories. +FORCE: + $(NOECHO) $(NOOP) + + +# --- MakeMaker perldepend section: + + +# --- MakeMaker makefile section: + +# We take a very conservative approach here, but it's worth it. +# We move Makefile to Makefile.old here to avoid gnu make looping. +$(FIRST_MAKEFILE) : Makefile.PL $(CONFIGDEP) + $(NOECHO) $(ECHO) "Makefile out-of-date with respect to $?" + $(NOECHO) $(ECHO) "Cleaning current config before rebuilding Makefile..." + $(NOECHO) $(RM_F) $(MAKEFILE_OLD) + $(NOECHO) $(MV) $(FIRST_MAKEFILE) $(MAKEFILE_OLD) + -$(MAKE) -f $(MAKEFILE_OLD) clean $(DEV_NULL) || $(NOOP) + $(PERLRUN) Makefile.PL + $(NOECHO) $(ECHO) "==> Your Makefile has been rebuilt. <==" + $(NOECHO) $(ECHO) "==> Please rerun the make command. <==" + false + + + +# --- MakeMaker staticmake section: + +# --- MakeMaker makeaperl section --- +MAP_TARGET = perl +FULLPERL = /usr/bin/perl5.8.5 + +$(MAP_TARGET) :: static $(MAKE_APERL_FILE) + $(MAKE) -f $(MAKE_APERL_FILE) $@ + +$(MAKE_APERL_FILE) : $(FIRST_MAKEFILE) + $(NOECHO) $(ECHO) Writing \"$(MAKE_APERL_FILE)\" for this $(MAP_TARGET) + $(NOECHO) $(PERLRUNINST) \ + Makefile.PL DIR= \ + MAKEFILE=$(MAKE_APERL_FILE) LINKTYPE=static \ + MAKEAPERL=1 NORECURS=1 CCCDLFLAGS= + + +# --- MakeMaker test section: + +TEST_VERBOSE=0 +TEST_TYPE=test_$(LINKTYPE) +TEST_FILE = test.pl +TEST_FILES = t/*.t +TESTDB_SW = -d + +testdb :: testdb_$(LINKTYPE) + +test :: $(TEST_TYPE) + +test_dynamic :: pure_all + PERL_DL_NONLAZY=1 $(FULLPERLRUN) "-MExtUtils::Command::MM" "-e" "test_harness($(TEST_VERBOSE), '$(INST_LIB)', '$(INST_ARCHLIB)')" $(TEST_FILES) + +testdb_dynamic :: pure_all + PERL_DL_NONLAZY=1 $(FULLPERLRUN) $(TESTDB_SW) "-I$(INST_LIB)" "-I$(INST_ARCHLIB)" $(TEST_FILE) + +test_ : test_dynamic + +test_static :: test_dynamic +testdb_static :: testdb_dynamic + + +# --- MakeMaker ppd section: +# Creates a PPD (Perl Package Description) for a binary distribution. +ppd: + $(NOECHO) $(ECHO) '<SOFTPKG NAME="$(DISTNAME)" VERSION="0,12,0,0">' > $(DISTNAME).ppd + $(NOECHO) $(ECHO) ' <TITLE>$(DISTNAME)</TITLE>' >> $(DISTNAME).ppd + $(NOECHO) $(ECHO) ' <ABSTRACT>return name and handle of a temporary file safely</ABSTRACT>' >> $(DISTNAME).ppd + $(NOECHO) $(ECHO) ' <AUTHOR>Tim Jenness <t.jenness@jach.hawaii.edu></AUTHOR>' >> $(DISTNAME).ppd + $(NOECHO) $(ECHO) ' <IMPLEMENTATION>' >> $(DISTNAME).ppd + $(NOECHO) $(ECHO) ' <DEPENDENCY NAME="Fcntl" VERSION="1,03,0,0" />' >> $(DISTNAME).ppd + $(NOECHO) $(ECHO) ' <DEPENDENCY NAME="File-Path" VERSION="0,0,0,0" />' >> $(DISTNAME).ppd + $(NOECHO) $(ECHO) ' <DEPENDENCY NAME="File-Spec" VERSION="0,8,0,0" />' >> $(DISTNAME).ppd + $(NOECHO) $(ECHO) ' <OS NAME="$(OSNAME)" />' >> $(DISTNAME).ppd + $(NOECHO) $(ECHO) ' <ARCHITECTURE NAME="i686-linux" />' >> $(DISTNAME).ppd + $(NOECHO) $(ECHO) ' <CODEBASE HREF="" />' >> $(DISTNAME).ppd + $(NOECHO) $(ECHO) ' </IMPLEMENTATION>' >> $(DISTNAME).ppd + $(NOECHO) $(ECHO) '</SOFTPKG>' >> $(DISTNAME).ppd + + +# --- MakeMaker pm_to_blib section: + +pm_to_blib: $(TO_INST_PM) + $(NOECHO) $(PERLRUN) -MExtUtils::Install -e 'pm_to_blib({@ARGV}, '\''$(INST_LIB)/auto'\'', '\''$(PM_FILTER)'\'')'\ + Temp.pm $(INST_LIB)/File/Temp.pm + $(NOECHO) $(TOUCH) $@ + +# --- MakeMaker selfdocument section: + + +# --- MakeMaker postamble section: + + +# End. diff --git a/lib/Temp/File-Temp-0.12/Makefile.PL b/lib/Temp/File-Temp-0.12/Makefile.PL new file mode 100644 index 0000000..638e77f --- /dev/null +++ b/lib/Temp/File-Temp-0.12/Makefile.PL @@ -0,0 +1,17 @@ +use ExtUtils::MakeMaker; + +# Write the makefile +WriteMakefile( + 'NAME' => 'File::Temp', + 'VERSION_FROM' => 'Temp.pm', # finds $VERSION + + 'PREREQ_PM' => { + File::Spec => 0.8, + Fcntl => 1.03, + File::Path => undef, + }, + 'dist' => { COMPRESS => "gzip -9f" }, + ($] >= 5.005 ? ## Add these new keywords supported since 5.005 + (ABSTRACT_FROM => 'Temp.pm', + AUTHOR => 'Tim Jenness <t.jenness@jach.hawaii.edu>') : ()), +); diff --git a/lib/Temp/File-Temp-0.12/README b/lib/Temp/File-Temp-0.12/README new file mode 100644 index 0000000..07874fc --- /dev/null +++ b/lib/Temp/File-Temp-0.12/README @@ -0,0 +1,161 @@ +File::Temp - provides functions for generating temporary files + +This is release V0.12 of File::Temp. This module can be used to +generate temporary files (providing a filename and filehandle) or directories. +Possible race conditions are avoided and some security checks are performed +(eg making sure the sticky bit is set on world writeable temp directories). + +It could be considered to be in a beta state since it has only been +tested on six operating systems. + +Please let me know if it fails on other operating systems. + +INSTALLATION + + % perl Makefile.PL + % make + % make test + % make install + +TEST FAILURES + +Test failures from lib/ftmp-security saying "system possibly insecure" + +Firstly, test failures from the ftmp-security are not necessarily +serious or indicative of a real security threat. That being said, +they bear investigating. + +The tests may fail for the following reasons. Note that each of the +tests is run both in the building directory and the temporary +directory, as returned by File::Spec->tmpdir(). + +(1) If the directory the tests are being run is owned by somebody else +than the user running the tests, or root (uid 0). This failure can +happen if the Perl source code distribution is unpacked in a way that +the user ids in the distribution package are used as-is. Some tar +programs do this. + +(2) If the directory the test are being run in is writable by group +or by other (remember: with UNIX/POSIX semantics, write access to +a directory means the right to add/remove files in that directory), +and there is no sticky bit set in the directory. 'Sticky bit' is +a feature used in some UNIXes to give extra protection to files: if +the bit is on a directory, no one but the owner (or the root) can remove +that file even if the permissions of the directory would allow file +removal by others. This failure can happen if the permissions in the +directory simply are a bit too liberal for the tests' liking. This +may or may not be a real problem: it depends on the permissions policy +used on this particular directory/project/system/site. This failure +can also happen if the system either doesn't support the sticky bit +(this is the case with many non-UNIX platforms: in principle the +File::Temp should know about these platforms and skip the tests), or +if the system supports the sticky bit but for some reason or reasons +it is not being used. This is for example the case with HP-UX: as of +HP-UX release 11.00, the sticky bit is very much supported, but HP-UX +doesn't use it on its /tmp directory as shipped. Also as with the +permissions, some local policy might dictate that the stickiness is +not used. + +(3) If the system supports the POSIX 'chown giveaway' feature and if +any of the parent directories of the temporary file back to the root +directory are 'unsafe', using the definitions given above in (1) and +(2). + +See the documentation for the File::Temp module for more information +about the various security aspects. + +REQUIREMENTS + +Requires perl 5.005 or newer. +Perl 5.6.0 will give access to extra security checks. + +Written completely in Perl. XS is not required. + +File::Spec greater than or equal to 0.8 is required. +Fcntl from perl5.5.670 or higher [but will work without it]. +The above two modules are standard on Perl 5.6 + +PLATFORMS + +Tested on the following platforms: + + RedHat Linux 7, perl 5.6.0 + Solaris 2.6, perl 5.6.0 + Windows NT 4, perl 5.6.0 + VMS, perl5.7.0 + OS/2, perl5.7.0 + DOS/DJGPP, perl5.7.0 + + RedHat Linux 6.1, perl 5.005_03 + Digital Unix 4.0, perl 5.005_03 + +File::Temp is a standard Perl module as of perl 5.7.0 and 5.6.1. + +Still may need work on non-Unix platforms to adjust test severity (for example +stickyness test does not work on NT, and neither does unlink on an open +file). MEDIUM and HIGH security checks have only been tested on Unix. +Porting notes are provided at the start of Temp.pm. + +AUTHOR + +Tim Jenness <t.jenness@jach.hawaii.edu> + +Copyright (C) 1999 - 2001 Tim Jenness and the UK Particle Physics and +Astronomy Research Council. All Rights Reserved. This program is free +software; you can redistribute it and/or modify it under the same +terms as Perl itself. + +CHANGES IN THIS RELEASE + +V0.12: + - Fix problem with Fcntl warnings on CGI and CGI::Carp + [Thanks to John Labovitz <johnl@valiha.inside.sealabs.com>] + - Remove most of the carp warnings and wrap all information into a + single croak (this allows security failures to die without + additional warnings getting in the way) + +V0.11: + - Fix bug on NT with O_TEMPORARY. The file was removed on close + rather than on exit + +V0.10: + - More fixes for VMS + - Add DOS/DJGPP support + - Make security test less prone to failure on insecure systems + since we are testing the module rather than the system. + - Security tests is run in build dir and tmpdir + +V0.09: + - Add VMS support + - OS/2 can not understand sticky bits + +V0.08: + - Improve performance by a factor of 3 over V0.07 + - Simplify the END block code + - Ignore requests for HIGH or MEDIUM safety on platforms that + can not support it (rather than generating a fatal error) + - Add OS/2 to list of platforms that can not unlink open file + +V0.07: + - Add support for perl 5.005. On perl 5.005 the HIGH and + MEDIUM security levels are not supported due to changes in + the Fcntl module. + + - A benchmark has been added to the misc directory to compare + IO::File->new_tmpfile, File::Temp and a simple creation wrapper + around POSIX::tmpnam. On my Linux system File::Temp::tempfile() + is an order of magnitude slower than the other two...... + +V0.06: + - Add a test suite + - Fix unlinking during the END blocks (was only removing the + first file generated) + - unlink0 can now be run on WinNT - the unlink of the file + is now deferred to an END block since can not unlink an + open file on WinNT + - If the POSIX _PC_CHOWN_RESTRICTED symbol is not available + it is assumed that "chown giveaway" is allowed. + + +V0.05: + - First release to CPAN diff --git a/lib/Temp/File-Temp-0.12/Temp.pm b/lib/Temp/File-Temp-0.12/Temp.pm new file mode 100644 index 0000000..b686682 --- /dev/null +++ b/lib/Temp/File-Temp-0.12/Temp.pm @@ -0,0 +1,1863 @@ +package File::Temp; + +=head1 NAME + +File::Temp - return name and handle of a temporary file safely + +=begin __INTERNALS + +=head1 PORTABILITY + +This module is designed to be portable across operating systems +and it currently supports Unix, VMS, DOS, OS/2 and Windows. When +porting to a new OS there are generally three main issues +that have to be solved: + +=over 4 + +=item * + +Can the OS unlink an open file? If it can not then the +C<_can_unlink_opened_file> method should be modified. + +=item * + +Are the return values from C<stat> reliable? By default all the +return values from C<stat> are compared when unlinking a temporary +file using the filename and the handle. Operating systems other than +unix do not always have valid entries in all fields. If C<unlink0> fails +then the C<stat> comparison should be modified accordingly. + +=item * + +Security. Systems that can not support a test for the sticky bit +on a directory can not use the MEDIUM and HIGH security tests. +The C<_can_do_level> method should be modified accordingly. + +=back + +=end __INTERNALS + +=head1 SYNOPSIS + + use File::Temp qw/ tempfile tempdir /; + + $dir = tempdir( CLEANUP => 1 ); + ($fh, $filename) = tempfile( DIR => $dir ); + + ($fh, $filename) = tempfile( $template, DIR => $dir); + ($fh, $filename) = tempfile( $template, SUFFIX => '.dat'); + + $fh = tempfile(); + +MkTemp family: + + use File::Temp qw/ :mktemp /; + + ($fh, $file) = mkstemp( "tmpfileXXXXX" ); + ($fh, $file) = mkstemps( "tmpfileXXXXXX", $suffix); + + $tmpdir = mkdtemp( $template ); + + $unopened_file = mktemp( $template ); + +POSIX functions: + + use File::Temp qw/ :POSIX /; + + $file = tmpnam(); + $fh = tmpfile(); + + ($fh, $file) = tmpnam(); + ($fh, $file) = tmpfile(); + + +Compatibility functions: + + $unopened_file = File::Temp::tempnam( $dir, $pfx ); + +=begin later + +Objects (NOT YET IMPLEMENTED): + + require File::Temp; + + $fh = new File::Temp($template); + $fname = $fh->filename; + +=end later + +=head1 DESCRIPTION + +C<File::Temp> can be used to create and open temporary files in a safe way. +The tempfile() function can be used to return the name and the open +filehandle of a temporary file. The tempdir() function can +be used to create a temporary directory. + +The security aspect of temporary file creation is emphasized such that +a filehandle and filename are returned together. This helps guarantee +that a race condition can not occur where the temporary file is +created by another process between checking for the existence of the +file and its opening. Additional security levels are provided to +check, for example, that the sticky bit is set on world writable +directories. See L<"safe_level"> for more information. + +For compatibility with popular C library functions, Perl implementations of +the mkstemp() family of functions are provided. These are, mkstemp(), +mkstemps(), mkdtemp() and mktemp(). + +Additionally, implementations of the standard L<POSIX|POSIX> +tmpnam() and tmpfile() functions are provided if required. + +Implementations of mktemp(), tmpnam(), and tempnam() are provided, +but should be used with caution since they return only a filename +that was valid when function was called, so cannot guarantee +that the file will not exist by the time the caller opens the filename. + +=cut + +# 5.6.0 gives us S_IWOTH, S_IWGRP, our and auto-vivifying filehandls +# People would like a version on 5.005 so give them what they want :-) +use 5.005; +use strict; +use Carp; +use File::Spec 0.8; +use File::Path qw/ rmtree /; +use Fcntl 1.03; +use Errno; +require VMS::Stdio if $^O eq 'VMS'; + +# Need the Symbol package if we are running older perl +require Symbol if $] < 5.006; + + +# use 'our' on v5.6.0 +use vars qw($VERSION @EXPORT_OK %EXPORT_TAGS $DEBUG); + +$DEBUG = 0; + +# We are exporting functions + +use base qw/Exporter/; + +# Export list - to allow fine tuning of export table + +@EXPORT_OK = qw{ + tempfile + tempdir + tmpnam + tmpfile + mktemp + mkstemp + mkstemps + mkdtemp + unlink0 + }; + +# Groups of functions for export + +%EXPORT_TAGS = ( + 'POSIX' => [qw/ tmpnam tmpfile /], + 'mktemp' => [qw/ mktemp mkstemp mkstemps mkdtemp/], + ); + +# add contents of these tags to @EXPORT +Exporter::export_tags('POSIX','mktemp'); + +# Version number + +$VERSION = '0.12'; + +# This is a list of characters that can be used in random filenames + +my @CHARS = (qw/ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z + a b c d e f g h i j k l m n o p q r s t u v w x y z + 0 1 2 3 4 5 6 7 8 9 _ + /); + +# Maximum number of tries to make a temp file before failing + +use constant MAX_TRIES => 10; + +# Minimum number of X characters that should be in a template +use constant MINX => 4; + +# Default template when no template supplied + +use constant TEMPXXX => 'X' x 10; + +# Constants for the security level + +use constant STANDARD => 0; +use constant MEDIUM => 1; +use constant HIGH => 2; + +# OPENFLAGS. If we defined the flag to use with Sysopen here this gives +# us an optimisation when many temporary files are requested + +my $OPENFLAGS = O_CREAT | O_EXCL | O_RDWR; + +for my $oflag (qw/ FOLLOW BINARY LARGEFILE EXLOCK NOINHERIT /) { + my ($bit, $func) = (0, "Fcntl::O_" . $oflag); + no strict 'refs'; + $OPENFLAGS |= $bit if eval { + # Make sure that redefined die handlers do not cause problems + # eg CGI::Carp + local $SIG{__DIE__} = sub {}; + local $SIG{__WARN__} = sub {}; + $bit = &$func(); + 1; + }; +} + +# On some systems the O_TEMPORARY flag can be used to tell the OS +# to automatically remove the file when it is closed. This is fine +# in most cases but not if tempfile is called with UNLINK=>0 and +# the filename is requested -- in the case where the filename is to +# be passed to another routine. This happens on windows. We overcome +# this by using a second open flags variable + +my $OPENTEMPFLAGS = $OPENFLAGS; +for my $oflag (qw/ TEMPORARY /) { + my ($bit, $func) = (0, "Fcntl::O_" . $oflag); + no strict 'refs'; + $OPENTEMPFLAGS |= $bit if eval { + # Make sure that redefined die handlers do not cause problems + # eg CGI::Carp + local $SIG{__DIE__} = sub {}; + local $SIG{__WARN__} = sub {}; + $bit = &$func(); + 1; + }; +} + +# INTERNAL ROUTINES - not to be used outside of package + +# Generic routine for getting a temporary filename +# modelled on OpenBSD _gettemp() in mktemp.c + +# The template must contain X's that are to be replaced +# with the random values + +# Arguments: + +# TEMPLATE - string containing the XXXXX's that is converted +# to a random filename and opened if required + +# Optionally, a hash can also be supplied containing specific options +# "open" => if true open the temp file, else just return the name +# default is 0 +# "mkdir"=> if true, we are creating a temp directory rather than tempfile +# default is 0 +# "suffixlen" => number of characters at end of PATH to be ignored. +# default is 0. +# "unlink_on_close" => indicates that, if possible, the OS should remove +# the file as soon as it is closed. Usually indicates +# use of the O_TEMPORARY flag to sysopen. +# Usually irrelevant on unix + +# 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 +# "ErrStr" => \$errstr + +# "open" and "mkdir" can not both be true +# "unlink_on_close" is not used when "mkdir" is true. + +# The default options are equivalent to mktemp(). + +# Returns: +# filehandle - open file handle (if called with doopen=1, else undef) +# temp name - name of the temp file or directory + +# For example: +# ($fh, $name) = _gettemp($template, "open" => 1); + +# for the current version, failures are associated with +# stored in an error string and returned to give the reason whilst debugging +# This routine is not called by any external function +sub _gettemp { + + croak 'Usage: ($fh, $name) = _gettemp($template, OPTIONS);' + unless scalar(@_) >= 1; + + # the internal error string - expect it to be overridden + # Need this in case the caller decides not to supply us a value + # need an anonymous scalar + my $tempErrStr; + + # Default options + my %options = ( + "open" => 0, + "mkdir" => 0, + "suffixlen" => 0, + "unlink_on_close" => 0, + "ErrStr" => \$tempErrStr, + ); + + # Read the template + my $template = shift; + if (ref($template)) { + # Use a warning here since we have not yet merged ErrStr + carp "File::Temp::_gettemp: template must not be a reference"; + return (); + } + + # Check that the number of entries on stack are even + if (scalar(@_) % 2 != 0) { + # Use a warning here since we have not yet merged ErrStr + carp "File::Temp::_gettemp: Must have even number of options"; + return (); + } + + # Read the options and merge with defaults + %options = (%options, @_) if @_; + + # Make sure the error string is set to undef + ${$options{ErrStr}} = undef; + + # Can not open the file and make a directory in a single call + if ($options{"open"} && $options{"mkdir"}) { + ${$options{ErrStr}} = "doopen and domkdir can not both be true\n"; + return (); + } + + # Find the start of the end of the Xs (position of last X) + # Substr starts from 0 + my $start = length($template) - 1 - $options{"suffixlen"}; + + # Check that we have at least MINX x X (eg 'XXXX") at the end of the string + # (taking suffixlen into account). Any fewer is insecure. + + # Do it using substr - no reason to use a pattern match since + # we know where we are looking and what we are looking for + + if (substr($template, $start - MINX + 1, MINX) ne 'X' x MINX) { + ${$options{ErrStr}} = "The template must contain at least ". + MINX . " 'X' characters\n"; + return (); + } + + # Replace all the X at the end of the substring with a + # random character or just all the XX at the end of a full string. + # Do it as an if, since the suffix adjusts which section to replace + # and suffixlen=0 returns nothing if used in the substr directly + # and generate a full path from the template + + my $path = _replace_XX($template, $options{"suffixlen"}); + + + # Split the path into constituent parts - eventually we need to check + # whether the directory exists + # We need to know whether we are making a temp directory + # or a tempfile + + my ($volume, $directories, $file); + my $parent; # parent directory + if ($options{"mkdir"}) { + # There is no filename at the end + ($volume, $directories, $file) = File::Spec->splitpath( $path, 1); + + # The parent is then $directories without the last directory + # Split the directory and put it back together again + my @dirs = File::Spec->splitdir($directories); + + # If @dirs only has one entry that means we are in the current + # directory + if ($#dirs == 0) { + $parent = File::Spec->curdir; + } else { + + if ($^O eq 'VMS') { # need volume to avoid relative dir spec + $parent = File::Spec->catdir($volume, @dirs[0..$#dirs-1]); + $parent = 'sys$disk:[]' if $parent eq ''; + } else { + + # Put it back together without the last one + $parent = File::Spec->catdir(@dirs[0..$#dirs-1]); + + # ...and attach the volume (no filename) + $parent = File::Spec->catpath($volume, $parent, ''); + } + + } + + } else { + + # Get rid of the last filename (use File::Basename for this?) + ($volume, $directories, $file) = File::Spec->splitpath( $path ); + + # Join up without the file part + $parent = File::Spec->catpath($volume,$directories,''); + + # If $parent is empty replace with curdir + $parent = File::Spec->curdir + unless $directories ne ''; + + } + + # Check that the parent directories exist + # Do this even for the case where we are simply returning a name + # not a file -- no point returning a name that includes a directory + # that does not exist or is not writable + + unless (-d $parent) { + ${$options{ErrStr}} = "Parent directory ($parent) is not a directory"; + return (); + } + unless (-w _) { + ${$options{ErrStr}} = "Parent directory ($parent) is not writable\n"; + return (); + } + + + # Check the stickiness of the directory and chown giveaway if required + # If the directory is world writable the sticky bit + # must be set + + if (File::Temp->safe_level == MEDIUM) { + my $safeerr; + unless (_is_safe($parent,\$safeerr)) { + ${$options{ErrStr}} = "Parent directory ($parent) is not safe ($safeerr)"; + return (); + } + } elsif (File::Temp->safe_level == HIGH) { + my $safeerr; + unless (_is_verysafe($parent, \$safeerr)) { + ${$options{ErrStr}} = "Parent directory ($parent) is not safe ($safeerr)"; + return (); + } + } + + + # Now try MAX_TRIES time to open the file + for (my $i = 0; $i < MAX_TRIES; $i++) { + + # Try to open the file if requested + if ($options{"open"}) { + my $fh; + + # If we are running before perl5.6.0 we can not auto-vivify + if ($] < 5.006) { + $fh = &Symbol::gensym; + } + + # Try to make sure this will be marked close-on-exec + # XXX: Win32 doesn't respect this, nor the proper fcntl, + # but may have O_NOINHERIT. This may or may not be in Fcntl. + local $^F = 2; + + # Store callers umask + my $umask = umask(); + + # Set a known umask + umask(066); + + # Attempt to open the file + my $open_success = undef; + if ( $^O eq 'VMS' and $options{"unlink_on_close"} ) { + # make it auto delete on close by setting FAB$V_DLT bit + $fh = VMS::Stdio::vmssysopen($path, $OPENFLAGS, 0600, 'fop=dlt'); + $open_success = $fh; + } else { + my $flags = ( $options{"unlink_on_close"} ? + $OPENTEMPFLAGS : + $OPENFLAGS ); + $open_success = sysopen($fh, $path, $flags, 0600); + } + if ( $open_success ) { + + # Reset umask + umask($umask); + + # Opened successfully - return file handle and name + return ($fh, $path); + + } else { + # Reset umask + umask($umask); + + # Error opening file - abort with error + # if the reason was anything but EEXIST + unless ($!{EEXIST}) { + ${$options{ErrStr}} = "Could not create temp file $path: $!"; + return (); + } + + # Loop round for another try + + } + } elsif ($options{"mkdir"}) { + + # Store callers umask + my $umask = umask(); + + # Set a known umask + umask(066); + + # Open the temp directory + if (mkdir( $path, 0700)) { + # created okay + # Reset umask + umask($umask); + + return undef, $path; + } else { + + # Reset umask + umask($umask); + + # Abort with error if the reason for failure was anything + # except EEXIST + unless ($!{EEXIST}) { + ${$options{ErrStr}} = "Could not create directory $path: $!"; + return (); + } + + # Loop round for another try + + } + + } else { + + # Return true if the file can not be found + # Directory has been checked previously + + return (undef, $path) unless -e $path; + + # Try again until MAX_TRIES + + } + + # Did not successfully open the tempfile/dir + # so try again with a different set of random letters + # No point in trying to increment unless we have only + # 1 X say and the randomness could come up with the same + # file MAX_TRIES in a row. + + # Store current attempt - in principal this implies that the + # 3rd time around the open attempt that the first temp file + # name could be generated again. Probably should store each + # attempt and make sure that none are repeated + + my $original = $path; + my $counter = 0; # Stop infinite loop + my $MAX_GUESS = 50; + + do { + + # Generate new name from original template + $path = _replace_XX($template, $options{"suffixlen"}); + + $counter++; + + } until ($path ne $original || $counter > $MAX_GUESS); + + # Check for out of control looping + if ($counter > $MAX_GUESS) { + ${$options{ErrStr}} = "Tried to get a new temp name different to the previous value $MAX_GUESS times.\nSomething wrong with template?? ($template)"; + return (); + } + + } + + # If we get here, we have run out of tries + ${ $options{ErrStr} } = "Have exceeded the maximum number of attempts (" + . MAX_TRIES . ") to open temp file/dir"; + + return (); + +} + +# Internal routine to return a random character from the +# character list. Does not do an srand() since rand() +# will do one automatically + +# No arguments. Return value is the random character + +# No longer called since _replace_XX runs a few percent faster if +# I inline the code. This is important if we are creating thousands of +# temporary files. + +sub _randchar { + + $CHARS[ int( rand( $#CHARS ) ) ]; + +} + +# Internal routine to replace the XXXX... with random characters +# This has to be done by _gettemp() every time it fails to +# open a temp file/dir + +# Arguments: $template (the template with XXX), +# $ignore (number of characters at end to ignore) + +# Returns: modified template + +sub _replace_XX { + + croak 'Usage: _replace_XX($template, $ignore)' + unless scalar(@_) == 2; + + my ($path, $ignore) = @_; + + # Do it as an if, since the suffix adjusts which section to replace + # and suffixlen=0 returns nothing if used in the substr directly + # Alternatively, could simply set $ignore to length($path)-1 + # Don't want to always use substr when not required though. + + if ($ignore) { + substr($path, 0, - $ignore) =~ s/X(?=X*\z)/$CHARS[ int( rand( $#CHARS ) ) ]/ge; + } else { + $path =~ s/X(?=X*\z)/$CHARS[ int( rand( $#CHARS ) ) ]/ge; + } + + return $path; +} + +# internal routine to check to see if the directory is safe +# First checks to see if the directory is not owned by the +# current user or root. Then checks to see if anyone else +# can write to the directory and if so, checks to see if +# it has the sticky bit set + +# Will not work on systems that do not support sticky bit + +#Args: directory path to check +# Optionally: reference to scalar to contain error message +# Returns true if the path is safe and false otherwise. +# Returns undef if can not even run stat() on the path + +# This routine based on version written by Tom Christiansen + +# Presumably, by the time we actually attempt to create the +# file or directory in this directory, it may not be safe +# anymore... Have to run _is_safe directly after the open. + +sub _is_safe { + + my $path = shift; + my $err_ref = shift; + + # Stat path + my @info = stat($path); + unless (scalar(@info)) { + $$err_ref = "stat(path) returned no values"; + return 0; + }; + return 1 if $^O eq 'VMS'; # owner delete control at file level + + # Check to see whether owner is neither superuser (or a system uid) nor me + # Use the real uid from the $< variable + # UID is in [4] + if ($info[4] > File::Temp->top_system_uid() && $info[4] != $<) { + + Carp::cluck(sprintf "uid=$info[4] topuid=%s \$<=$< path='$path'", + File::Temp->top_system_uid()); + + $$err_ref = "Directory owned neither by root nor the current user" + if ref($err_ref); + return 0; + } + + # check whether group or other can write file + # use 066 to detect either reading or writing + # use 022 to check writability + # Do it with S_IWOTH and S_IWGRP for portability (maybe) + # mode is in info[2] + if (($info[2] & &Fcntl::S_IWGRP) || # Is group writable? + ($info[2] & &Fcntl::S_IWOTH) ) { # Is world writable? + # Must be a directory + unless (-d _) { + $$err_ref = "Path ($path) is not a directory" + if ref($err_ref); + return 0; + } + # Must have sticky bit set + unless (-k _) { + $$err_ref = "Sticky bit not set on $path when dir is group|world writable" + if ref($err_ref); + return 0; + } + } + + return 1; +} + +# Internal routine to check whether a directory is safe +# for temp files. Safer than _is_safe since it checks for +# the possibility of chown giveaway and if that is a possibility +# checks each directory in the path to see if it is safe (with _is_safe) + +# If _PC_CHOWN_RESTRICTED is not set, does the full test of each +# directory anyway. + +# Takes optional second arg as scalar ref to error reason + +sub _is_verysafe { + + # Need POSIX - but only want to bother if really necessary due to overhead + require POSIX; + + my $path = shift; + print "_is_verysafe testing $path\n" if $DEBUG; + return 1 if $^O eq 'VMS'; # owner delete control at file level + + my $err_ref = shift; + + # Should Get the value of _PC_CHOWN_RESTRICTED if it is defined + # and If it is not there do the extensive test + my $chown_restricted; + $chown_restricted = &POSIX::_PC_CHOWN_RESTRICTED() + if eval { &POSIX::_PC_CHOWN_RESTRICTED(); 1}; + + # If chown_resticted is set to some value we should test it + if (defined $chown_restricted) { + + # Return if the current directory is safe + return _is_safe($path,$err_ref) if POSIX::sysconf( $chown_restricted ); + + } + + # To reach this point either, the _PC_CHOWN_RESTRICTED symbol + # was not avialable or the symbol was there but chown giveaway + # is allowed. Either way, we now have to test the entire tree for + # safety. + + # Convert path to an absolute directory if required + unless (File::Spec->file_name_is_absolute($path)) { + $path = File::Spec->rel2abs($path); + } + + # Split directory into components - assume no file + my ($volume, $directories, undef) = File::Spec->splitpath( $path, 1); + + # Slightly less efficient than having a a function in File::Spec + # to chop off the end of a directory or even a function that + # can handle ../ in a directory tree + # Sometimes splitdir() returns a blank at the end + # so we will probably check the bottom directory twice in some cases + my @dirs = File::Spec->splitdir($directories); + + # Concatenate one less directory each time around + foreach my $pos (0.. $#dirs) { + # Get a directory name + my $dir = File::Spec->catpath($volume, + File::Spec->catdir(@dirs[0.. $#dirs - $pos]), + '' + ); + + print "TESTING DIR $dir\n" if $DEBUG; + + # Check the directory + return 0 unless _is_safe($dir,$err_ref); + + } + + return 1; +} + + + +# internal routine to determine whether unlink works on this +# platform for files that are currently open. +# Returns true if we can, false otherwise. + +# Currently WinNT, OS/2 and VMS can not unlink an opened file +# On VMS this is because the O_EXCL flag is used to open the +# temporary file. Currently I do not know enough about the issues +# on VMS to decide whether O_EXCL is a requirement. + +sub _can_unlink_opened_file { + + if ($^O eq 'MSWin32' || $^O eq 'os2' || $^O eq 'VMS' || $^O eq 'dos') { + return 0; + } else { + return 1; + } + +} + +# internal routine to decide which security levels are allowed +# see safe_level() for more information on this + +# Controls whether the supplied security level is allowed + +# $cando = _can_do_level( $level ) + +sub _can_do_level { + + # Get security level + my $level = shift; + + # Always have to be able to do STANDARD + return 1 if $level == STANDARD; + + # Currently, the systems that can do HIGH or MEDIUM are identical + if ( $^O eq 'MSWin32' || $^O eq 'os2' || $^O eq 'cygwin' || $^O eq 'dos') { + return 0; + } else { + return 1; + } + +} + +# This routine sets up a deferred unlinking of a specified +# filename and filehandle. It is used in the following cases: +# - Called by unlink0 if an opened file can not be unlinked +# - Called by tempfile() if files are to be removed on shutdown +# - Called by tempdir() if directories are to be removed on shutdown + +# Arguments: +# _deferred_unlink( $fh, $fname, $isdir ); +# +# - filehandle (so that it can be expclicitly closed if open +# - filename (the thing we want to remove) +# - isdir (flag to indicate that we are being given a directory) +# [and hence no filehandle] + +# Status is not referred to since all the magic is done with an END block + +{ + # Will set up two lexical variables to contain all the files to be + # removed. One array for files, another for directories + # They will only exist in this block + # This means we only have to set up a single END block to remove all files + # @files_to_unlink contains an array ref with the filehandle and filename + my (@files_to_unlink, @dirs_to_unlink); + + # Set up an end block to use these arrays + END { + # Files + foreach my $file (@files_to_unlink) { + # close the filehandle without checking its state + # in order to make real sure that this is closed + # if its already closed then I dont care about the answer + # probably a better way to do this + close($file->[0]); # file handle is [0] + + if (-f $file->[1]) { # file name is [1] + unlink $file->[1] or warn "Error removing ".$file->[1]; + } + } + # Dirs + foreach my $dir (@dirs_to_unlink) { + if (-d $dir) { + rmtree($dir, $DEBUG, 1); + } + } + + } + + # This is the sub called to register a file for deferred unlinking + # This could simply store the input parameters and defer everything + # until the END block. For now we do a bit of checking at this + # point in order to make sure that (1) we have a file/dir to delete + # and (2) we have been called with the correct arguments. + sub _deferred_unlink { + + croak 'Usage: _deferred_unlink($fh, $fname, $isdir)' + unless scalar(@_) == 3; + + my ($fh, $fname, $isdir) = @_; + + warn "Setting up deferred removal of $fname\n" + if $DEBUG; + + # If we have a directory, check that it is a directory + if ($isdir) { + + if (-d $fname) { + + # Directory exists so store it + # first on VMS turn []foo into [.foo] for rmtree + $fname = VMS::Filespec::vmspath($fname) if $^O eq 'VMS'; + push (@dirs_to_unlink, $fname); + + } else { + carp "Request to remove directory $fname could not be completed since it does not exist!\n" if $^W; + } + + } else { + + if (-f $fname) { + + # file exists so store handle and name for later removal + push(@files_to_unlink, [$fh, $fname]); + + } else { + carp "Request to remove file $fname could not be completed since it is not there!\n" if $^W; + } + + } + + } + + +} + +=head1 FUNCTIONS + +This section describes the recommended interface for generating +temporary files and directories. + +=over 4 + +=item B<tempfile> + +This is the basic function to generate temporary files. +The behaviour of the file can be changed using various options: + + ($fh, $filename) = tempfile(); + +Create a temporary file in the directory specified for temporary +files, as specified by the tmpdir() function in L<File::Spec>. + + ($fh, $filename) = tempfile($template); + +Create a temporary file in the current directory using the supplied +template. Trailing `X' characters are replaced with random letters to +generate the filename. At least four `X' characters must be present +in the template. + + ($fh, $filename) = tempfile($template, SUFFIX => $suffix) + +Same as previously, except that a suffix is added to the template +after the `X' translation. Useful for ensuring that a temporary +filename has a particular extension when needed by other applications. +But see the WARNING at the end. + + ($fh, $filename) = tempfile($template, DIR => $dir); + +Translates the template as before except that a directory name +is specified. + + ($fh, $filename) = tempfile($template, UNLINK => 1); + +Return the filename and filehandle as before except that the file is +automatically removed when the program exits. Default is for the file +to be removed if a file handle is requested and to be kept if the +filename is requested. In a scalar context (where no filename is +returned) the file is always deleted either on exit or when it is closed. + +If the template is not specified, a template is always +automatically generated. This temporary file is placed in tmpdir() +(L<File::Spec>) unless a directory is specified explicitly with the +DIR option. + + $fh = tempfile( $template, DIR => $dir ); + +If called in scalar context, only the filehandle is returned +and the file will automatically be deleted when closed (see +the description of tmpfile() elsewhere in this document). +This is the preferred mode of operation, as if you only +have a filehandle, you can never create a race condition +by fumbling with the filename. On systems that can not unlink +an open file or can not mark a file as temporary when it is opened +(for example, Windows NT uses the C<O_TEMPORARY> flag)) +the file is marked for deletion when the program ends (equivalent +to setting UNLINK to 1). The C<UNLINK> flag is ignored if present. + + (undef, $filename) = tempfile($template, OPEN => 0); + +This will return the filename based on the template but +will not open this file. Cannot be used in conjunction with +UNLINK set to true. Default is to always open the file +to protect from possible race conditions. A warning is issued +if warnings are turned on. Consider using the tmpnam() +and mktemp() functions described elsewhere in this document +if opening the file is not required. + +Options can be combined as required. + +=cut + +sub tempfile { + + # Can not check for argument count since we can have any + # number of args + + # Default options + my %options = ( + "DIR" => undef, # Directory prefix + "SUFFIX" => '', # Template suffix + "UNLINK" => 0, # Do not unlink file on exit + "OPEN" => 1, # Open file + ); + + # Check to see whether we have an odd or even number of arguments + my $template = (scalar(@_) % 2 == 1 ? shift(@_) : undef); + + # Read the options and merge with defaults + %options = (%options, @_) if @_; + + # First decision is whether or not to open the file + if (! $options{"OPEN"}) { + + warn "tempfile(): temporary filename requested but not opened.\nPossibly unsafe, consider using tempfile() with OPEN set to true\n" + if $^W; + + } + + if ($options{"DIR"} and $^O eq 'VMS') { + + # on VMS turn []foo into [.foo] for concatenation + $options{"DIR"} = VMS::Filespec::vmspath($options{"DIR"}); + } + + # Construct the template + + # Have a choice of trying to work around the mkstemp/mktemp/tmpnam etc + # functions or simply constructing a template and using _gettemp() + # explicitly. Go for the latter + + # First generate a template if not defined and prefix the directory + # If no template must prefix the temp directory + if (defined $template) { + if ($options{"DIR"}) { + + $template = File::Spec->catfile($options{"DIR"}, $template); + + } + + } else { + + if ($options{"DIR"}) { + + $template = File::Spec->catfile($options{"DIR"}, TEMPXXX); + + } else { + + $template = File::Spec->catfile(File::Spec->tmpdir, TEMPXXX); + + } + + } + + # Now add a suffix + $template .= $options{"SUFFIX"}; + + # Determine whether we should tell _gettemp to unlink the file + # On unix this is irrelevant and can be worked out after the file is + # opened (simply by unlinking the open filehandle). On Windows or VMS + # we have to indicate temporary-ness when we open the file. In general + # we only want a true temporary file if we are returning just the + # filehandle - if the user wants the filename they probably do not + # want the file to disappear as soon as they close it. + # For this reason, tie unlink_on_close to the return context regardless + # of OS. + my $unlink_on_close = ( wantarray ? 0 : 1); + + # Create the file + my ($fh, $path, $errstr); + croak "Error in tempfile() using $template: $errstr" + unless (($fh, $path) = _gettemp($template, + "open" => $options{'OPEN'}, + "mkdir"=> 0 , + "unlink_on_close" => $unlink_on_close, + "suffixlen" => length($options{'SUFFIX'}), + "ErrStr" => \$errstr, + ) ); + + # Set up an exit handler that can do whatever is right for the + # system. This removes files at exit when requested explicitly or when + # system is asked to unlink_on_close but is unable to do so because + # of OS limitations. + # The latter should be achieved by using a tied filehandle. + # Do not check return status since this is all done with END blocks. + _deferred_unlink($fh, $path, 0) if $options{"UNLINK"}; + + # Return + if (wantarray()) { + + if ($options{'OPEN'}) { + return ($fh, $path); + } else { + return (undef, $path); + } + + } else { + + # Unlink the file. It is up to unlink0 to decide what to do with + # this (whether to unlink now or to defer until later) + unlink0($fh, $path) or croak "Error unlinking file $path using unlink0"; + + # Return just the filehandle. + return $fh; + } + + +} + +=item B<tempdir> + +This is the recommended interface for creation of temporary directories. +The behaviour of the function depends on the arguments: + + $tempdir = tempdir(); + +Create a directory in tmpdir() (see L<File::Spec|File::Spec>). + + $tempdir = tempdir( $template ); + +Create a directory from the supplied template. This template is +similar to that described for tempfile(). `X' characters at the end +of the template are replaced with random letters to construct the +directory name. At least four `X' characters must be in the template. + + $tempdir = tempdir ( DIR => $dir ); + +Specifies the directory to use for the temporary directory. +The temporary directory name is derived from an internal template. + + $tempdir = tempdir ( $template, DIR => $dir ); + +Prepend the supplied directory name to the template. The template +should not include parent directory specifications itself. Any parent +directory specifications are removed from the template before +prepending the supplied directory. + + $tempdir = tempdir ( $template, TMPDIR => 1 ); + +Using the supplied template, creat the temporary directory in +a standard location for temporary files. Equivalent to doing + + $tempdir = tempdir ( $template, DIR => File::Spec->tmpdir); + +but shorter. Parent directory specifications are stripped from the +template itself. The C<TMPDIR> option is ignored if C<DIR> is set +explicitly. Additionally, C<TMPDIR> is implied if neither a template +nor a directory are supplied. + + $tempdir = tempdir( $template, CLEANUP => 1); + +Create a temporary directory using the supplied template, but +attempt to remove it (and all files inside it) when the program +exits. Note that an attempt will be made to remove all files from +the directory even if they were not created by this module (otherwise +why ask to clean it up?). The directory removal is made with +the rmtree() function from the L<File::Path|File::Path> module. +Of course, if the template is not specified, the temporary directory +will be created in tmpdir() and will also be removed at program exit. + +=cut + +# ' + +sub tempdir { + + # Can not check for argument count since we can have any + # number of args + + # Default options + my %options = ( + "CLEANUP" => 0, # Remove directory on exit + "DIR" => '', # Root directory + "TMPDIR" => 0, # Use tempdir with template + ); + + # Check to see whether we have an odd or even number of arguments + my $template = (scalar(@_) % 2 == 1 ? shift(@_) : undef ); + + # Read the options and merge with defaults + %options = (%options, @_) if @_; + + # Modify or generate the template + + # Deal with the DIR and TMPDIR options + if (defined $template) { + + # Need to strip directory path if using DIR or TMPDIR + if ($options{'TMPDIR'} || $options{'DIR'}) { + + # Strip parent directory from the filename + # + # There is no filename at the end + $template = VMS::Filespec::vmspath($template) if $^O eq 'VMS'; + my ($volume, $directories, undef) = File::Spec->splitpath( $template, 1); + + # Last directory is then our template + $template = (File::Spec->splitdir($directories))[-1]; + + # Prepend the supplied directory or temp dir + if ($options{"DIR"}) { + + $template = File::Spec->catdir($options{"DIR"}, $template); + + } elsif ($options{TMPDIR}) { + + # Prepend tmpdir + $template = File::Spec->catdir(File::Spec->tmpdir, $template); + + } + + } + + } else { + + if ($options{"DIR"}) { + + $template = File::Spec->catdir($options{"DIR"}, TEMPXXX); + + } else { + + $template = File::Spec->catdir(File::Spec->tmpdir, TEMPXXX); + + } + + } + + # Create the directory + my $tempdir; + my $suffixlen = 0; + if ($^O eq 'VMS') { # dir names can end in delimiters + $template =~ m/([\.\]:>]+)$/; + $suffixlen = length($1); + } + + my $errstr; + croak "Error in tempdir() using $template: $errstr" + unless ((undef, $tempdir) = _gettemp($template, + "open" => 0, + "mkdir"=> 1 , + "suffixlen" => $suffixlen, + "ErrStr" => \$errstr, + ) ); + + # Install exit handler; must be dynamic to get lexical + if ( $options{'CLEANUP'} && -d $tempdir) { + _deferred_unlink(undef, $tempdir, 1); + } + + # Return the dir name + return $tempdir; + +} + +=back + +=head1 MKTEMP FUNCTIONS + +The following functions are Perl implementations of the +mktemp() family of temp file generation system calls. + +=over 4 + +=item B<mkstemp> + +Given a template, returns a filehandle to the temporary file and the name +of the file. + + ($fh, $name) = mkstemp( $template ); + +In scalar context, just the filehandle is returned. + +The template may be any filename with some number of X's appended +to it, for example F</tmp/temp.XXXX>. The trailing X's are replaced +with unique alphanumeric combinations. + +=cut + + + +sub mkstemp { + + croak "Usage: mkstemp(template)" + if scalar(@_) != 1; + + my $template = shift; + + my ($fh, $path, $errstr); + croak "Error in mkstemp using $template: $errstr" + unless (($fh, $path) = _gettemp($template, + "open" => 1, + "mkdir"=> 0 , + "suffixlen" => 0, + "ErrStr" => \$errstr, + ) ); + + if (wantarray()) { + return ($fh, $path); + } else { + return $fh; + } + +} + + +=item B<mkstemps> + +Similar to mkstemp(), except that an extra argument can be supplied +with a suffix to be appended to the template. + + ($fh, $name) = mkstemps( $template, $suffix ); + +For example a template of C<testXXXXXX> and suffix of C<.dat> +would generate a file similar to F<testhGji_w.dat>. + +Returns just the filehandle alone when called in scalar context. + +=cut + +sub mkstemps { + + croak "Usage: mkstemps(template, suffix)" + if scalar(@_) != 2; + + + my $template = shift; + my $suffix = shift; + + $template .= $suffix; + + my ($fh, $path, $errstr); + croak "Error in mkstemps using $template: $errstr" + unless (($fh, $path) = _gettemp($template, + "open" => 1, + "mkdir"=> 0 , + "suffixlen" => length($suffix), + "ErrStr" => \$errstr, + ) ); + + if (wantarray()) { + return ($fh, $path); + } else { + return $fh; + } + +} + +=item B<mkdtemp> + +Create a directory from a template. The template must end in +X's that are replaced by the routine. + + $tmpdir_name = mkdtemp($template); + +Returns the name of the temporary directory created. +Returns undef on failure. + +Directory must be removed by the caller. + +=cut + +#' # for emacs + +sub mkdtemp { + + croak "Usage: mkdtemp(template)" + if scalar(@_) != 1; + + my $template = shift; + my $suffixlen = 0; + if ($^O eq 'VMS') { # dir names can end in delimiters + $template =~ m/([\.\]:>]+)$/; + $suffixlen = length($1); + } + my ($junk, $tmpdir, $errstr); + croak "Error creating temp directory from template $template\: $errstr" + unless (($junk, $tmpdir) = _gettemp($template, + "open" => 0, + "mkdir"=> 1 , + "suffixlen" => $suffixlen, + "ErrStr" => \$errstr, + ) ); + + return $tmpdir; + +} + +=item B<mktemp> + +Returns a valid temporary filename but does not guarantee +that the file will not be opened by someone else. + + $unopened_file = mktemp($template); + +Template is the same as that required by mkstemp(). + +=cut + +sub mktemp { + + croak "Usage: mktemp(template)" + if scalar(@_) != 1; + + my $template = shift; + + my ($tmpname, $junk, $errstr); + croak "Error getting name to temp file from template $template: $errstr" + unless (($junk, $tmpname) = _gettemp($template, + "open" => 0, + "mkdir"=> 0 , + "suffixlen" => 0, + "ErrStr" => \$errstr, + ) ); + + return $tmpname; +} + +=back + +=head1 POSIX FUNCTIONS + +This section describes the re-implementation of the tmpnam() +and tmpfile() functions described in L<POSIX> +using the mkstemp() from this module. + +Unlike the L<POSIX|POSIX> implementations, the directory used +for the temporary file is not specified in a system include +file (C<P_tmpdir>) but simply depends on the choice of tmpdir() +returned by L<File::Spec|File::Spec>. On some implementations this +location can be set using the C<TMPDIR> environment variable, which +may not be secure. +If this is a problem, simply use mkstemp() and specify a template. + +=over 4 + +=item B<tmpnam> + +When called in scalar context, returns the full name (including path) +of a temporary file (uses mktemp()). The only check is that the file does +not already exist, but there is no guarantee that that condition will +continue to apply. + + $file = tmpnam(); + +When called in list context, a filehandle to the open file and +a filename are returned. This is achieved by calling mkstemp() +after constructing a suitable template. + + ($fh, $file) = tmpnam(); + +If possible, this form should be used to prevent possible +race conditions. + +See L<File::Spec/tmpdir> for information on the choice of temporary +directory for a particular operating system. + +=cut + +sub tmpnam { + + # Retrieve the temporary directory name + my $tmpdir = File::Spec->tmpdir; + + croak "Error temporary directory is not writable" + if $tmpdir eq ''; + + # Use a ten character template and append to tmpdir + my $template = File::Spec->catfile($tmpdir, TEMPXXX); + + if (wantarray() ) { + return mkstemp($template); + } else { + return mktemp($template); + } + +} + +=item B<tmpfile> + +In scalar context, returns the filehandle of a temporary file. + + $fh = tmpfile(); + +The file is removed when the filehandle is closed or when the program +exits. No access to the filename is provided. + +If the temporary file can not be created undef is returned. +Currently this command will probably not work when the temporary +directory is on an NFS file system. + +=cut + +sub tmpfile { + + # Simply call tmpnam() in a list context + my ($fh, $file) = tmpnam(); + + # Make sure file is removed when filehandle is closed + # This will fail on NFS + unlink0($fh, $file) + or return undef; + + return $fh; + +} + +=back + +=head1 ADDITIONAL FUNCTIONS + +These functions are provided for backwards compatibility +with common tempfile generation C library functions. + +They are not exported and must be addressed using the full package +name. + +=over 4 + +=item B<tempnam> + +Return the name of a temporary file in the specified directory +using a prefix. The file is guaranteed not to exist at the time +the function was called, but such guarantees are good for one +clock tick only. Always use the proper form of C<sysopen> +with C<O_CREAT | O_EXCL> if you must open such a filename. + + $filename = File::Temp::tempnam( $dir, $prefix ); + +Equivalent to running mktemp() with $dir/$prefixXXXXXXXX +(using unix file convention as an example) + +Because this function uses mktemp(), it can suffer from race conditions. + +=cut + +sub tempnam { + + croak 'Usage tempnam($dir, $prefix)' unless scalar(@_) == 2; + + my ($dir, $prefix) = @_; + + # Add a string to the prefix + $prefix .= 'XXXXXXXX'; + + # Concatenate the directory to the file + my $template = File::Spec->catfile($dir, $prefix); + + return mktemp($template); + +} + +=back + +=head1 UTILITY FUNCTIONS + +Useful functions for dealing with the filehandle and filename. + +=over 4 + +=item B<unlink0> + +Given an open filehandle and the associated filename, make a safe +unlink. This is achieved by first checking that the filename and +filehandle initially point to the same file and that the number of +links to the file is 1 (all fields returned by stat() are compared). +Then the filename is unlinked and the filehandle checked once again to +verify that the number of links on that file is now 0. This is the +closest you can come to making sure that the filename unlinked was the +same as the file whose descriptor you hold. + + unlink0($fh, $path) or die "Error unlinking file $path safely"; + +Returns false on error. The filehandle is not closed since on some +occasions this is not required. + +On some platforms, for example Windows NT, it is not possible to +unlink an open file (the file must be closed first). On those +platforms, the actual unlinking is deferred until the program ends and +good status is returned. A check is still performed to make sure that +the filehandle and filename are pointing to the same thing (but not at +the time the end block is executed since the deferred removal may not +have access to the filehandle). + +Additionally, on Windows NT not all the fields returned by stat() can +be compared. For example, the C<dev> and C<rdev> fields seem to be +different. Also, it seems that the size of the file returned by stat() +does not always agree, with C<stat(FH)> being more accurate than +C<stat(filename)>, presumably because of caching issues even when +using autoflush (this is usually overcome by waiting a while after +writing to the tempfile before attempting to C<unlink0> it). + +Finally, on NFS file systems the link count of the file handle does +not always go to zero immediately after unlinking. Currently, this +command is expected to fail on NFS disks. + +=cut + +sub unlink0 { + + croak 'Usage: unlink0(filehandle, filename)' + unless scalar(@_) == 2; + + # Read args + my ($fh, $path) = @_; + + warn "Unlinking $path using unlink0\n" + if $DEBUG; + + # Stat the filehandle + my @fh = stat $fh; + + if ($fh[3] > 1 && $^W) { + carp "unlink0: fstat found too many links; SB=@fh" if $^W; + } + + # Stat the path + my @path = stat $path; + + unless (@path) { + carp "unlink0: $path is gone already" if $^W; + return; + } + + # this is no longer a file, but may be a directory, or worse + unless (-f _) { + confess "panic: $path is no longer a file: SB=@fh"; + } + + # Do comparison of each member of the array + # On WinNT dev and rdev seem to be different + # depending on whether it is a file or a handle. + # Cannot simply compare all members of the stat return + # Select the ones we can use + my @okstat = (0..$#fh); # Use all by default + if ($^O eq 'MSWin32') { + @okstat = (1,2,3,4,5,7,8,9,10); + } elsif ($^O eq 'os2') { + @okstat = (0, 2..$#fh); + } elsif ($^O eq 'VMS') { # device and file ID are sufficient + @okstat = (0, 1); + } elsif ($^O eq 'dos') { + @okstat = (0,2..7,11..$#fh); + } + + # Now compare each entry explicitly by number + for (@okstat) { + print "Comparing: $_ : $fh[$_] and $path[$_]\n" if $DEBUG; + # Use eq rather than == since rdev, blksize, and blocks (6, 11, + # and 12) will be '' on platforms that do not support them. This + # is fine since we are only comparing integers. + unless ($fh[$_] eq $path[$_]) { + warn "Did not match $_ element of stat\n" if $DEBUG; + return 0; + } + } + + # attempt remove the file (does not work on some platforms) + if (_can_unlink_opened_file()) { + # XXX: do *not* call this on a directory; possible race + # resulting in recursive removal + croak "unlink0: $path has become a directory!" if -d $path; + unlink($path) or return 0; + + # Stat the filehandle + @fh = stat $fh; + + print "Link count = $fh[3] \n" if $DEBUG; + + # Make sure that the link count is zero + # - Cygwin provides deferred unlinking, however, + # on Win9x the link count remains 1 + # On NFS the link count may still be 1 but we cant know that + # we are on NFS + return ( $fh[3] == 0 or $^O eq 'cygwin' ? 1 : 0); + + } else { + _deferred_unlink($fh, $path, 0); + return 1; + } + +} + +=back + +=head1 PACKAGE VARIABLES + +These functions control the global state of the package. + +=over 4 + +=item B<safe_level> + +Controls the lengths to which the module will go to check the safety of the +temporary file or directory before proceeding. +Options are: + +=over 8 + +=item STANDARD + +Do the basic security measures to ensure the directory exists and +is writable, that the umask() is fixed before opening of the file, +that temporary files are opened only if they do not already exist, and +that possible race conditions are avoided. Finally the L<unlink0|"unlink0"> +function is used to remove files safely. + +=item MEDIUM + +In addition to the STANDARD security, the output directory is checked +to make sure that it is owned either by root or the user running the +program. If the directory is writable by group or by other, it is then +checked to make sure that the sticky bit is set. + +Will not work on platforms that do not support the C<-k> test +for sticky bit. + +=item HIGH + +In addition to the MEDIUM security checks, also check for the +possibility of ``chown() giveaway'' using the L<POSIX|POSIX> +sysconf() function. If this is a possibility, each directory in the +path is checked in turn for safeness, recursively walking back to the +root directory. + +For platforms that do not support the L<POSIX|POSIX> +C<_PC_CHOWN_RESTRICTED> symbol (for example, Windows NT) it is +assumed that ``chown() giveaway'' is possible and the recursive test +is performed. + +=back + +The level can be changed as follows: + + File::Temp->safe_level( File::Temp::HIGH ); + +The level constants are not exported by the module. + +Currently, you must be running at least perl v5.6.0 in order to +run with MEDIUM or HIGH security. This is simply because the +safety tests use functions from L<Fcntl|Fcntl> that are not +available in older versions of perl. The problem is that the version +number for Fcntl is the same in perl 5.6.0 and in 5.005_03 even though +they are different versions. + +On systems that do not support the HIGH or MEDIUM safety levels +(for example Win NT or OS/2) any attempt to change the level will +be ignored. The decision to ignore rather than raise an exception +allows portable programs to be written with high security in mind +for the systems that can support this without those programs failing +on systems where the extra tests are irrelevant. + +If you really need to see whether the change has been accepted +simply examine the return value of C<safe_level>. + + $newlevel = File::Temp->safe_level( File::Temp::HIGH ); + die "Could not change to high security" + if $newlevel != File::Temp::HIGH; + +=cut + +{ + # protect from using the variable itself + my $LEVEL = STANDARD; + sub safe_level { + my $self = shift; + if (@_) { + my $level = shift; + if (($level != STANDARD) && ($level != MEDIUM) && ($level != HIGH)) { + carp "safe_level: Specified level ($level) not STANDARD, MEDIUM or HIGH - ignoring\n" if $^W; + } else { + # Dont allow this on perl 5.005 or earlier + if ($] < 5.006 && $level != STANDARD) { + # Cant do MEDIUM or HIGH checks + croak "Currently requires perl 5.006 or newer to do the safe checks"; + } + # Check that we are allowed to change level + # Silently ignore if we can not. + $LEVEL = $level if _can_do_level($level); + } + } + return $LEVEL; + } +} + +=item TopSystemUID + +This is the highest UID on the current system that refers to a root +UID. This is used to make sure that the temporary directory is +owned by a system UID (C<root>, C<bin>, C<sys> etc) rather than +simply by root. + +This is required since on many unix systems C</tmp> is not owned +by root. + +Default is to assume that any UID less than or equal to 10 is a root +UID. + + File::Temp->top_system_uid(10); + my $topid = File::Temp->top_system_uid; + +This value can be adjusted to reduce security checking if required. +The value is only relevant when C<safe_level> is set to MEDIUM or higher. + +=back + +=cut + +{ + my $TopSystemUID = 10; + sub top_system_uid { + my $self = shift; + if (@_) { + my $newuid = shift; + croak "top_system_uid: UIDs should be numeric" + unless $newuid =~ /^\d+$/s; + $TopSystemUID = $newuid; + } + return $TopSystemUID; + } +} + +=head1 WARNING + +For maximum security, endeavour always to avoid ever looking at, +touching, or even imputing the existence of the filename. You do not +know that that filename is connected to the same file as the handle +you have, and attempts to check this can only trigger more race +conditions. It's far more secure to use the filehandle alone and +dispense with the filename altogether. + +If you need to pass the handle to something that expects a filename +then, on a unix system, use C<"/dev/fd/" . fileno($fh)> for arbitrary +programs, or more generally C<< "+<=&" . fileno($fh) >> for Perl +programs. You will have to clear the close-on-exec bit on that file +descriptor before passing it to another process. + + use Fcntl qw/F_SETFD F_GETFD/; + fcntl($tmpfh, F_SETFD, 0) + or die "Can't clear close-on-exec flag on temp fh: $!\n"; + +=head2 Temporary files and NFS + +Some problems are associated with using temporary files that reside +on NFS file systems and it is recommended that a local filesystem +is used whenever possible. Some of the security tests will most probably +fail when the temp file is not local. Additionally, be aware that +the performance of I/O operations over NFS will not be as good as for +a local disk. + +=head1 HISTORY + +Originally began life in May 1999 as an XS interface to the system +mkstemp() function. In March 2000, the OpenBSD mkstemp() code was +translated to Perl for total control of the code's +security checking, to ensure the presence of the function regardless of +operating system and to help with portability. + +=head1 SEE ALSO + +L<POSIX/tmpnam>, L<POSIX/tmpfile>, L<File::Spec>, L<File::Path> + +See L<IO::File> and L<File::MkTemp> for different implementations of +temporary file handling. + +=head1 AUTHOR + +Tim Jenness E<lt>t.jenness@jach.hawaii.eduE<gt> + +Copyright (C) 1999-2001 Tim Jenness and the UK Particle Physics and +Astronomy Research Council. All Rights Reserved. This program is free +software; you can redistribute it and/or modify it under the same +terms as Perl itself. + +Original Perl implementation loosely based on the OpenBSD C code for +mkstemp(). Thanks to Tom Christiansen for suggesting that this module +should be written and providing ideas for code improvements and +security enhancements. + +=cut + + +1; diff --git a/lib/Temp/File-Temp-0.12/blib/arch/auto/File/Temp/.exists b/lib/Temp/File-Temp-0.12/blib/arch/auto/File/Temp/.exists new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/lib/Temp/File-Temp-0.12/blib/arch/auto/File/Temp/.exists diff --git a/lib/Temp/File-Temp-0.12/blib/lib/auto/File/Temp/.exists b/lib/Temp/File-Temp-0.12/blib/lib/auto/File/Temp/.exists new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/lib/Temp/File-Temp-0.12/blib/lib/auto/File/Temp/.exists diff --git a/lib/Temp/File-Temp-0.12/blib/man3/.exists b/lib/Temp/File-Temp-0.12/blib/man3/.exists new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/lib/Temp/File-Temp-0.12/blib/man3/.exists diff --git a/lib/Temp/File-Temp-0.12/blib/man3/File::Temp.3pm b/lib/Temp/File-Temp-0.12/blib/man3/File::Temp.3pm new file mode 100644 index 0000000..1b7e1f4 --- /dev/null +++ b/lib/Temp/File-Temp-0.12/blib/man3/File::Temp.3pm @@ -0,0 +1,681 @@ +.\" Automatically generated by Pod::Man v1.37, Pod::Parser v1.14 +.\" +.\" Standard preamble: +.\" ======================================================================== +.de Sh \" Subsection heading +.br +.if t .Sp +.ne 5 +.PP +\fB\\$1\fR +.PP +.. +.de Sp \" Vertical space (when we can't use .PP) +.if t .sp .5v +.if n .sp +.. +.de Vb \" Begin verbatim text +.ft CW +.nf +.ne \\$1 +.. +.de Ve \" End verbatim text +.ft R +.fi +.. +.\" Set up some character translations and predefined strings. \*(-- will +.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left +.\" double quote, and \*(R" will give a right double quote. | will give a +.\" real vertical bar. \*(C+ will give a nicer C++. Capital omega is used to +.\" do unbreakable dashes and therefore won't be available. \*(C` and \*(C' +.\" expand to `' in nroff, nothing in troff, for use with C<>. +.tr \(*W-|\(bv\*(Tr +.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' +.ie n \{\ +. ds -- \(*W- +. ds PI pi +. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch +. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch +. ds L" "" +. ds R" "" +. ds C` "" +. ds C' "" +'br\} +.el\{\ +. ds -- \|\(em\| +. ds PI \(*p +. ds L" `` +. ds R" '' +'br\} +.\" +.\" If the F register is turned on, we'll generate index entries on stderr for +.\" titles (.TH), headers (.SH), subsections (.Sh), items (.Ip), and index +.\" entries marked with X<> in POD. Of course, you'll have to process the +.\" output yourself in some meaningful fashion. +.if \nF \{\ +. de IX +. tm Index:\\$1\t\\n%\t"\\$2" +.. +. nr % 0 +. rr F +.\} +.\" +.\" For nroff, turn off justification. Always turn off hyphenation; it makes +.\" way too many mistakes in technical documents. +.hy 0 +.if n .na +.\" +.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). +.\" Fear. Run. Save yourself. No user-serviceable parts. +. \" fudge factors for nroff and troff +.if n \{\ +. ds #H 0 +. ds #V .8m +. ds #F .3m +. ds #[ \f1 +. ds #] \fP +.\} +.if t \{\ +. ds #H ((1u-(\\\\n(.fu%2u))*.13m) +. ds #V .6m +. ds #F 0 +. ds #[ \& +. ds #] \& +.\} +. \" simple accents for nroff and troff +.if n \{\ +. ds ' \& +. ds ` \& +. ds ^ \& +. ds , \& +. ds ~ ~ +. ds / +.\} +.if t \{\ +. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" +. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' +. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' +. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' +. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' +. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' +.\} +. \" troff and (daisy-wheel) nroff accents +.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' +.ds 8 \h'\*(#H'\(*b\h'-\*(#H' +.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] +.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' +.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' +.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] +.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] +.ds ae a\h'-(\w'a'u*4/10)'e +.ds Ae A\h'-(\w'A'u*4/10)'E +. \" corrections for vroff +.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' +.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' +. \" for low resolution devices (crt and lpr) +.if \n(.H>23 .if \n(.V>19 \ +\{\ +. ds : e +. ds 8 ss +. ds o a +. ds d- d\h'-1'\(ga +. ds D- D\h'-1'\(hy +. ds th \o'bp' +. ds Th \o'LP' +. ds ae ae +. ds Ae AE +.\} +.rm #[ #] #H #V #F C +.\" ======================================================================== +.\" +.IX Title "Temp 3" +.TH Temp 3 "2001-02-23" "perl v5.8.5" "User Contributed Perl Documentation" +.SH "NAME" +File::Temp \- return name and handle of a temporary file safely +.SH "SYNOPSIS" +.IX Header "SYNOPSIS" +.Vb 1 +\& use File::Temp qw/ tempfile tempdir /; +.Ve +.PP +.Vb 2 +\& $dir = tempdir( CLEANUP => 1 ); +\& ($fh, $filename) = tempfile( DIR => $dir ); +.Ve +.PP +.Vb 2 +\& ($fh, $filename) = tempfile( $template, DIR => $dir); +\& ($fh, $filename) = tempfile( $template, SUFFIX => '.dat'); +.Ve +.PP +.Vb 1 +\& $fh = tempfile(); +.Ve +.PP +MkTemp family: +.PP +.Vb 1 +\& use File::Temp qw/ :mktemp /; +.Ve +.PP +.Vb 2 +\& ($fh, $file) = mkstemp( "tmpfileXXXXX" ); +\& ($fh, $file) = mkstemps( "tmpfileXXXXXX", $suffix); +.Ve +.PP +.Vb 1 +\& $tmpdir = mkdtemp( $template ); +.Ve +.PP +.Vb 1 +\& $unopened_file = mktemp( $template ); +.Ve +.PP +\&\s-1POSIX\s0 functions: +.PP +.Vb 1 +\& use File::Temp qw/ :POSIX /; +.Ve +.PP +.Vb 2 +\& $file = tmpnam(); +\& $fh = tmpfile(); +.Ve +.PP +.Vb 2 +\& ($fh, $file) = tmpnam(); +\& ($fh, $file) = tmpfile(); +.Ve +.PP +Compatibility functions: +.PP +.Vb 1 +\& $unopened_file = File::Temp::tempnam( $dir, $pfx ); +.Ve +.SH "DESCRIPTION" +.IX Header "DESCRIPTION" +\&\f(CW\*(C`File::Temp\*(C'\fR can be used to create and open temporary files in a safe way. +The \fItempfile()\fR function can be used to return the name and the open +filehandle of a temporary file. The \fItempdir()\fR function can +be used to create a temporary directory. +.PP +The security aspect of temporary file creation is emphasized such that +a filehandle and filename are returned together. This helps guarantee +that a race condition can not occur where the temporary file is +created by another process between checking for the existence of the +file and its opening. Additional security levels are provided to +check, for example, that the sticky bit is set on world writable +directories. See \*(L"safe_level\*(R" for more information. +.PP +For compatibility with popular C library functions, Perl implementations of +the \fImkstemp()\fR family of functions are provided. These are, \fImkstemp()\fR, +\&\fImkstemps()\fR, \fImkdtemp()\fR and \fImktemp()\fR. +.PP +Additionally, implementations of the standard \s-1POSIX\s0 +\&\fItmpnam()\fR and \fItmpfile()\fR functions are provided if required. +.PP +Implementations of \fImktemp()\fR, \fItmpnam()\fR, and \fItempnam()\fR are provided, +but should be used with caution since they return only a filename +that was valid when function was called, so cannot guarantee +that the file will not exist by the time the caller opens the filename. +.SH "FUNCTIONS" +.IX Header "FUNCTIONS" +This section describes the recommended interface for generating +temporary files and directories. +.IP "\fBtempfile\fR" 4 +.IX Item "tempfile" +This is the basic function to generate temporary files. +The behaviour of the file can be changed using various options: +.Sp +.Vb 1 +\& ($fh, $filename) = tempfile(); +.Ve +.Sp +Create a temporary file in the directory specified for temporary +files, as specified by the \fItmpdir()\fR function in File::Spec. +.Sp +.Vb 1 +\& ($fh, $filename) = tempfile($template); +.Ve +.Sp +Create a temporary file in the current directory using the supplied +template. Trailing `X' characters are replaced with random letters to +generate the filename. At least four `X' characters must be present +in the template. +.Sp +.Vb 1 +\& ($fh, $filename) = tempfile($template, SUFFIX => $suffix) +.Ve +.Sp +Same as previously, except that a suffix is added to the template +after the `X' translation. Useful for ensuring that a temporary +filename has a particular extension when needed by other applications. +But see the \s-1WARNING\s0 at the end. +.Sp +.Vb 1 +\& ($fh, $filename) = tempfile($template, DIR => $dir); +.Ve +.Sp +Translates the template as before except that a directory name +is specified. +.Sp +.Vb 1 +\& ($fh, $filename) = tempfile($template, UNLINK => 1); +.Ve +.Sp +Return the filename and filehandle as before except that the file is +automatically removed when the program exits. Default is for the file +to be removed if a file handle is requested and to be kept if the +filename is requested. In a scalar context (where no filename is +returned) the file is always deleted either on exit or when it is closed. +.Sp +If the template is not specified, a template is always +automatically generated. This temporary file is placed in \fItmpdir()\fR +(File::Spec) unless a directory is specified explicitly with the +\&\s-1DIR\s0 option. +.Sp +.Vb 1 +\& $fh = tempfile( $template, DIR => $dir ); +.Ve +.Sp +If called in scalar context, only the filehandle is returned +and the file will automatically be deleted when closed (see +the description of \fItmpfile()\fR elsewhere in this document). +This is the preferred mode of operation, as if you only +have a filehandle, you can never create a race condition +by fumbling with the filename. On systems that can not unlink +an open file or can not mark a file as temporary when it is opened +(for example, Windows \s-1NT\s0 uses the \f(CW\*(C`O_TEMPORARY\*(C'\fR flag)) +the file is marked for deletion when the program ends (equivalent +to setting \s-1UNLINK\s0 to 1). The \f(CW\*(C`UNLINK\*(C'\fR flag is ignored if present. +.Sp +.Vb 1 +\& (undef, $filename) = tempfile($template, OPEN => 0); +.Ve +.Sp +This will return the filename based on the template but +will not open this file. Cannot be used in conjunction with +\&\s-1UNLINK\s0 set to true. Default is to always open the file +to protect from possible race conditions. A warning is issued +if warnings are turned on. Consider using the \fItmpnam()\fR +and \fImktemp()\fR functions described elsewhere in this document +if opening the file is not required. +.Sp +Options can be combined as required. +.IP "\fBtempdir\fR" 4 +.IX Item "tempdir" +This is the recommended interface for creation of temporary directories. +The behaviour of the function depends on the arguments: +.Sp +.Vb 1 +\& $tempdir = tempdir(); +.Ve +.Sp +Create a directory in \fItmpdir()\fR (see File::Spec). +.Sp +.Vb 1 +\& $tempdir = tempdir( $template ); +.Ve +.Sp +Create a directory from the supplied template. This template is +similar to that described for \fItempfile()\fR. `X' characters at the end +of the template are replaced with random letters to construct the +directory name. At least four `X' characters must be in the template. +.Sp +.Vb 1 +\& $tempdir = tempdir ( DIR => $dir ); +.Ve +.Sp +Specifies the directory to use for the temporary directory. +The temporary directory name is derived from an internal template. +.Sp +.Vb 1 +\& $tempdir = tempdir ( $template, DIR => $dir ); +.Ve +.Sp +Prepend the supplied directory name to the template. The template +should not include parent directory specifications itself. Any parent +directory specifications are removed from the template before +prepending the supplied directory. +.Sp +.Vb 1 +\& $tempdir = tempdir ( $template, TMPDIR => 1 ); +.Ve +.Sp +Using the supplied template, creat the temporary directory in +a standard location for temporary files. Equivalent to doing +.Sp +.Vb 1 +\& $tempdir = tempdir ( $template, DIR => File::Spec->tmpdir); +.Ve +.Sp +but shorter. Parent directory specifications are stripped from the +template itself. The \f(CW\*(C`TMPDIR\*(C'\fR option is ignored if \f(CW\*(C`DIR\*(C'\fR is set +explicitly. Additionally, \f(CW\*(C`TMPDIR\*(C'\fR is implied if neither a template +nor a directory are supplied. +.Sp +.Vb 1 +\& $tempdir = tempdir( $template, CLEANUP => 1); +.Ve +.Sp +Create a temporary directory using the supplied template, but +attempt to remove it (and all files inside it) when the program +exits. Note that an attempt will be made to remove all files from +the directory even if they were not created by this module (otherwise +why ask to clean it up?). The directory removal is made with +the \fIrmtree()\fR function from the File::Path module. +Of course, if the template is not specified, the temporary directory +will be created in \fItmpdir()\fR and will also be removed at program exit. +.SH "MKTEMP FUNCTIONS" +.IX Header "MKTEMP FUNCTIONS" +The following functions are Perl implementations of the +\&\fImktemp()\fR family of temp file generation system calls. +.IP "\fBmkstemp\fR" 4 +.IX Item "mkstemp" +Given a template, returns a filehandle to the temporary file and the name +of the file. +.Sp +.Vb 1 +\& ($fh, $name) = mkstemp( $template ); +.Ve +.Sp +In scalar context, just the filehandle is returned. +.Sp +The template may be any filename with some number of X's appended +to it, for example \fI/tmp/temp.XXXX\fR. The trailing X's are replaced +with unique alphanumeric combinations. +.IP "\fBmkstemps\fR" 4 +.IX Item "mkstemps" +Similar to \fImkstemp()\fR, except that an extra argument can be supplied +with a suffix to be appended to the template. +.Sp +.Vb 1 +\& ($fh, $name) = mkstemps( $template, $suffix ); +.Ve +.Sp +For example a template of \f(CW\*(C`testXXXXXX\*(C'\fR and suffix of \f(CW\*(C`.dat\*(C'\fR +would generate a file similar to \fItesthGji_w.dat\fR. +.Sp +Returns just the filehandle alone when called in scalar context. +.IP "\fBmkdtemp\fR" 4 +.IX Item "mkdtemp" +Create a directory from a template. The template must end in +X's that are replaced by the routine. +.Sp +.Vb 1 +\& $tmpdir_name = mkdtemp($template); +.Ve +.Sp +Returns the name of the temporary directory created. +Returns undef on failure. +.Sp +Directory must be removed by the caller. +.IP "\fBmktemp\fR" 4 +.IX Item "mktemp" +Returns a valid temporary filename but does not guarantee +that the file will not be opened by someone else. +.Sp +.Vb 1 +\& $unopened_file = mktemp($template); +.Ve +.Sp +Template is the same as that required by \fImkstemp()\fR. +.SH "POSIX FUNCTIONS" +.IX Header "POSIX FUNCTIONS" +This section describes the re-implementation of the \fItmpnam()\fR +and \fItmpfile()\fR functions described in \s-1POSIX\s0 +using the \fImkstemp()\fR from this module. +.PP +Unlike the \s-1POSIX\s0 implementations, the directory used +for the temporary file is not specified in a system include +file (\f(CW\*(C`P_tmpdir\*(C'\fR) but simply depends on the choice of \fItmpdir()\fR +returned by File::Spec. On some implementations this +location can be set using the \f(CW\*(C`TMPDIR\*(C'\fR environment variable, which +may not be secure. +If this is a problem, simply use \fImkstemp()\fR and specify a template. +.IP "\fBtmpnam\fR" 4 +.IX Item "tmpnam" +When called in scalar context, returns the full name (including path) +of a temporary file (uses \fImktemp()\fR). The only check is that the file does +not already exist, but there is no guarantee that that condition will +continue to apply. +.Sp +.Vb 1 +\& $file = tmpnam(); +.Ve +.Sp +When called in list context, a filehandle to the open file and +a filename are returned. This is achieved by calling \fImkstemp()\fR +after constructing a suitable template. +.Sp +.Vb 1 +\& ($fh, $file) = tmpnam(); +.Ve +.Sp +If possible, this form should be used to prevent possible +race conditions. +.Sp +See \*(L"tmpdir\*(R" in File::Spec for information on the choice of temporary +directory for a particular operating system. +.IP "\fBtmpfile\fR" 4 +.IX Item "tmpfile" +In scalar context, returns the filehandle of a temporary file. +.Sp +.Vb 1 +\& $fh = tmpfile(); +.Ve +.Sp +The file is removed when the filehandle is closed or when the program +exits. No access to the filename is provided. +.Sp +If the temporary file can not be created undef is returned. +Currently this command will probably not work when the temporary +directory is on an \s-1NFS\s0 file system. +.SH "ADDITIONAL FUNCTIONS" +.IX Header "ADDITIONAL FUNCTIONS" +These functions are provided for backwards compatibility +with common tempfile generation C library functions. +.PP +They are not exported and must be addressed using the full package +name. +.IP "\fBtempnam\fR" 4 +.IX Item "tempnam" +Return the name of a temporary file in the specified directory +using a prefix. The file is guaranteed not to exist at the time +the function was called, but such guarantees are good for one +clock tick only. Always use the proper form of \f(CW\*(C`sysopen\*(C'\fR +with \f(CW\*(C`O_CREAT | O_EXCL\*(C'\fR if you must open such a filename. +.Sp +.Vb 1 +\& $filename = File::Temp::tempnam( $dir, $prefix ); +.Ve +.Sp +Equivalent to running \fImktemp()\fR with \f(CW$dir\fR/$prefixXXXXXXXX +(using unix file convention as an example) +.Sp +Because this function uses \fImktemp()\fR, it can suffer from race conditions. +.SH "UTILITY FUNCTIONS" +.IX Header "UTILITY FUNCTIONS" +Useful functions for dealing with the filehandle and filename. +.IP "\fBunlink0\fR" 4 +.IX Item "unlink0" +Given an open filehandle and the associated filename, make a safe +unlink. This is achieved by first checking that the filename and +filehandle initially point to the same file and that the number of +links to the file is 1 (all fields returned by \fIstat()\fR are compared). +Then the filename is unlinked and the filehandle checked once again to +verify that the number of links on that file is now 0. This is the +closest you can come to making sure that the filename unlinked was the +same as the file whose descriptor you hold. +.Sp +.Vb 1 +\& unlink0($fh, $path) or die "Error unlinking file $path safely"; +.Ve +.Sp +Returns false on error. The filehandle is not closed since on some +occasions this is not required. +.Sp +On some platforms, for example Windows \s-1NT\s0, it is not possible to +unlink an open file (the file must be closed first). On those +platforms, the actual unlinking is deferred until the program ends and +good status is returned. A check is still performed to make sure that +the filehandle and filename are pointing to the same thing (but not at +the time the end block is executed since the deferred removal may not +have access to the filehandle). +.Sp +Additionally, on Windows \s-1NT\s0 not all the fields returned by \fIstat()\fR can +be compared. For example, the \f(CW\*(C`dev\*(C'\fR and \f(CW\*(C`rdev\*(C'\fR fields seem to be +different. Also, it seems that the size of the file returned by \fIstat()\fR +does not always agree, with \f(CW\*(C`stat(FH)\*(C'\fR being more accurate than +\&\f(CW\*(C`stat(filename)\*(C'\fR, presumably because of caching issues even when +using autoflush (this is usually overcome by waiting a while after +writing to the tempfile before attempting to \f(CW\*(C`unlink0\*(C'\fR it). +.Sp +Finally, on \s-1NFS\s0 file systems the link count of the file handle does +not always go to zero immediately after unlinking. Currently, this +command is expected to fail on \s-1NFS\s0 disks. +.SH "PACKAGE VARIABLES" +.IX Header "PACKAGE VARIABLES" +These functions control the global state of the package. +.IP "\fBsafe_level\fR" 4 +.IX Item "safe_level" +Controls the lengths to which the module will go to check the safety of the +temporary file or directory before proceeding. +Options are: +.RS 4 +.IP "\s-1STANDARD\s0" 8 +.IX Item "STANDARD" +Do the basic security measures to ensure the directory exists and +is writable, that the \fIumask()\fR is fixed before opening of the file, +that temporary files are opened only if they do not already exist, and +that possible race conditions are avoided. Finally the unlink0 +function is used to remove files safely. +.IP "\s-1MEDIUM\s0" 8 +.IX Item "MEDIUM" +In addition to the \s-1STANDARD\s0 security, the output directory is checked +to make sure that it is owned either by root or the user running the +program. If the directory is writable by group or by other, it is then +checked to make sure that the sticky bit is set. +.Sp +Will not work on platforms that do not support the \f(CW\*(C`\-k\*(C'\fR test +for sticky bit. +.IP "\s-1HIGH\s0" 8 +.IX Item "HIGH" +In addition to the \s-1MEDIUM\s0 security checks, also check for the +possibility of ``\fIchown()\fR giveaway'' using the \s-1POSIX\s0 +\&\fIsysconf()\fR function. If this is a possibility, each directory in the +path is checked in turn for safeness, recursively walking back to the +root directory. +.Sp +For platforms that do not support the \s-1POSIX\s0 +\&\f(CW\*(C`_PC_CHOWN_RESTRICTED\*(C'\fR symbol (for example, Windows \s-1NT\s0) it is +assumed that ``\fIchown()\fR giveaway'' is possible and the recursive test +is performed. +.RE +.RS 4 +.Sp +The level can be changed as follows: +.Sp +.Vb 1 +\& File::Temp->safe_level( File::Temp::HIGH ); +.Ve +.Sp +The level constants are not exported by the module. +.Sp +Currently, you must be running at least perl v5.6.0 in order to +run with \s-1MEDIUM\s0 or \s-1HIGH\s0 security. This is simply because the +safety tests use functions from Fcntl that are not +available in older versions of perl. The problem is that the version +number for Fcntl is the same in perl 5.6.0 and in 5.005_03 even though +they are different versions. +.Sp +On systems that do not support the \s-1HIGH\s0 or \s-1MEDIUM\s0 safety levels +(for example Win \s-1NT\s0 or \s-1OS/2\s0) any attempt to change the level will +be ignored. The decision to ignore rather than raise an exception +allows portable programs to be written with high security in mind +for the systems that can support this without those programs failing +on systems where the extra tests are irrelevant. +.Sp +If you really need to see whether the change has been accepted +simply examine the return value of \f(CW\*(C`safe_level\*(C'\fR. +.Sp +.Vb 3 +\& $newlevel = File::Temp->safe_level( File::Temp::HIGH ); +\& die "Could not change to high security" +\& if $newlevel != File::Temp::HIGH; +.Ve +.RE +.IP "TopSystemUID" 4 +.IX Item "TopSystemUID" +This is the highest \s-1UID\s0 on the current system that refers to a root +\&\s-1UID\s0. This is used to make sure that the temporary directory is +owned by a system \s-1UID\s0 (\f(CW\*(C`root\*(C'\fR, \f(CW\*(C`bin\*(C'\fR, \f(CW\*(C`sys\*(C'\fR etc) rather than +simply by root. +.Sp +This is required since on many unix systems \f(CW\*(C`/tmp\*(C'\fR is not owned +by root. +.Sp +Default is to assume that any \s-1UID\s0 less than or equal to 10 is a root +\&\s-1UID\s0. +.Sp +.Vb 2 +\& File::Temp->top_system_uid(10); +\& my $topid = File::Temp->top_system_uid; +.Ve +.Sp +This value can be adjusted to reduce security checking if required. +The value is only relevant when \f(CW\*(C`safe_level\*(C'\fR is set to \s-1MEDIUM\s0 or higher. +.SH "WARNING" +.IX Header "WARNING" +For maximum security, endeavour always to avoid ever looking at, +touching, or even imputing the existence of the filename. You do not +know that that filename is connected to the same file as the handle +you have, and attempts to check this can only trigger more race +conditions. It's far more secure to use the filehandle alone and +dispense with the filename altogether. +.PP +If you need to pass the handle to something that expects a filename +then, on a unix system, use \f(CW\*(C`"/dev/fd/" . fileno($fh)\*(C'\fR for arbitrary +programs, or more generally \f(CW\*(C`"+<=&" . fileno($fh)\*(C'\fR for Perl +programs. You will have to clear the close-on-exec bit on that file +descriptor before passing it to another process. +.PP +.Vb 3 +\& use Fcntl qw/F_SETFD F_GETFD/; +\& fcntl($tmpfh, F_SETFD, 0) +\& or die "Can't clear close-on-exec flag on temp fh: $!\en"; +.Ve +.Sh "Temporary files and \s-1NFS\s0" +.IX Subsection "Temporary files and NFS" +Some problems are associated with using temporary files that reside +on \s-1NFS\s0 file systems and it is recommended that a local filesystem +is used whenever possible. Some of the security tests will most probably +fail when the temp file is not local. Additionally, be aware that +the performance of I/O operations over \s-1NFS\s0 will not be as good as for +a local disk. +.SH "HISTORY" +.IX Header "HISTORY" +Originally began life in May 1999 as an \s-1XS\s0 interface to the system +\&\fImkstemp()\fR function. In March 2000, the OpenBSD \fImkstemp()\fR code was +translated to Perl for total control of the code's +security checking, to ensure the presence of the function regardless of +operating system and to help with portability. +.SH "SEE ALSO" +.IX Header "SEE ALSO" +\&\*(L"tmpnam\*(R" in \s-1POSIX\s0, \*(L"tmpfile\*(R" in \s-1POSIX\s0, File::Spec, File::Path +.PP +See IO::File and File::MkTemp for different implementations of +temporary file handling. +.SH "AUTHOR" +.IX Header "AUTHOR" +Tim Jenness <t.jenness@jach.hawaii.edu> +.PP +Copyright (C) 1999\-2001 Tim Jenness and the \s-1UK\s0 Particle Physics and +Astronomy Research Council. All Rights Reserved. This program is free +software; you can redistribute it and/or modify it under the same +terms as Perl itself. +.PP +Original Perl implementation loosely based on the OpenBSD C code for +\&\fImkstemp()\fR. Thanks to Tom Christiansen for suggesting that this module +should be written and providing ideas for code improvements and +security enhancements. diff --git a/lib/Temp/File-Temp-0.12/misc/benchmark.pl b/lib/Temp/File-Temp-0.12/misc/benchmark.pl new file mode 100755 index 0000000..bdea837 --- /dev/null +++ b/lib/Temp/File-Temp-0.12/misc/benchmark.pl @@ -0,0 +1,42 @@ +#!/usr/local/bin/perl -w + +# Simple benchmark of temporary file creation (no filename just a handle) +# Uses the following: +# - temporary file creation created by IO::File +# - temporary file creation using File::Temp (uses security checking) +# - A roll-our-own wrapper on top of POSIX::tempnam (essentially +# a compact form of File::Temp without all the extras) taken from +# the Perl cookbook + +# Would not + +use strict; +use Benchmark; +use IO::File; +use POSIX qw/ tmpnam /; +use File::Temp qw/ tempfile /; +use Symbol; + +# Benchmark IO::File and File::Temp + +timethese(10000, { + 'IO::File' => sub { + my $fh = IO::File::new_tmpfile || die $ !; + }, + 'File::Temp::tempfile' => sub { + my $fh = tempfile() || die $ !; + }, + 'POSIX::tmpnam' => sub { + my $fh = gensym;; + my $name; + for (;;) { + $name = tmpnam(); + sysopen( $fh, $name, O_RDWR | O_CREAT | O_EXCL ) + && last; + } + unlink $name; + } + } + ); + + diff --git a/lib/Temp/File-Temp-0.12/misc/results.txt b/lib/Temp/File-Temp-0.12/misc/results.txt new file mode 100644 index 0000000..b73196a --- /dev/null +++ b/lib/Temp/File-Temp-0.12/misc/results.txt @@ -0,0 +1,33 @@ +This file contains the results of the File::Temp benchmark script +by File::Temp version, perl version and OS. + +On Windows NT, currently have problems with this benchmark since it +runs into a file limit after a while (this is because unlinking of the +open file is deferred until the end of the program rather than closing +it and unlinking it explcitly round the loop). + +Times are in CPU seconds. + +VERSION PERL OS File::Temp/s IO::File/s POSIX::tmpnam + +0.07 5.6.0 linux(1) 22.4 1.7 2.1 + 5.005_03 linux(1) 33.6 1.6 2.1 + +0.08 5.6.0 linux(1) 8.1 1.7 2.1 + 5.005_03 linux(1) 8.4 1.6 2.1 + + 5.6.0 solaris(2) 32.3 237.0 229.5 + + 5.005_03 dig.unix(3) 153.2 44.9 51.5 + + + + +1. A 600 MHz pentium III running RedHat 6.1 + +2. A Sparc Ultra 1 running Solaris 2.6. /tmp local, /var/tmp on NFS + (/var/tmp is the default temp location on Solaris and is used by + POSIX::tmpnam whereas /tmp is used by File::Temp since that is the + location specified by File::Spec) + +3. DEC 3000 Alpha running digital unix 4.0. diff --git a/lib/Temp/File-Temp-0.12/pm_to_blib b/lib/Temp/File-Temp-0.12/pm_to_blib new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/lib/Temp/File-Temp-0.12/pm_to_blib diff --git a/lib/Temp/File-Temp-0.12/t/mktemp.t b/lib/Temp/File-Temp-0.12/t/mktemp.t new file mode 100755 index 0000000..2014e30 --- /dev/null +++ b/lib/Temp/File-Temp-0.12/t/mktemp.t @@ -0,0 +1,110 @@ +#!/usr/local/bin/perl -w + +# Test for mktemp family of commands in File::Temp +# Use STANDARD safe level for these tests + +use strict; +use Test; +BEGIN { plan tests => 9 } + +use File::Spec; +use File::Path; +use File::Temp qw/ :mktemp unlink0 /; +use FileHandle; + +ok(1); + +# MKSTEMP - test + +# Create file in temp directory +my $template = File::Spec->catfile(File::Spec->tmpdir, 'wowserXXXX'); + +(my $fh, $template) = mkstemp($template); + +print "# MKSTEMP: FH is $fh File is $template fileno=".fileno($fh)."\n"; +# Check if the file exists +ok( (-e $template) ); + +# Autoflush +$fh->autoflush(1) if $] >= 5.006; + +# Try printing something to the file +my $string = "woohoo\n"; +print $fh $string; + +# rewind the file +ok(seek( $fh, 0, 0)); + +# Read from the file +my $line = <$fh>; + +# compare with previous string +ok($string, $line); + +# Tidy up +# This test fails on Windows NT since it seems that the size returned by +# stat(filehandle) does not always equal the size of the stat(filename) +# This must be due to caching. In particular this test writes 7 bytes +# to the file which are not recognised by stat(filename) +# Simply waiting 3 seconds seems to be enough for the system to update + +if ($^O eq 'MSWin32') { + sleep 3; +} +my $status = unlink0($fh, $template); +if ($status) { + ok( $status ); +} else { + skip("Skip test failed probably due to \$TMPDIR being on NFS",1); +} + +# MKSTEMPS +# File with suffix. This is created in the current directory so +# may be problematic on NFS + +$template = "suffixXXXXXX"; +my $suffix = ".dat"; + +($fh, my $fname) = mkstemps($template, $suffix); + +print "# MKSTEMPS: File is $template -> $fname fileno=".fileno($fh)."\n"; +# Check if the file exists +ok( (-e $fname) ); + +# This fails if you are running on NFS +# If this test fails simply skip it rather than doing a hard failure +$status = unlink0($fh, $fname); + +if ($status) { + ok($status); +} else { + skip("Skip test failed probably due to cwd being on NFS",1) +} + +# MKDTEMP +# Temp directory + +$template = File::Spec->catdir(File::Spec->tmpdir, 'tmpdirXXXXXX'); + +my $tmpdir = mkdtemp($template); + +print "# MKDTEMP: Name is $tmpdir from template $template\n"; + +ok( (-d $tmpdir ) ); + +# Need to tidy up after myself +rmtree($tmpdir); + +# MKTEMP +# Just a filename, not opened + +$template = File::Spec->catfile(File::Spec->tmpdir, 'mytestXXXXXX'); + +my $tmpfile = mktemp($template); + +print "# MKTEMP: Tempfile is $template -> $tmpfile\n"; + +# Okay if template no longer has XXXXX in + + +ok( ($tmpfile !~ /XXXXX$/) ); diff --git a/lib/Temp/File-Temp-0.12/t/posix.t b/lib/Temp/File-Temp-0.12/t/posix.t new file mode 100755 index 0000000..b63fb29 --- /dev/null +++ b/lib/Temp/File-Temp-0.12/t/posix.t @@ -0,0 +1,77 @@ +#!/usr/local/bin/perl -w +# Test for File::Temp - POSIX functions + +use strict; +use Test; +BEGIN { plan tests => 7} + +use File::Temp qw/ :POSIX unlink0 /; +use FileHandle; +ok(1); + +# TMPNAM - scalar + +print "# TMPNAM: in a scalar context: \n"; +my $tmpnam = tmpnam(); + +# simply check that the file does not exist +# Not a 100% water tight test though if another program +# has managed to create one in the meantime. +ok( !(-e $tmpnam )); + +print "# TMPNAM file name: $tmpnam\n"; + +# TMPNAM list context +# Not strict posix behaviour +(my $fh, $tmpnam) = tmpnam(); + +print "# TMPNAM: in list context: $fh $tmpnam\n"; + +# File is opened - make sure it exists +ok( (-e $tmpnam )); + +# Unlink it - a possible NFS issue again if TMPDIR is not a local disk +my $status = unlink0($fh, $tmpnam); +if ($status) { + ok( $status ); +} else { + skip("Skip test failed probably due to \$TMPDIR being on NFS",1); +} + +# TMPFILE + +$fh = tmpfile(); + +if (defined $fh) { + ok( $fh ); + print "# TMPFILE: tmpfile got FH $fh\n"; + + $fh->autoflush(1) if $] >= 5.006; + + # print something to it + my $original = "Hello a test\n"; + print "# TMPFILE: Wrote line: $original"; + print $fh $original + or die "Error printing to tempfile\n"; + + # rewind it + ok( seek($fh,0,0) ); + + # Read from it + my $line = <$fh>; + + print "# TMPFILE: Read line: $line"; + ok( $original, $line); + + close($fh); + +} else { + # Skip all the remaining tests + foreach (1..3) { + skip("Skip test failed probably due to \$TMPDIR being on NFS",1); + } +} + + + + diff --git a/lib/Temp/File-Temp-0.12/t/security.t b/lib/Temp/File-Temp-0.12/t/security.t new file mode 100755 index 0000000..f08f6db --- /dev/null +++ b/lib/Temp/File-Temp-0.12/t/security.t @@ -0,0 +1,136 @@ +#!/usr/bin/perl -w +# Test for File::Temp - Security levels + +# Some of the security checking will not work on all platforms +# Test a simple open in the cwd and tmpdir foreach of the +# security levels + +use Test; +BEGIN { plan tests => 13 } + +use strict; +use File::Spec; + +# Set up END block - this needs to happen before we load +# File::Temp since this END block must be evaluated after the +# END block configured by File::Temp +my @files; # list of files to remove +END { foreach (@files) { ok( !(-e $_) )} } + +use File::Temp qw/ tempfile unlink0 /; +ok(1); + +# The high security tests must currently be skipped on some platforms +my $skipplat = ( ( + # No sticky bits. + $^O eq 'MSWin32' || $^O eq 'os2' || $^O eq 'dos' + ) ? 1 : 0 ); + +# Can not run high security tests in perls before 5.6.0 +my $skipperl = ($] < 5.006 ? 1 : 0 ); + +# Determine whether we need to skip things and why +my $skip = 0; +if ($skipplat) { + $skip = "Skip Not supported on this platform"; +} elsif ($skipperl) { + $skip = "Skip Perl version must be v5.6.0 for these tests"; + +} + +print "# We will be skipping some tests : $skip\n" if $skip; + +# start off with basic checking + +File::Temp->safe_level( File::Temp::STANDARD ); + +print "# Testing with STANDARD security...\n"; + +&test_security(0); + +# Try medium + +File::Temp->safe_level( File::Temp::MEDIUM ) + unless $skip; + +print "# Testing with MEDIUM security...\n"; + +# Now we need to start skipping tests +&test_security($skip); + +# Try HIGH + +File::Temp->safe_level( File::Temp::HIGH ) + unless $skip; + +print "# Testing with HIGH security...\n"; + +&test_security($skip); + +exit; + +# Subroutine to open two temporary files. +# one is opened in the current dir and the other in the temp dir + +sub test_security { + + # Read in the skip flag + my $skip = shift; + + # If we are skipping we need to simply fake the correct number + # of tests -- we dont use skip since the tempfile() commands will + # fail with MEDIUM/HIGH security before the skip() command would be run + if ($skip) { + + skip($skip,1); + skip($skip,1); + + # plus we need an end block so the tests come out in the right order + eval q{ END { skip($skip,1); skip($skip,1) } 1; } || die; + + return; + } + + # Create the tempfile + my $template = "tmpXXXXX"; + my ($fh1, $fname1) = eval { tempfile ( $template, + DIR => File::Spec->tmpdir, + UNLINK => 1, + ); + }; + + if (defined $fname1) { + print "# fname1 = $fname1\n"; + ok( (-e $fname1) ); + push(@files, $fname1); # store for end block + } elsif (File::Temp->safe_level() != File::Temp::STANDARD) { + my $skip2 = "Skip system possibly insecure, see INSTALL, section 'make test'"; + skip($skip2, 1); + # plus we need an end block so the tests come out in the right order + eval q{ END { skip($skip2,1); } 1; } || die; + } else { + ok(0); + } + + # Explicitly + if ( $< < File::Temp->top_system_uid() ){ + skip("Skip Test inappropriate for root", 1); + eval q{ END { skip($skip,1); } 1; } || die; + return; + } + my ($fh2, $fname2) = eval { tempfile ($template, UNLINK => 1 ); }; + if (defined $fname2) { + print "# fname2 = $fname2\n"; + ok( (-e $fname2) ); + push(@files, $fname2); # store for end block + close($fh2); + } elsif (File::Temp->safe_level() != File::Temp::STANDARD) { + my $skip2 = "Skip system possibly insecure, see INSTALL, section 'make test'"; + skip($skip2, 1); + # plus we need an end block so the tests come out in the right order + eval q{ END { skip($skip2,1); } 1; } || die; + } else { + ok(0); + } + +} diff --git a/lib/Temp/File-Temp-0.12/t/tempfile.t b/lib/Temp/File-Temp-0.12/t/tempfile.t new file mode 100644 index 0000000..6e3fa94 --- /dev/null +++ b/lib/Temp/File-Temp-0.12/t/tempfile.t @@ -0,0 +1,140 @@ +#!/usr/local/bin/perl -w +# Test for File::Temp - tempfile function + +use strict; +use Test; +BEGIN { plan tests => 20} +use File::Spec; + +# Will need to check that all files were unlinked correctly +# Set up an END block here to do it + +# Arrays containing list of dirs/files to test +my (@files, @dirs, @still_there); + +# And a test for files that should still be around +# These are tidied up +END { + foreach (@still_there) { + ok( -f $_ ); + ok( unlink( $_ ) ); + ok( !(-f $_) ); + } +} + +# Loop over an array hoping that the files dont exist +END { foreach (@files) { ok( !(-e $_) )} } + +# And a test for directories +END { foreach (@dirs) { ok( !(-d $_) )} } + +# Need to make sure that the END blocks are setup before +# the ones that File::Temp configures since END blocks are evaluated +# in revers order and we need to check the files *after* File::Temp +# removes them +use File::Temp qw/ tempfile tempdir/; + +# Now we start the tests properly +ok(1); + + +# Tempfile +# Open tempfile in some directory, unlink at end +my ($fh, $tempfile) = tempfile( + UNLINK => 1, + SUFFIX => '.txt', + ); + +ok( (-f $tempfile) ); +# Should still be around after closing +ok( close( $fh ) ); +ok( (-f $tempfile) ); +# Check again at exit +push(@files, $tempfile); + +# TEMPDIR test +# Create temp directory in current dir +my $template = 'tmpdirXXXXXX'; +print "# Template: $template\n"; +my $tempdir = tempdir( $template , + DIR => File::Spec->curdir, + CLEANUP => 1, + ); + +print "# TEMPDIR: $tempdir\n"; + +ok( (-d $tempdir) ); +push(@dirs, $tempdir); + +# Create file in the temp dir +($fh, $tempfile) = tempfile( + DIR => $tempdir, + UNLINK => 1, + SUFFIX => '.dat', + ); + +print "# TEMPFILE: Created $tempfile\n"; + +ok( (-f $tempfile)); +push(@files, $tempfile); + +# Test tempfile +# ..and again +($fh, $tempfile) = tempfile( + DIR => $tempdir, + ); + + +ok( (-f $tempfile )); +push(@files, $tempfile); + +print "# TEMPFILE: Created $tempfile\n"; + +# and another (with template) + +($fh, $tempfile) = tempfile( 'helloXXXXXXX', + DIR => $tempdir, + UNLINK => 1, + SUFFIX => '.dat', + ); + +print "# TEMPFILE: Created $tempfile\n"; + +ok( (-f $tempfile) ); +push(@files, $tempfile); + + +# Create a temporary file that should stay around after +# it has been closed +($fh, $tempfile) = tempfile( 'permXXXXXXX', UNLINK => 0 ); +print "# TEMPFILE: Created $tempfile\n"; +ok( -f $tempfile ); +ok( close( $fh ) ); +push( @still_there, $tempfile); # check at END + +# Would like to create a temp file and just retrieve the handle +# but the test is problematic since: +# - We dont know the filename so we cant check that it is tidied +# correctly +# - The unlink0 required on unix for tempfile creation will fail +# on NFS +# Try to do what we can. +# Tempfile croaks on error so we need an eval +$fh = eval { tempfile( 'ftmpXXXXX', DIR => File::Spec->tmpdir ) }; + +if ($fh) { + + # print something to it to make sure something is there + ok( print $fh "Test\n" ); + + # Close it - can not check it is gone since we dont know the name + ok( close($fh) ); + +} else { + skip "Skip Failed probably due to NFS", 1; + skip "Skip Failed probably due to NFS", 1; +} + +# Now END block will execute to test the removal of directories +print "# End of tests. Execute END blocks\n"; + |