petolino@joe.Eng.Sun.COM (Joe Petolino) (08/01/90)
I'm a fairly new perl user, so excuse me if this is a dumb question. I know I can change my working directory with chdir(<string>). Is there a symmetrical operation which tells me what my working directory is (short of invoking pwd in a subshell, that is)? Imagine my surprise when I found out that chdir() doesn't set $ENV{'PWD'} ! Do I really have to test each chdir() for success and then conditionally assign its argument to $ENV{'PWD'} ? The programs I'm invoking after the chdir() expect $PWD to be accurate. -Joe
lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) (08/03/90)
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(<string>). 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
khera@juliet.cs.duke.edu (Vick Khera) (08/03/90)
In article <8974@jpl-devvax.JPL.NASA.GOV> lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) writes: :In article <139945@sun.Eng.Sun.COM> petolino@joe.Eng.Sun.COM (Joe Petolino) writes: :: 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 GNU Emacs uses PWD if it exists. my normal login shell updates PWD but /bin/csh doesn't (under 4.3BSD) so when i fire up emacs after su'ing to another user, emacs gets the wrong directory. i'd say this is busted. v. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Vick Khera (919) 660-6528 Department of Computer Science ARPA: khera@cs.duke.edu Duke University UUCP: ..!{mcnc,decvax}!duke!khera Durham, NC 27706
tchrist@convex.COM (Tom Christiansen) (08/04/90)
In article <21198@duke.cs.duke.edu> khera@cs.duke.edu (Vick Khera) writes: >In article <8974@jpl-devvax.JPL.NASA.GOV> lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) writes: >:I stop just short of saying the programs are busted. >GNU Emacs uses PWD if it exists. my normal login shell updates PWD >but /bin/csh doesn't (under 4.3BSD) so when i fire up emacs after >su'ing to another user, emacs gets the wrong directory. i'd say this >is busted. I'm not sure which you say is busted. It seems highly suspect to look at your environment for the $PWD. It's like trusting it for $USER. Use getwd() and getpwnam(getuid()) for these. What if a program does its own chdir() followed by an exec() or system()? --tom -- Tom Christiansen {uunet,uiucdcs,sun}!convex!tchrist Convex Computer Corporation tchrist@convex.COM "EMACS belongs in <sys/errno.h>: Editor too big!"
richard@pegasus.com (Richard Foulk) (08/05/90)
>>GNU Emacs uses PWD if it exists. my normal login shell updates PWD >>but /bin/csh doesn't (under 4.3BSD) so when i fire up emacs after >>su'ing to another user, emacs gets the wrong directory. i'd say this >>is busted. > >I'm not sure which you say is busted. It seems highly suspect >to look at your environment for the $PWD. It's like trusting >it for $USER. Use getwd() and getpwnam(getuid()) for these. >What if a program does its own chdir() followed by an exec() >or system()? The only time $USER isn't trusted is when security is at stake. Having a $PWD that is incorrect seems very ungood to me. You could at least remove it from the environment if you know it's wrong. -- Richard Foulk richard@pegasus.com
jv@mh.nl (Johan Vromans) (08/06/90)
In article <1990Aug5.115155.10191@pegasus.com> richard@pegasus.com (Richard Foulk) writes: > The only time $USER isn't trusted is when security is at stake. Having > a $PWD that is incorrect seems very ungood to me. You could at least > remove it from the environment if you know it's wrong. The environment variable PWD does not have any relation at all with the current working directory, although some programs think it does. Because sometimes it does reflect where you are, it may be used as a starting point to find out the current working dir. Removing PWD from the environment in certain situations would violate all rules. The user is in total control of all environment variables, no program should interfere. Johan -- Johan Vromans jv@mh.nl via internet backbones Multihouse Automatisering bv uucp: ..!{uunet,hp4nl}!mh.nl!jv Doesburgweg 7, 2803 PL Gouda, The Netherlands phone/fax: +31 1820 62911/62500 ------------------------ "Arms are made for hugging" -------------------------
stef@zweig.sun (Stephane Payrard) (08/07/90)
At high levels, the infos about the current directory, are not very reliable. But sometimes it is no better in the lowest level!!! On a Sun host using automounter (at least in SunOS 4.1), you can't even always expect something usable from getwd() or getcwd(). As an example, my current directory is: /home/fred But getwd() says me that it is /auto/home/fred This path will work as long as the file-system is mounted. But the automounter unmounts file systems not recently referenced and is unable to understand /auto/home/fred once the corresponding has been unmounted. I guess what happened is that getcwd() tried to normalize the path and returned a path without symbolic links. This is clearly not the correct behavior with automounted directories. Using the infos in /etc/mtab and the automounter maps, it should be possible to write a perl script which does correctly what getwd() should do. In my particular case, I know that the prefix to suppress is '/auto' so I don't need such a general script. The automounter is a utility which allows to mount dynamically and transparently NFS files-sytems. It uses the NIS (ex YP) so the administration of the mount is not necessarily done host by host. It is great (as in SunOS 4.1), but, as mentionned, has still some minor shortcoming. stef -- Stephane Payrard -- stef@sun.com -- (415) 336 3726 Sun Microsystems -- 2550 Garcia Avenue -- M/S 10-09 -- Mountain View CA 94043
hakanson@ogicse.ogi.edu (Marion Hakanson) (08/09/90)
In article <8974@jpl-devvax.JPL.NASA.GOV> lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) writes: >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(<string>). Is there a >: symmetrical operation which tells me what my working directory is (short >: of invoking pwd in a subshell, that is)? > >No. This has bugged me for a long time. You've got rmdir and mkdir, which are implemented by running the corresponding commands, on systems which don't have rmdir(2) and mkdir(2). Why not provide the same kind of uniform access to getwd? Use the system call if it's there, and run "pwd" for the user if it's not. After all, isn't one of the points of Perl's existence to provide a uniform interface to various systems? Suppose I want to port my Perl script to a machine that doesn't have a pwd command (like DOS or some such)? I've asked for this before. I've also asked for a gethostname interface to the various "uname/hostname/gethostname" system calls, too. And ctime(3) and getfsent(3), etc. You can't always get what you want.... -- Marion Hakanson Domain: hakanson@cse.ogi.edu UUCP : {hp-pcd,tektronix}!ogicse!hakanson