1 package File::Spec::Unix;
7 $VERSION = eval $VERSION;
11 File::Spec::Unix - File::Spec for Unix, base for other File::Spec modules
15 require File::Spec::Unix; # Done automatically by File::Spec
19 Methods for manipulating file specifications. Other File::Spec
20 modules, such as File::Spec::Mac, inherit from File::Spec::Unix and
21 override specific methods.
29 No physical check on the filesystem, but a logical cleanup of a
30 path. On UNIX eliminates successive slashes and successive "/.".
32 $cpath = File::Spec->canonpath( $path ) ;
34 Note that this does *not* collapse F<x/../y> sections into F<y>. This
35 is by design. If F</foo> on your system is a symlink to F</bar/baz>,
36 then F</foo/../quux> is actually F</bar/quux>, not F</quux> as a naive
37 F<../>-removal would give you. If you want to do this kind of
38 processing, you probably want C<Cwd>'s C<realpath()> function to
39 actually traverse the filesystem cleaning up paths like this.
44 my ($self,$path) = @_;
45 return unless defined $path;
47 # Handle POSIX-style node names beginning with double slash (qnx, nto)
48 # (POSIX says: "a pathname that begins with two successive slashes
49 # may be interpreted in an implementation-defined manner, although
50 # more than two leading slashes shall be treated as a single slash.")
52 my $double_slashes_special = $^O eq 'qnx' || $^O eq 'nto';
53 if ( $double_slashes_special && $path =~ s{^(//[^/]+)(?:/|\z)}{/}s ) {
57 # $path =~ s|/+|/|g unless ($^O eq 'cygwin');
58 # but that made tests 29, 30, 35, 46, and 213 (as of #13272) to fail
59 # (Mainly because trailing "" directories didn't get stripped).
60 # Why would cygwin avoid collapsing multiple slashes into one? --jhi
61 $path =~ s|/{2,}|/|g; # xx////xx -> xx/xx
62 $path =~ s{(?:/\.)+(?:/|\z)}{/}g; # xx/././xx -> xx/xx
63 $path =~ s|^(?:\./)+||s unless $path eq "./"; # ./xx -> xx
64 $path =~ s|^/(?:\.\./)+|/|; # /../../xx -> xx
65 $path =~ s|^/\.\.$|/|; # /.. -> /
66 $path =~ s|/\z|| unless $path eq "/"; # xx/ -> xx
72 Concatenate two or more directory names to form a complete path ending
73 with a directory. But remove the trailing slash from the resulting
74 string, because it doesn't look good, isn't necessary and confuses
75 OS2. Of course, if this is the root directory, don't cut off the
83 $self->canonpath(join('/', @_, '')); # '' because need a trailing '/'
88 Concatenate one or more directory names and a filename to form a
89 complete path ending with a filename
95 my $file = $self->canonpath(pop @_);
96 return $file unless @_;
97 my $dir = $self->catdir(@_);
98 $dir .= "/" unless substr($dir,-1) eq "/";
104 Returns a string representation of the current directory. "." on UNIX.
112 Returns a string representation of the null device. "/dev/null" on UNIX.
116 sub devnull { '/dev/null' }
120 Returns a string representation of the root directory. "/" on UNIX.
128 Returns a string representation of the first writable directory from
129 the following list or the current directory if none from the list are
135 Since perl 5.8.0, if running under taint mode, and if $ENV{TMPDIR}
136 is tainted, it is not used.
142 return $tmpdir if defined $tmpdir;
147 if (${"\cTAINT"}) { # Check for taint mode on perl >= 5.8.0
148 require Scalar::Util;
149 @dirlist = grep { ! Scalar::Util::tainted($_) } @dirlist;
153 next unless defined && -d && -w _;
157 $tmpdir = $self->curdir unless defined $tmpdir;
158 $tmpdir = defined $tmpdir && $self->canonpath($tmpdir);
163 return $tmpdir if defined $tmpdir;
164 $tmpdir = $_[0]->_tmpdir( $ENV{TMPDIR}, "/tmp" );
169 Returns a string representation of the parent directory. ".." on UNIX.
177 Given a list of file names, strip out those that refer to a parent
178 directory. (Does not strip symlinks, only '.', '..', and equivalents.)
184 return grep(!/^\.{1,2}\z/s, @_);
189 Returns a true or false value indicating, respectively, that alphabetic
190 is not or is significant when comparing file specifications.
194 sub case_tolerant { 0 }
196 =item file_name_is_absolute
198 Takes as argument a path and returns true if it is an absolute path.
200 This does not consult the local filesystem on Unix, Win32, OS/2 or Mac
201 OS (Classic). It does consult the working environment for VMS (see
202 L<File::Spec::VMS/file_name_is_absolute>).
206 sub file_name_is_absolute {
207 my ($self,$file) = @_;
208 return scalar($file =~ m:^/:s);
213 Takes no argument, returns the environment variable PATH as an array.
218 return () unless exists $ENV{PATH};
219 my @path = split(':', $ENV{PATH});
220 foreach (@path) { $_ = '.' if $_ eq '' }
226 join is the same as catfile.
232 return $self->catfile(@_);
237 ($volume,$directories,$file) = File::Spec->splitpath( $path );
238 ($volume,$directories,$file) = File::Spec->splitpath( $path, $no_file );
240 Splits a path into volume, directory, and filename portions. On systems
241 with no concept of volume, returns '' for volume.
243 For systems with no syntax differentiating filenames from directories,
244 assumes that the last file is a path unless $no_file is true or a
245 trailing separator or /. or /.. is present. On Unix this means that $no_file
246 true makes this return ( '', $path, '' ).
248 The directory portion may or may not be returned with a trailing '/'.
250 The results can be passed to L</catpath()> to get back a path equivalent to
251 (usually identical to) the original path.
256 my ($self,$path, $nofile) = @_;
258 my ($volume,$directory,$file) = ('','','');
264 $path =~ m|^ ( (?: .* / (?: \.\.?\z )? )? ) ([^/]*) |xs;
269 return ($volume,$directory,$file);
275 The opposite of L</catdir()>.
277 @dirs = File::Spec->splitdir( $directories );
279 $directories must be only the directory portion of the path on systems
280 that have the concept of a volume or that have path syntax that differentiates
281 files from directories.
283 Unlike just splitting the directories on the separator, empty
284 directory names (C<''>) can be returned, because these are significant
289 File::Spec->splitdir( "/a/b//c/" );
293 ( '', 'a', 'b', '', 'c', '' )
298 return split m|/|, $_[1], -1; # Preserve trailing fields
304 Takes volume, directory and file portions and returns an entire path. Under
305 Unix, $volume is ignored, and directory and file are concatenated. A '/' is
306 inserted if needed (though if the directory portion doesn't start with
307 '/' it is not added). On other OSs, $volume is significant.
312 my ($self,$volume,$directory,$file) = @_;
314 if ( $directory ne '' &&
316 substr( $directory, -1 ) ne '/' &&
317 substr( $file, 0, 1 ) ne '/'
319 $directory .= "/$file" ;
322 $directory .= $file ;
330 Takes a destination path and an optional base path returns a relative path
331 from the base path to the destination path:
333 $rel_path = File::Spec->abs2rel( $path ) ;
334 $rel_path = File::Spec->abs2rel( $path, $base ) ;
336 If $base is not present or '', then L<cwd()|Cwd> is used. If $base is
337 relative, then it is converted to absolute form using
338 L</rel2abs()>. This means that it is taken to be relative to
341 On systems that have a grammar that indicates filenames, this ignores the
342 $base filename. Otherwise all path components are assumed to be
345 If $path is relative, it is converted to absolute form using L</rel2abs()>.
346 This means that it is taken to be relative to L<cwd()|Cwd>.
348 No checks against the filesystem are made. On VMS, there is
349 interaction with the working environment, as logicals and
352 Based on code written by Shigio Yamaguchi.
357 my($self,$path,$base) = @_;
358 $base = $self->_cwd() unless defined $base and length $base;
360 ($path, $base) = map $self->canonpath($_), $path, $base;
362 if (grep $self->file_name_is_absolute($_), $path, $base) {
363 ($path, $base) = map $self->rel2abs($_), $path, $base;
366 # save a couple of cwd()s if both paths are relative
367 ($path, $base) = map $self->catdir('/', $_), $path, $base;
370 my ($path_volume) = $self->splitpath($path, 1);
371 my ($base_volume) = $self->splitpath($base, 1);
373 # Can't relativize across volumes
374 return $path unless $path_volume eq $base_volume;
376 my $path_directories = ($self->splitpath($path, 1))[1];
377 my $base_directories = ($self->splitpath($base, 1))[1];
379 # For UNC paths, the user might give a volume like //foo/bar that
380 # strictly speaking has no directory portion. Treat it as if it
381 # had the root directory for that volume.
382 if (!length($base_directories) and $self->file_name_is_absolute($base)) {
383 $base_directories = $self->rootdir;
386 # Now, remove all leading components that are the same
387 my @pathchunks = $self->splitdir( $path_directories );
388 my @basechunks = $self->splitdir( $base_directories );
390 if ($base_directories eq $self->rootdir) {
392 return $self->canonpath( $self->catpath('', $self->catdir( @pathchunks ), '') );
395 while (@pathchunks && @basechunks && $self->_same($pathchunks[0], $basechunks[0])) {
399 return $self->curdir unless @pathchunks || @basechunks;
401 # $base now contains the directories the resulting relative path
402 # must ascend out of before it can descend to $path_directory.
403 my $result_dirs = $self->catdir( ($self->updir) x @basechunks, @pathchunks );
404 return $self->canonpath( $self->catpath('', $result_dirs, '') );
413 Converts a relative path to an absolute path.
415 $abs_path = File::Spec->rel2abs( $path ) ;
416 $abs_path = File::Spec->rel2abs( $path, $base ) ;
418 If $base is not present or '', then L<cwd()|Cwd> is used. If $base is
419 relative, then it is converted to absolute form using
420 L</rel2abs()>. This means that it is taken to be relative to
423 On systems that have a grammar that indicates filenames, this ignores
424 the $base filename. Otherwise all path components are assumed to be
427 If $path is absolute, it is cleaned up and returned using L</canonpath()>.
429 No checks against the filesystem are made. On VMS, there is
430 interaction with the working environment, as logicals and
433 Based on code written by Shigio Yamaguchi.
438 my ($self,$path,$base ) = @_;
441 if ( ! $self->file_name_is_absolute( $path ) ) {
442 # Figure out the effective $base and clean it up.
443 if ( !defined( $base ) || $base eq '' ) {
444 $base = $self->_cwd();
446 elsif ( ! $self->file_name_is_absolute( $base ) ) {
447 $base = $self->rel2abs( $base ) ;
450 $base = $self->canonpath( $base ) ;
454 $path = $self->catdir( $base, $path ) ;
457 return $self->canonpath( $path ) ;
464 Copyright (c) 2004 by the Perl 5 Porters. All rights reserved.
466 This program is free software; you can redistribute it and/or modify
467 it under the same terms as Perl itself.
475 # Internal routine to File::Spec, no point in making this public since
476 # it is the standard Cwd interface. Most of the platform-specific
477 # File::Spec subclasses use this.
484 # Internal method to reduce xx\..\yy -> yy
488 my $updir = $fs->updir;
489 my $curdir = $fs->curdir;
491 my($vol, $dirs, $file) = $fs->splitpath($path);
492 my @dirs = $fs->splitdir($dirs);
493 pop @dirs if @dirs && $dirs[-1] eq '';
496 foreach my $dir (@dirs) {
497 if( $dir eq $updir and # if we have an updir
498 @collapsed and # and something to collapse
499 length $collapsed[-1] and # and its not the rootdir
500 $collapsed[-1] ne $updir and # nor another updir
501 $collapsed[-1] ne $curdir # nor the curdir
504 pop @collapsed; # collapse
507 push @collapsed, $dir; # just hang onto it
511 return $fs->catpath($vol,
512 $fs->catdir(@collapsed),