Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!sdd.hp.com!elroy.jpl.nasa.gov!jpl-devvax!lwall From: lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) Newsgroups: comp.lang.perl Subject: Re: How to find working directory? Message-ID: <8974@jpl-devvax.JPL.NASA.GOV> Date: 2 Aug 90 21:35:38 GMT References: <139945@sun.Eng.Sun.COM> Reply-To: lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) Organization: Jet Propulsion Laboratory, Pasadena, CA Lines: 71 In article <139945@sun.Eng.Sun.COM> petolino@joe.Eng.Sun.COM (Joe Petolino) writes: : I know I can change my working directory with chdir(). Is there a : symmetrical operation which tells me what my working directory is (short : of invoking pwd in a subshell, that is)? No. : Imagine my surprise when I found out that chdir() doesn't set $ENV{'PWD'} ! Ok. : Do I really have to test each chdir() for success and then conditionally : assign its argument to $ENV{'PWD'} ? Yes and/or no, depending on how you work it. Here's the slow but concise way: sub initpwd { chop($ENV{'PWD'} = `pwd`); } sub chdir { chdir shift; &initpwd; } Call initpwd at the top of the show. Note that the existence of a getwd call wouldn't speed this up all that much--getwd is a fairly expensive operation. You really just want to init PWD at the beginning of the program and then keep track of it. So here's the fast way sub initpwd { if ($ENV{'PWD'}) { local($dd,$di) = stat('.'); local($pd,$pi) = stat($ENV{'PWD'}); return if $di == $pi && $dd == $pd; } chop($ENV{'PWD'} = `pwd`); } sub chdir { local($newdir) = shift; if (chdir $newdir) { if ($newdir =~ m#^/#) { $ENV{'PWD'} = $newdir; } else { local(@curdir) = split(m#/#,$ENV{'PWD'}); @curdir = '' unless @curdir; foreach $component (split(m#/#, $newdir)) { next if $component eq '.'; pop(@curdir),next if $component eq '..'; push(@curdir,$component); } $ENV{'PWD'} = join('/',@curdir) || '/'; } } else { 0; } } There will be a library package to do this in the next patch. : The programs I'm invoking after the chdir() expect $PWD to be accurate. Then the programs you're invoking are highly non-portable. Only certain shells keep track of PWD. Any C program that uses chdir and then invokes one of these programs will confuse it. I stop just short of saying the programs are busted. Larry