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';
55 if ( $double_slashes_special
56 && ( $path =~ s{^(//[^/]+)/?\z}{}s || $path =~ s{^(//[^/]+)/}{/}s ) ) {
60 # $path =~ s|/+|/|g unless ($^O eq 'cygwin');
61 # but that made tests 29, 30, 35, 46, and 213 (as of #13272) to fail
62 # (Mainly because trailing "" directories didn't get stripped).
63 # Why would cygwin avoid collapsing multiple slashes into one? --jhi
64 $path =~ s|/{2,}|/|g; # xx////xx -> xx/xx
65 $path =~ s{(?:/\.)+(?:/|\z)}{/}g; # xx/././xx -> xx/xx
66 $path =~ s|^(?:\./)+||s unless $path eq "./"; # ./xx -> xx
67 $path =~ s|^/(?:\.\./)+|/|; # /../../xx -> xx
68 $path =~ s|^/\.\.$|/|; # /.. -> /
69 $path =~ s|/\z|| unless $path eq "/"; # xx/ -> xx
75 Concatenate two or more directory names to form a complete path ending
76 with a directory. But remove the trailing slash from the resulting
77 string, because it doesn't look good, isn't necessary and confuses
78 OS2. Of course, if this is the root directory, don't cut off the
86 $self->canonpath(join('/', @_, '')); # '' because need a trailing '/'
91 Concatenate one or more directory names and a filename to form a
92 complete path ending with a filename
98 my $file = $self->canonpath(pop @_);
99 return $file unless @_;
100 my $dir = $self->catdir(@_);
101 $dir .= "/" unless substr($dir,-1) eq "/";
107 Returns a string representation of the current directory. "." on UNIX.
115 Returns a string representation of the null device. "/dev/null" on UNIX.
119 sub devnull { '/dev/null' }
123 Returns a string representation of the root directory. "/" on UNIX.
131 Returns a string representation of the first writable directory from
132 the following list or the current directory if none from the list are
138 Since perl 5.8.0, if running under taint mode, and if $ENV{TMPDIR}
139 is tainted, it is not used.
145 return $tmpdir if defined $tmpdir;
150 if (${"\cTAINT"}) { # Check for taint mode on perl >= 5.8.0
151 require Scalar::Util;
152 @dirlist = grep { ! Scalar::Util::tainted($_) } @dirlist;
156 next unless defined && -d && -w _;
160 $tmpdir = $self->curdir unless defined $tmpdir;
161 $tmpdir = defined $tmpdir && $self->canonpath($tmpdir);
166 return $tmpdir if defined $tmpdir;
167 $tmpdir = $_[0]->_tmpdir( $ENV{TMPDIR}, "/tmp" );
172 Returns a string representation of the parent directory. ".." on UNIX.
180 Given a list of file names, strip out those that refer to a parent
181 directory. (Does not strip symlinks, only '.', '..', and equivalents.)
187 return grep(!/^\.{1,2}\z/s, @_);
192 Returns a true or false value indicating, respectively, that alphabetic
193 is not or is significant when comparing file specifications.
197 sub case_tolerant { 0 }
199 =item file_name_is_absolute
201 Takes as argument a path and returns true if it is an absolute path.
203 This does not consult the local filesystem on Unix, Win32, OS/2 or Mac
204 OS (Classic). It does consult the working environment for VMS (see
205 L<File::Spec::VMS/file_name_is_absolute>).
209 sub file_name_is_absolute {
210 my ($self,$file) = @_;
211 return scalar($file =~ m:^/:s);
216 Takes no argument, returns the environment variable PATH as an array.
221 return () unless exists $ENV{PATH};
222 my @path = split(':', $ENV{PATH});
223 foreach (@path) { $_ = '.' if $_ eq '' }
229 join is the same as catfile.
235 return $self->catfile(@_);
240 ($volume,$directories,$file) = File::Spec->splitpath( $path );
241 ($volume,$directories,$file) = File::Spec->splitpath( $path, $no_file );
243 Splits a path into volume, directory, and filename portions. On systems
244 with no concept of volume, returns '' for volume.
246 For systems with no syntax differentiating filenames from directories,
247 assumes that the last file is a path unless $no_file is true or a
248 trailing separator or /. or /.. is present. On Unix this means that $no_file
249 true makes this return ( '', $path, '' ).
251 The directory portion may or may not be returned with a trailing '/'.
253 The results can be passed to L</catpath()> to get back a path equivalent to
254 (usually identical to) the original path.
259 my ($self,$path, $nofile) = @_;
261 my ($volume,$directory,$file) = ('','','');
267 $path =~ m|^ ( (?: .* / (?: \.\.?\z )? )? ) ([^/]*) |xs;
272 return ($volume,$directory,$file);
278 The opposite of L</catdir()>.
280 @dirs = File::Spec->splitdir( $directories );
282 $directories must be only the directory portion of the path on systems
283 that have the concept of a volume or that have path syntax that differentiates
284 files from directories.
286 Unlike just splitting the directories on the separator, empty
287 directory names (C<''>) can be returned, because these are significant
292 File::Spec->splitdir( "/a/b//c/" );
296 ( '', 'a', 'b', '', 'c', '' )
301 return split m|/|, $_[1], -1; # Preserve trailing fields
307 Takes volume, directory and file portions and returns an entire path. Under
308 Unix, $volume is ignored, and directory and file are concatenated. A '/' is
309 inserted if needed (though if the directory portion doesn't start with
310 '/' it is not added). On other OSs, $volume is significant.
315 my ($self,$volume,$directory,$file) = @_;
317 if ( $directory ne '' &&
319 substr( $directory, -1 ) ne '/' &&
320 substr( $file, 0, 1 ) ne '/'
322 $directory .= "/$file" ;
325 $directory .= $file ;
333 Takes a destination path and an optional base path returns a relative path
334 from the base path to the destination path:
336 $rel_path = File::Spec->abs2rel( $path ) ;
337 $rel_path = File::Spec->abs2rel( $path, $base ) ;
339 If $base is not present or '', then L<cwd()|Cwd> is used. If $base is
340 relative, then it is converted to absolute form using
341 L</rel2abs()>. This means that it is taken to be relative to
344 On systems that have a grammar that indicates filenames, this ignores the
345 $base filename. Otherwise all path components are assumed to be
348 If $path is relative, it is converted to absolute form using L</rel2abs()>.
349 This means that it is taken to be relative to L<cwd()|Cwd>.
351 No checks against the filesystem are made. On VMS, there is
352 interaction with the working environment, as logicals and
355 Based on code written by Shigio Yamaguchi.
360 my($self,$path,$base) = @_;
361 $base = $self->_cwd() unless defined $base and length $base;
363 ($path, $base) = map $self->canonpath($_), $path, $base;
365 if (grep $self->file_name_is_absolute($_), $path, $base) {
366 ($path, $base) = map $self->rel2abs($_), $path, $base;
369 # save a couple of cwd()s if both paths are relative
370 ($path, $base) = map $self->catdir('/', $_), $path, $base;
373 my ($path_volume) = $self->splitpath($path, 1);
374 my ($base_volume) = $self->splitpath($base, 1);
376 # Can't relativize across volumes
377 return $path unless $path_volume eq $base_volume;
379 my $path_directories = ($self->splitpath($path, 1))[1];
380 my $base_directories = ($self->splitpath($base, 1))[1];
382 # For UNC paths, the user might give a volume like //foo/bar that
383 # strictly speaking has no directory portion. Treat it as if it
384 # had the root directory for that volume.
385 if (!length($base_directories) and $self->file_name_is_absolute($base)) {
386 $base_directories = $self->rootdir;
389 # Now, remove all leading components that are the same
390 my @pathchunks = $self->splitdir( $path_directories );
391 my @basechunks = $self->splitdir( $base_directories );
393 if ($base_directories eq $self->rootdir) {
395 return $self->canonpath( $self->catpath('', $self->catdir( @pathchunks ), '') );
398 while (@pathchunks && @basechunks && $self->_same($pathchunks[0], $basechunks[0])) {
402 return $self->curdir unless @pathchunks || @basechunks;
404 # $base now contains the directories the resulting relative path
405 # must ascend out of before it can descend to $path_directory.
406 my $result_dirs = $self->catdir( ($self->updir) x @basechunks, @pathchunks );
407 return $self->canonpath( $self->catpath('', $result_dirs, '') );
416 Converts a relative path to an absolute path.
418 $abs_path = File::Spec->rel2abs( $path ) ;
419 $abs_path = File::Spec->rel2abs( $path, $base ) ;
421 If $base is not present or '', then L<cwd()|Cwd> is used. If $base is
422 relative, then it is converted to absolute form using
423 L</rel2abs()>. This means that it is taken to be relative to
426 On systems that have a grammar that indicates filenames, this ignores
427 the $base filename. Otherwise all path components are assumed to be
430 If $path is absolute, it is cleaned up and returned using L</canonpath()>.
432 No checks against the filesystem are made. On VMS, there is
433 interaction with the working environment, as logicals and
436 Based on code written by Shigio Yamaguchi.
441 my ($self,$path,$base ) = @_;
444 if ( ! $self->file_name_is_absolute( $path ) ) {
445 # Figure out the effective $base and clean it up.
446 if ( !defined( $base ) || $base eq '' ) {
447 $base = $self->_cwd();
449 elsif ( ! $self->file_name_is_absolute( $base ) ) {
450 $base = $self->rel2abs( $base ) ;
453 $base = $self->canonpath( $base ) ;
457 $path = $self->catdir( $base, $path ) ;
460 return $self->canonpath( $path ) ;
467 Copyright (c) 2004 by the Perl 5 Porters. All rights reserved.
469 This program is free software; you can redistribute it and/or modify
470 it under the same terms as Perl itself.
478 # Internal routine to File::Spec, no point in making this public since
479 # it is the standard Cwd interface. Most of the platform-specific
480 # File::Spec subclasses use this.
487 # Internal method to reduce xx\..\yy -> yy
491 my $updir = $fs->updir;
492 my $curdir = $fs->curdir;
494 my($vol, $dirs, $file) = $fs->splitpath($path);
495 my @dirs = $fs->splitdir($dirs);
496 pop @dirs if @dirs && $dirs[-1] eq '';
499 foreach my $dir (@dirs) {
500 if( $dir eq $updir and # if we have an updir
501 @collapsed and # and something to collapse
502 length $collapsed[-1] and # and its not the rootdir
503 $collapsed[-1] ne $updir and # nor another updir
504 $collapsed[-1] ne $curdir # nor the curdir
507 pop @collapsed; # collapse
510 push @collapsed, $dir; # just hang onto it
514 return $fs->catpath($vol,
515 $fs->catdir(@collapsed),