home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / perl501m.zip / lib / Cwd.pm < prev    next >
Text File  |  1995-07-03  |  5KB  |  209 lines

  1. package Cwd;
  2. require 5.000;
  3. require Exporter;
  4. use Config;
  5.  
  6. =head1 NAME
  7.  
  8. getcwd - get pathname of current working directory
  9.  
  10. =head1 SYNOPSIS
  11.  
  12.     require Cwd;
  13.     $dir = Cwd::getcwd();
  14.  
  15.     use Cwd;
  16.     $dir = getcwd();
  17.  
  18.     use Cwd 'chdir';
  19.     chdir "/tmp";
  20.     print $ENV{'PWD'};
  21.  
  22. =head1 DESCRIPTION
  23.  
  24. The getcwd() function re-implements the getcwd(3) (or getwd(3)) functions
  25. in Perl.  If you ask to override your chdir() built-in function, then your
  26. PWD environment variable will be kept up to date.  (See
  27. L<perlsub/Overriding builtin functions>.)
  28.  
  29. The fastgetcwd() function looks the same as getcwd(), but runs faster.
  30. It's also more dangerous because you might conceivably chdir() out of a
  31. directory that you can't chdir() back into.
  32.  
  33. =cut
  34.  
  35. @ISA = qw(Exporter);
  36. @EXPORT = qw(getcwd fastcwd);
  37. @EXPORT_OK = qw(chdir);
  38.  
  39.  
  40. # VMS: $ENV{'DEFAULT'} points to default directory at all times
  41. # 08-Dec-1994  Charles Bailey  bailey@genetics.upenn.edu
  42. # Note: Use of Cwd::getcwd() or Cwd::chdir() (but not Cwd::fastcwd())
  43. #   causes the logical name PWD to be defined in the process 
  44. #   logical name table as the default device and directory 
  45. #   seen by Perl. This may not be the same as the default device 
  46. #   and directory seen by DCL after Perl exits, since the effects
  47. #   the CRTL chdir() function persist only until Perl exits.
  48.  
  49. # By Brandon S. Allbery
  50. #
  51. # Usage: $cwd = getcwd();
  52.  
  53. sub getcwd
  54. {
  55.     if($Config{'osname'} eq 'VMS') { return $ENV{'PWD'} = $ENV{'DEFAULT'} }
  56.     if($Config{'osname'} eq 'OS/2') { $_ = `\@cd`; s'\\'/'g; s/\s+$//g; return $_; }
  57.  
  58.     my($dotdots, $cwd, @pst, @cst, $dir, @tst);
  59.  
  60.     unless (@cst = stat('.'))
  61.     {
  62.     warn "stat(.): $!";
  63.     return '';
  64.     }
  65.     $cwd = '';
  66.     $dotdots = '';
  67.     do
  68.     {
  69.     $dotdots .= '/' if $dotdots;
  70.     $dotdots .= '..';
  71.     @pst = @cst;
  72.     unless (opendir(PARENT, $dotdots))
  73.     {
  74.         warn "opendir($dotdots): $!";
  75.         return '';
  76.     }
  77.     unless (@cst = stat($dotdots))
  78.     {
  79.         warn "stat($dotdots): $!";
  80.         closedir(PARENT);
  81.         return '';
  82.     }
  83.     if ($pst[0] == $cst[0] && $pst[1] == $cst[1])
  84.     {
  85.         $dir = '';
  86.     }
  87.     else
  88.     {
  89.         do
  90.         {
  91.         unless (defined ($dir = readdir(PARENT)))
  92.             {
  93.             warn "readdir($dotdots): $!";
  94.             closedir(PARENT);
  95.             return '';
  96.         }
  97.         unless (@tst = lstat("$dotdots/$dir"))
  98.         {
  99.             warn "lstat($dotdots/$dir): $!";
  100.             closedir(PARENT);
  101.             return '';
  102.         }
  103.         }
  104.         while ($dir eq '.' || $dir eq '..' || $tst[0] != $pst[0] ||
  105.            $tst[1] != $pst[1]);
  106.     }
  107.     $cwd = "$dir/$cwd";
  108.     closedir(PARENT);
  109.     } while ($dir);
  110.     chop($cwd); # drop the trailing /
  111.     $cwd;
  112. }
  113.  
  114.  
  115.  
  116. # By John Bazik
  117. #
  118. # Usage: $cwd = &fastcwd;
  119. #
  120. # This is a faster version of getcwd.  It's also more dangerous because
  121. # you might chdir out of a directory that you can't chdir back into.
  122.  
  123. sub fastcwd {
  124.     if($Config{'osname'} eq 'VMS') { return $ENV{'DEFAULT'} }
  125.     if($Config{'osname'} eq 'OS/2') { $_ = `\@cd`; s'\\'/'g; s/\s+$//g; return $_; }
  126.  
  127.     my($odev, $oino, $cdev, $cino, $tdev, $tino);
  128.     my(@path, $path);
  129.     local(*DIR);
  130.  
  131.     ($cdev, $cino) = stat('.');
  132.     for (;;) {
  133.     my $direntry;
  134.     ($odev, $oino) = ($cdev, $cino);
  135.     chdir('..');
  136.     ($cdev, $cino) = stat('.');
  137.     last if $odev == $cdev && $oino == $cino;
  138.     opendir(DIR, '.');
  139.     while ($direntry = readdir(DIR)) {
  140.         next if $direntry eq '.';
  141.         next if $direntry eq '..';
  142.         ($tdev, $tino) = lstat($direntry);
  143.         last unless $tdev != $odev || $tino != $oino;
  144.     }
  145.     closedir(DIR);
  146.     unshift(@path, $direntry);
  147.     }
  148.     chdir($path = '/' . join('/', @path));
  149.     $path;
  150. }
  151.  
  152.  
  153. # keeps track of current working directory in PWD environment var
  154. #
  155. # $RCSfile: pwd.pl,v $$Revision: 4.1 $$Date: 92/08/07 18:24:11 $
  156. #
  157. # $Log:    pwd.pl,v $
  158. #
  159. # Usage:
  160. #    use Cwd 'chdir';
  161. #    chdir $newdir;
  162.  
  163. $chdir_init = 0;
  164.  
  165. sub chdir_init{
  166.     if ($ENV{'PWD'}) {
  167.     my($dd,$di) = stat('.');
  168.     my($pd,$pi) = stat($ENV{'PWD'});
  169.     if (!defined $dd or !defined $pd or $di != $pi or $dd != $pd) {
  170.         chop($ENV{'PWD'} = `pwd`);
  171.     }
  172.     }
  173.     else {
  174.     chop($ENV{'PWD'} = `pwd`);
  175.     }
  176.     if ($ENV{'PWD'} =~ m|(/[^/]+(/[^/]+/[^/]+))(.*)|) {
  177.     my($pd,$pi) = stat($2);
  178.     my($dd,$di) = stat($1);
  179.     if (defined $pd and defined $dd and $di == $pi and $dd == $pd) {
  180.         $ENV{'PWD'}="$2$3";
  181.     }
  182.     }
  183.     $chdir_init = 1;
  184. }
  185.  
  186. sub chdir {
  187.     my($newdir) = shift;
  188.     $newdir =~ s|/{2,}|/|g;
  189.     chdir_init() unless $chdir_init;
  190.     return 0 unless (CORE::chdir $newdir);
  191.     if ($Config{'osname'} eq 'VMS') { return $ENV{PWD} = $ENV{DEFAULT} }
  192.  
  193.     if ($newdir =~ m#^/#) {
  194.     $ENV{'PWD'} = $newdir;
  195.     }else{
  196.     my(@curdir) = split(m#/#,$ENV{'PWD'});
  197.     @curdir = '' unless @curdir;
  198.     foreach $component (split(m#/#, $newdir)) {
  199.         next if $component eq '.';
  200.         pop(@curdir),next if $component eq '..';
  201.         push(@curdir,$component);
  202.     }
  203.     $ENV{'PWD'} = join('/',@curdir) || '/';
  204.     }
  205. }
  206.  
  207. 1;
  208.  
  209.