pfalstad@phoenix.Princeton.EDU (Paul John Falstad) (09/14/90)
Can anyone tell me how /bin/pwd works? I thought it was a trivial program until I tried to write my own without getcwd(3). getcwd is not a system call, so it must be possible. The way I think it works is quite complicated, so I thought there would be an easier way. David Hemmings appeared by permission of the National Forestry Commission.
gwyn@smoke.BRL.MIL (Doug Gwyn) (09/14/90)
In article <2488@idunno.Princeton.EDU> pfalstad@phoenix.Princeton.EDU (Paul John Falstad) writes: >Can anyone tell me how /bin/pwd works? I thought it was a trivial >program until I tried to write my own without getcwd(3). getcwd is not >a system call, so it must be possible. The way I think it works is >quite complicated, so I thought there would be an easier way. No, on most systems there is no easier way than the obvious one of seeing where a succession of ".."s gets you.
pfalstad@phoenix.Princeton.EDU (Paul John Falstad) (09/14/90)
In article <13851@smoke.BRL.MIL> gwyn@smoke.BRL.MIL (Doug Gwyn) writes: >In article <2488@idunno.Princeton.EDU> pfalstad@phoenix.Princeton.EDU (Paul John Falstad) writes: >>Can anyone tell me how /bin/pwd works? I thought it was a trivial >>program until I tried to write my own without getcwd(3). getcwd is not >>a system call, so it must be possible. The way I think it works is >>quite complicated, so I thought there would be an easier way. >No, on most systems there is no easier way than the obvious one of >seeing where a succession of ".."s gets you. That was what I considered "the easy way." But how do you do that? For example, how do you find out the name of "."? You could find out its inode, and then check the previous directory to see which name matches its inode; but that only works until you get to the root of the filesystem your directory is mounted in (I don't mean "/"). What then? Do you have to check /etc/mtab? I think there should be more race prejudice. <slap> LESS race prejudice.
cpcahil@virtech.uucp (Conor P. Cahill) (09/14/90)
In article <2488@idunno.Princeton.EDU> pfalstad@phoenix.Princeton.EDU (Paul John Falstad) writes: >Can anyone tell me how /bin/pwd works? I thought it was a trivial On BSD style systems /bin/pwd calls the library function (I think it is getcwd(), but don't have the manual nearby). On System V style systems, getcwd(3) popen(3)'s "/bin/pwd" to get the current workind directory. Anyway, the way pwd works is something like the following: Stat the current directory (".") and get the inode number and device number Open ".." and read each entry if you find an entry with the same inode number stat it if it is the same device number you got a match, save name portion close this directory start again one directory higher if you don't find an entry with the right inode number go back and stat each entry looking for the one with the correct device number This goes on and on until you get to the top of the filesystem. (you get to the top when a stat of . & .. return the exact same stuff. -- Conor P. Cahill (703)430-9247 Virtual Technologies, Inc., uunet!virtech!cpcahil 46030 Manekin Plaza, Suite 160 Sterling, VA 22170
gwyn@smoke.BRL.MIL (Doug Gwyn) (09/15/90)
In article <2497@idunno.Princeton.EDU> pfalstad@phoenix.Princeton.EDU (Paul John Falstad) writes: -In article <13851@smoke.BRL.MIL> gwyn@smoke.BRL.MIL (Doug Gwyn) writes: ->No, on most systems there is no easier way than the obvious one of ->seeing where a succession of ".."s gets you. -That was what I considered "the easy way." But how do you do that? -For example, how do you find out the name of "."? You could find out -its inode, and then check the previous directory to see which name -matches its inode; but that only works until you get to the root of the -filesystem your directory is mounted in (I don't mean "/"). What then? Do -you have to check /etc/mtab? Yes, you got it, exactly.
guy@auspex.auspex.com (Guy Harris) (09/15/90)
>For example, how do you find out the name of "."? You could find out >its inode, and then check the previous directory to see which name >matches its inode; but that only works until you get to the root of the >filesystem your directory is mounted in (I don't mean "/"). What then? Do >you have to check /etc/mtab? No. You just have to do a little more work to see which name matches the inode. I.e., if the directory whose name you're trying to find, and the directory in which you're trying to find it, are on the same file system, *and* you know that the directory entries you get back from "readdir()" or whatever contain i-numbers (POSIX does *not* guarantee this, although the SVID and XPG3 do), you can use the i-number from the directory entry. However, if they're *not* on the same file system, for each directory entry in the directory you're reading you have to construct the path of the file that entry refers to and "stat()" it (or "lstat()" it, if you have "lstat()") to find out its inumber; the directory entry's inumber will be the inumber of the mount point, but the "stat()" will give the inumber of the file mounted atop that mount point.
guy@auspex.auspex.com (Guy Harris) (09/15/90)
>On System V style systems, getcwd(3) popen(3)'s "/bin/pwd" to get >the current workind directory. On some, anyway. That's how S5 from AT&T - at least prior to S5R4 - implements "getcwd()", but you could have "getcwd()" be the routine that does the work (just like "getwd()", but with bounds checking) and have "/bin/pwd" just call it. (SGI basically does that in recent releases, although "getcwd()" ends up calling a BSD-flavored "getwd()" to do the actual work). Dunno whether S5R4 does that or not.
del@thrush.mlb.semi.harris.com (Don Lewis) (09/15/90)
In article <13858@smoke.BRL.MIL> gwyn@smoke.BRL.MIL (Doug Gwyn) writes: >In article <2497@idunno.Princeton.EDU> pfalstad@phoenix.Princeton.EDU (Paul John Falstad) writes: >-In article <13851@smoke.BRL.MIL> gwyn@smoke.BRL.MIL (Doug Gwyn) writes: >->No, on most systems there is no easier way than the obvious one of >->seeing where a succession of ".."s gets you. >-That was what I considered "the easy way." But how do you do that? >-For example, how do you find out the name of "."? You could find out >-its inode, and then check the previous directory to see which name >-matches its inode; but that only works until you get to the root of the >-filesystem your directory is mounted in (I don't mean "/"). What then? Do >-you have to check /etc/mtab? > >Yes, you got it, exactly. This scheme fails badly in the presence if Sun's loopback mounts because the filesystem can be mounted in multiple places. -- Don "Truck" Lewis Harris Semiconductor Internet: del@mlb.semi.harris.com PO Box 883 MS 62A-028 Phone: (407) 729-5205 Melbourne, FL 32901
cpcahil@virtech.uucp (Conor P. Cahill) (09/15/90)
In article <13858@smoke.BRL.MIL> gwyn@smoke.BRL.MIL (Doug Gwyn) writes: >In article <2497@idunno.Princeton.EDU> pfalstad@phoenix.Princeton.EDU (Paul John Falstad) writes: >-matches its inode; but that only works until you get to the root of the >-filesystem your directory is mounted in (I don't mean "/"). What then? Do >-you have to check /etc/mtab? > >Yes, you got it, exactly. Actually you can use the device number portion. (get the device number from the current directory and then stat each entry in the .. directory looking for an entry on the same device). -- Conor P. Cahill (703)430-9247 Virtual Technologies, Inc., uunet!virtech!cpcahil 46030 Manekin Plaza, Suite 160 Sterling, VA 22170
toma@ozdaltx.UUCP (Tom Armistead) (09/18/90)
In article <2488@idunno.Princeton.EDU>, pfalstad@phoenix.Princeton.EDU (Paul John Falstad) writes: > Can anyone tell me how /bin/pwd works? I thought it was a trivial > program until I tried to write my own without getcwd(3). getcwd is not > a system call, so it must be possible. The way I think it works is > quite complicated, so I thought there would be an easier way. > > David Hemmings appeared by permission of the National Forestry Commission. I don't know how /bin/pwd works - but I ran into the same problem and this is how I tackled it... Open "." using stat(2), get the inode number and save it. Open ".." using stat, get the inode number, if equal to the inode for "." then you are at the root dir "/". If they are not equal: open ".." using opendir(3C) and read the entries from it using readdir(3C) until you find the inode number for ".", this will give you the name of the current dir from the parent. Repeat this process walking back to "../..", then "../../..", etc, until the 2 inodes are equal... It sounds kinda messy, but it really isn't after you think about???? I have this coded and working (for System V 3.2), if you would like a copy, just let me know... Tom -- ------------------------------- {uunet,smu,ames}!sulaco!ozdaltx!toma (Tom Armistead @ Garland, Texas) {mic,void,egsner}!ozdaltx!toma
a0528@gray3.zrz.tu-berlin.de (Ueb28) (09/19/90)
In article <6960@ozdaltx.UUCP> toma@ozdaltx.UUCP (Tom Armistead) writes:
I don't know how /bin/pwd works - but I ran into the same problem and this
is how I tackled it...
Open "." using stat(2), get the inode number and save it.
Open ".." using stat, get the inode number, if equal to the inode for "." then
you are at the root dir "/".
If they are not equal:
open ".." using opendir(3C) and read the entries from it using readdir(3C)
[etc.]
It has to be something like that, if not exactly. On a System here
around there is a partition with a scrambled root directory. When you
do a ls -al /expo1, you get:
total 24
drwxrwxrwx 18 root root 368 Sep 5 20:21
drwxr-xr-x 5 root other 80 Jun 23 01:26 386ix
drwx------ 3 a0203 101 64 May 2 22:12 a0203
drwxr-xr-x 3 a0238 other 64 Aug 27 10:57 a0238
[etc.]
The first entry is really blank, and there are NO "." and ".." entries.
System works fine, except for users or programs who want to do a pwd
on this partition. pwd answers:
pwd: cannot open ..
I suggested to patch the first two entries to inode number 2 and the
names "." and "..", but a new Unix release will soon be installed, and
in this turn the partition will be backuped and mkfs'ed.
--
-----------------
Juergen Nickelsen
nickel@w104zrz.zrz.tu-berlin.de
nickelsen@mikroperipherik.e-technik.tu-berlin.dbp.de