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,
244 Splits a path into volume, directory, and filename portions. On systems
245 with no concept of volume, returns '' for volume.
247 For systems with no syntax differentiating filenames from directories,
248 assumes that the last file is a path unless $no_file is true or a
249 trailing separator or /. or /.. is present. On Unix this means that $no_file
250 true makes this return ( '', $path, '' ).
252 The directory portion may or may not be returned with a trailing '/'.
254 The results can be passed to L</catpath()> to get back a path equivalent to
255 (usually identical to) the original path.
260 my ($self,$path, $nofile) = @_;
262 my ($volume,$directory,$file) = ('','','');
268 $path =~ m|^ ( (?: .* / (?: \.\.?\z )? )? ) ([^/]*) |xs;
273 return ($volume,$directory,$file);
279 The opposite of L</catdir()>.
281 @dirs = File::Spec->splitdir( $directories );
283 $directories must be only the directory portion of the path on systems
284 that have the concept of a volume or that have path syntax that differentiates
285 files from directories.
287 Unlike just splitting the directories on the separator, empty
288 directory names (C<''>) can be returned, because these are significant
293 File::Spec->splitdir( "/a/b//c/" );
297 ( '', 'a', 'b', '', 'c', '' )
302 return split m|/|, $_[1], -1; # Preserve trailing fields
308 Takes volume, directory and file portions and returns an entire path. Under
309 Unix, $volume is ignored, and directory and file are concatenated. A '/' is
310 inserted if needed (though if the directory portion doesn't start with
311 '/' it is not added). On other OSs, $volume is significant.
316 my ($self,$volume,$directory,$file) = @_;
318 if ( $directory ne '' &&
320 substr( $directory, -1 ) ne '/' &&
321 substr( $file, 0, 1 ) ne '/'
323 $directory .= "/$file" ;
326 $directory .= $file ;
334 Takes a destination path and an optional base path returns a relative path
335 from the base path to the destination path:
337 $rel_path = File::Spec->abs2rel( $path ) ;
338 $rel_path = File::Spec->abs2rel( $path, $base ) ;
340 If $base is not present or '', then L<cwd()|Cwd> is used. If $base is
341 relative, then it is converted to absolute form using
342 L</rel2abs()>. This means that it is taken to be relative to
345 On systems that have a grammar that indicates filenames, this ignores the
346 $base filename. Otherwise all path components are assumed to be
349 If $path is relative, it is converted to absolute form using L</rel2abs()>.
350 This means that it is taken to be relative to L<cwd()|Cwd>.
352 No checks against the filesystem are made. On VMS, there is
353 interaction with the working environment, as logicals and
356 Based on code written by Shigio Yamaguchi.
361 my($self,$path,$base) = @_;
362 $base = $self->_cwd() unless defined $base and length $base;
364 ($path, $base) = map $self->canonpath($_), $path, $base;
366 if (grep $self->file_name_is_absolute($_), $path, $base) {
367 ($path, $base) = map $self->rel2abs($_), $path, $base;
370 # save a couple of cwd()s if both paths are relative
371 ($path, $base) = map $self->catdir('/', $_), $path, $base;
374 my ($path_volume) = $self->splitpath($path, 1);
375 my ($base_volume) = $self->splitpath($base, 1);
377 # Can't relativize across volumes
378 return $path unless $path_volume eq $base_volume;
380 my $path_directories = ($self->splitpath($path, 1))[1];
381 my $base_directories = ($self->splitpath($base, 1))[1];
383 # For UNC paths, the user might give a volume like //foo/bar that
384 # strictly speaking has no directory portion. Treat it as if it
385 # had the root directory for that volume.
386 if (!length($base_directories) and $self->file_name_is_absolute($base)) {
387 $base_directories = $self->rootdir;
390 # Now, remove all leading components that are the same
391 my @pathchunks = $self->splitdir( $path_directories );
392 my @basechunks = $self->splitdir( $base_directories );
394 if ($base_directories eq $self->rootdir) {
396 return $self->canonpath( $self->catpath('', $self->catdir( @pathchunks ), '') );
399 while (@pathchunks && @basechunks && $self->_same($pathchunks[0], $basechunks[0])) {
403 return $self->curdir unless @pathchunks || @basechunks;
405 # $base now contains the directories the resulting relative path
406 # must ascend out of before it can descend to $path_directory.
407 my $result_dirs = $self->catdir( ($self->updir) x @basechunks, @pathchunks );
408 return $self->canonpath( $self->catpath('', $result_dirs, '') );
417 Converts a relative path to an absolute path.
419 $abs_path = File::Spec->rel2abs( $path ) ;
420 $abs_path = File::Spec->rel2abs( $path, $base ) ;
422 If $base is not present or '', then L<cwd()|Cwd> is used. If $base is
423 relative, then it is converted to absolute form using
424 L</rel2abs()>. This means that it is taken to be relative to
427 On systems that have a grammar that indicates filenames, this ignores
428 the $base filename. Otherwise all path components are assumed to be
431 If $path is absolute, it is cleaned up and returned using L</canonpath()>.
433 No checks against the filesystem are made. On VMS, there is
434 interaction with the working environment, as logicals and
437 Based on code written by Shigio Yamaguchi.
442 my ($self,$path,$base ) = @_;
445 if ( ! $self->file_name_is_absolute( $path ) ) {
446 # Figure out the effective $base and clean it up.
447 if ( !defined( $base ) || $base eq '' ) {
448 $base = $self->_cwd();
450 elsif ( ! $self->file_name_is_absolute( $base ) ) {
451 $base = $self->rel2abs( $base ) ;
454 $base = $self->canonpath( $base ) ;
458 $path = $self->catdir( $base, $path ) ;
461 return $self->canonpath( $path ) ;
468 Copyright (c) 2004 by the Perl 5 Porters. All rights reserved.
470 This program is free software; you can redistribute it and/or modify
471 it under the same terms as Perl itself.
479 # Internal routine to File::Spec, no point in making this public since
480 # it is the standard Cwd interface. Most of the platform-specific
481 # File::Spec subclasses use this.
488 # Internal method to reduce xx\..\yy -> yy
492 my $updir = $fs->updir;
493 my $curdir = $fs->curdir;
495 my($vol, $dirs, $file) = $fs->splitpath($path);
496 my @dirs = $fs->splitdir($dirs);
497 pop @dirs if @dirs && $dirs[-1] eq '';
500 foreach my $dir (@dirs) {
501 if( $dir eq $updir and # if we have an updir
502 @collapsed and # and something to collapse
503 length $collapsed[-1] and # and its not the rootdir
504 $collapsed[-1] ne $updir and # nor another updir
505 $collapsed[-1] ne $curdir # nor the curdir
508 pop @collapsed; # collapse
511 push @collapsed, $dir; # just hang onto it
515 return $fs->catpath($vol,
516 $fs->catdir(@collapsed),