1 package File::Spec::Unix;
10 File::Spec::Unix - File::Spec for Unix, base for other File::Spec modules
14 require File::Spec::Unix; # Done automatically by File::Spec
18 Methods for manipulating file specifications. Other File::Spec
19 modules, such as File::Spec::Mac, inherit from File::Spec::Unix and
20 override specific methods.
28 No physical check on the filesystem, but a logical cleanup of a
29 path. On UNIX eliminates successive slashes and successive "/.".
31 $cpath = File::Spec->canonpath( $path ) ;
33 Note that this does *not* collapse F<x/../y> sections into F<y>. This
34 is by design. If F</foo> on your system is a symlink to F</bar/baz>,
35 then F</foo/../quux> is actually F</bar/quux>, not F</quux> as a naive
36 F<../>-removal would give you. If you want to do this kind of
37 processing, you probably want C<Cwd>'s C<realpath()> function to
38 actually traverse the filesystem cleaning up paths like this.
43 my ($self,$path) = @_;
45 # Handle POSIX-style node names beginning with double slash (qnx, nto)
46 # (POSIX says: "a pathname that begins with two successive slashes
47 # may be interpreted in an implementation-defined manner, although
48 # more than two leading slashes shall be treated as a single slash.")
50 my $double_slashes_special = $^O eq 'qnx' || $^O eq 'nto';
51 if ( $double_slashes_special && $path =~ s{^(//[^/]+)(?:/|\z)}{/}s ) {
55 # $path =~ s|/+|/|g unless ($^O eq 'cygwin');
56 # but that made tests 29, 30, 35, 46, and 213 (as of #13272) to fail
57 # (Mainly because trailing "" directories didn't get stripped).
58 # Why would cygwin avoid collapsing multiple slashes into one? --jhi
59 $path =~ s|/{2,}|/|g; # xx////xx -> xx/xx
60 $path =~ s{(?:/\.)+(?:/|\z)}{/}g; # xx/././xx -> xx/xx
61 $path =~ s|^(?:\./)+||s unless $path eq "./"; # ./xx -> xx
62 $path =~ s|^/(?:\.\./)+|/|; # /../../xx -> xx
63 $path =~ s|^/\.\.$|/|; # /.. -> /
64 $path =~ s|/\z|| unless $path eq "/"; # xx/ -> xx
70 Concatenate two or more directory names to form a complete path ending
71 with a directory. But remove the trailing slash from the resulting
72 string, because it doesn't look good, isn't necessary and confuses
73 OS2. Of course, if this is the root directory, don't cut off the
81 $self->canonpath(join('/', @_, '')); # '' because need a trailing '/'
86 Concatenate one or more directory names and a filename to form a
87 complete path ending with a filename
93 my $file = $self->canonpath(pop @_);
94 return $file unless @_;
95 my $dir = $self->catdir(@_);
96 $dir .= "/" unless substr($dir,-1) eq "/";
102 Returns a string representation of the current directory. "." on UNIX.
106 sub curdir () { '.' }
110 Returns a string representation of the null device. "/dev/null" on UNIX.
114 sub devnull () { '/dev/null' }
118 Returns a string representation of the root directory. "/" on UNIX.
122 sub rootdir () { '/' }
126 Returns a string representation of the first writable directory from
127 the following list or the current directory if none from the list are
133 Since perl 5.8.0, if running under taint mode, and if $ENV{TMPDIR}
134 is tainted, it is not used.
140 return $tmpdir if defined $tmpdir;
145 if (${"\cTAINT"}) { # Check for taint mode on perl >= 5.8.0
146 require Scalar::Util;
147 @dirlist = grep { ! Scalar::Util::tainted($_) } @dirlist;
151 next unless defined && -d && -w _;
155 $tmpdir = $self->curdir unless defined $tmpdir;
156 $tmpdir = defined $tmpdir && $self->canonpath($tmpdir);
161 return $tmpdir if defined $tmpdir;
162 $tmpdir = $_[0]->_tmpdir( $ENV{TMPDIR}, "/tmp" );
167 Returns a string representation of the parent directory. ".." on UNIX.
171 sub updir () { '..' }
175 Given a list of file names, strip out those that refer to a parent
176 directory. (Does not strip symlinks, only '.', '..', and equivalents.)
182 return grep(!/^\.{1,2}\z/s, @_);
187 Returns a true or false value indicating, respectively, that alphabetic
188 is not or is significant when comparing file specifications.
192 sub case_tolerant () { 0 }
194 =item file_name_is_absolute
196 Takes as argument a path and returns true if it is an absolute path.
198 This does not consult the local filesystem on Unix, Win32, OS/2 or Mac
199 OS (Classic). It does consult the working environment for VMS (see
200 L<File::Spec::VMS/file_name_is_absolute>).
204 sub file_name_is_absolute {
205 my ($self,$file) = @_;
206 return scalar($file =~ m:^/:s);
211 Takes no argument, returns the environment variable PATH as an array.
216 return () unless exists $ENV{PATH};
217 my @path = split(':', $ENV{PATH});
218 foreach (@path) { $_ = '.' if $_ eq '' }
224 join is the same as catfile.
230 return $self->catfile(@_);
235 ($volume,$directories,$file) = File::Spec->splitpath( $path );
236 ($volume,$directories,$file) = File::Spec->splitpath( $path, $no_file );
238 Splits a path into volume, directory, and filename portions. On systems
239 with no concept of volume, returns '' for volume.
241 For systems with no syntax differentiating filenames from directories,
242 assumes that the last file is a path unless $no_file is true or a
243 trailing separator or /. or /.. is present. On Unix this means that $no_file
244 true makes this return ( '', $path, '' ).
246 The directory portion may or may not be returned with a trailing '/'.
248 The results can be passed to L</catpath()> to get back a path equivalent to
249 (usually identical to) the original path.
254 my ($self,$path, $nofile) = @_;
256 my ($volume,$directory,$file) = ('','','');
262 $path =~ m|^ ( (?: .* / (?: \.\.?\z )? )? ) ([^/]*) |xs;
267 return ($volume,$directory,$file);
273 The opposite of L</catdir()>.
275 @dirs = File::Spec->splitdir( $directories );
277 $directories must be only the directory portion of the path on systems
278 that have the concept of a volume or that have path syntax that differentiates
279 files from directories.
281 Unlike just splitting the directories on the separator, empty
282 directory names (C<''>) can be returned, because these are significant
287 File::Spec->splitdir( "/a/b//c/" );
291 ( '', 'a', 'b', '', 'c', '' )
296 return split m|/|, $_[1], -1; # Preserve trailing fields
302 Takes volume, directory and file portions and returns an entire path. Under
303 Unix, $volume is ignored, and directory and file are concatenated. A '/' is
304 inserted if needed (though if the directory portion doesn't start with
305 '/' it is not added). On other OSs, $volume is significant.
310 my ($self,$volume,$directory,$file) = @_;
312 if ( $directory ne '' &&
314 substr( $directory, -1 ) ne '/' &&
315 substr( $file, 0, 1 ) ne '/'
317 $directory .= "/$file" ;
320 $directory .= $file ;
328 Takes a destination path and an optional base path returns a relative path
329 from the base path to the destination path:
331 $rel_path = File::Spec->abs2rel( $path ) ;
332 $rel_path = File::Spec->abs2rel( $path, $base ) ;
334 If $base is not present or '', then L<cwd()|Cwd> is used. If $base is
335 relative, then it is converted to absolute form using
336 L</rel2abs()>. This means that it is taken to be relative to
339 On systems that have a grammar that indicates filenames, this ignores the
340 $base filename. Otherwise all path components are assumed to be
343 If $path is relative, it is converted to absolute form using L</rel2abs()>.
344 This means that it is taken to be relative to L<cwd()|Cwd>.
346 No checks against the filesystem are made. On VMS, there is
347 interaction with the working environment, as logicals and
350 Based on code written by Shigio Yamaguchi.
355 my($self,$path,$base) = @_;
356 $base = $self->_cwd() unless defined $base and length $base;
358 ($path, $base) = map $self->canonpath($_), $path, $base;
360 if (grep $self->file_name_is_absolute($_), $path, $base) {
361 ($path, $base) = map $self->rel2abs($_), $path, $base;
364 # save a couple of cwd()s if both paths are relative
365 ($path, $base) = map $self->catdir('/', $_), $path, $base;
368 my ($path_volume) = $self->splitpath($path, 1);
369 my ($base_volume) = $self->splitpath($base, 1);
371 # Can't relativize across volumes
372 return $path unless $path_volume eq $base_volume;
374 my $path_directories = ($self->splitpath($path, 1))[1];
375 my $base_directories = ($self->splitpath($base, 1))[1];
377 # For UNC paths, the user might give a volume like //foo/bar that
378 # strictly speaking has no directory portion. Treat it as if it
379 # had the root directory for that volume.
380 if (!length($base_directories) and $self->file_name_is_absolute($base)) {
381 $base_directories = $self->rootdir;
384 # Now, remove all leading components that are the same
385 my @pathchunks = $self->splitdir( $path_directories );
386 my @basechunks = $self->splitdir( $base_directories );
388 if ($base_directories eq $self->rootdir) {
390 return $self->canonpath( $self->catpath('', $self->catdir( @pathchunks ), '') );
393 while (@pathchunks && @basechunks && $self->_same($pathchunks[0], $basechunks[0])) {
397 return $self->curdir unless @pathchunks || @basechunks;
399 # $base now contains the directories the resulting relative path
400 # must ascend out of before it can descend to $path_directory.
401 my $result_dirs = $self->catdir( ($self->updir) x @basechunks, @pathchunks );
402 return $self->canonpath( $self->catpath('', $result_dirs, '') );
411 Converts a relative path to an absolute path.
413 $abs_path = File::Spec->rel2abs( $path ) ;
414 $abs_path = File::Spec->rel2abs( $path, $base ) ;
416 If $base is not present or '', then L<cwd()|Cwd> is used. If $base is
417 relative, then it is converted to absolute form using
418 L</rel2abs()>. This means that it is taken to be relative to
421 On systems that have a grammar that indicates filenames, this ignores
422 the $base filename. Otherwise all path components are assumed to be
425 If $path is absolute, it is cleaned up and returned using L</canonpath()>.
427 No checks against the filesystem are made. On VMS, there is
428 interaction with the working environment, as logicals and
431 Based on code written by Shigio Yamaguchi.
436 my ($self,$path,$base ) = @_;
439 if ( ! $self->file_name_is_absolute( $path ) ) {
440 # Figure out the effective $base and clean it up.
441 if ( !defined( $base ) || $base eq '' ) {
442 $base = $self->_cwd();
444 elsif ( ! $self->file_name_is_absolute( $base ) ) {
445 $base = $self->rel2abs( $base ) ;
448 $base = $self->canonpath( $base ) ;
452 $path = $self->catdir( $base, $path ) ;
455 return $self->canonpath( $path ) ;
462 Copyright (c) 2004 by the Perl 5 Porters. All rights reserved.
464 This program is free software; you can redistribute it and/or modify
465 it under the same terms as Perl itself.
473 # Internal routine to File::Spec, no point in making this public since
474 # it is the standard Cwd interface. Most of the platform-specific
475 # File::Spec subclasses use this.
482 # Internal method to reduce xx\..\yy -> yy
486 my $updir = $fs->updir;
487 my $curdir = $fs->curdir;
489 my($vol, $dirs, $file) = $fs->splitpath($path);
490 my @dirs = $fs->splitdir($dirs);
491 pop @dirs if @dirs && $dirs[-1] eq '';
494 foreach my $dir (@dirs) {
495 if( $dir eq $updir and # if we have an updir
496 @collapsed and # and something to collapse
497 length $collapsed[-1] and # and its not the rootdir
498 $collapsed[-1] ne $updir and # nor another updir
499 $collapsed[-1] ne $curdir # nor the curdir
502 pop @collapsed; # collapse
505 push @collapsed, $dir; # just hang onto it
509 return $fs->catpath($vol,
510 $fs->catdir(@collapsed),