[comp.unix.internals] replacement getwd

casper@fwi.uva.nl (Casper H.S. Dik) (11/07/90)

I've written a replacement getwd(3) for SunOS 4.x that returns ~user/tail
(with ~user expanded as in /etc/passwd) if the current directory
is a subdirectory of a user's home directory.
[The original might return: /tmp_mnt/foo/bar/bletch/usrs/casper/dir
 the new returns /usr/casper/dir]

I've installed it in my own copy of the shared library and thinks seem
to work fine.

My question is: what utilities (if any) will break because of this?

--
Casper H.S. Dik, casper@fwi.uva.nl,	NIC: !cd151

eric@mks.com (Eric Gisin) (11/07/90)

In article <1431@carol.fwi.uva.nl> casper@fwi.uva.nl (Casper H.S. Dik) writes:

   I've written a replacement getwd(3) for SunOS 4.x that returns ~user/tail
   (with ~user expanded as in /etc/passwd) if the current directory
   is a subdirectory of a user's home directory.
   [The original might return: /tmp_mnt/foo/bar/bletch/usrs/casper/dir
    the new returns /usr/casper/dir]

   I've installed it in my own copy of the shared library and thinks seem
   to work fine.

   My question is: what utilities (if any) will break because of this?

Ideally none would break, because any properly written program
on SysV or SunOS would use getcwd(), not getwd().
Any program that effectively does chdir(getwd()) would break
with your getwd. ~ expansion is handled by applications,
not libc and the kernel.

eric@mks.mks.com (Eric Gisin) (11/08/90)

In some article I write:
. Ideally none would break, because any properly written program
. on SysV or SunOS would use getcwd(), not getwd().

Looking at the Sun man page reveals that getcwd uses popen /bin/pwd
while getwd does things directly. That was stupid of me,
to think that Sun would implement things the obvious, efficient way.

pfalstad@phoenix.Princeton.EDU (Paul John Falstad) (11/08/90)

In article <ERIC.90Nov7131425@femto.mks.com> eric@mks.com (Eric Gisin) writes:
>In article <1431@carol.fwi.uva.nl> casper@fwi.uva.nl (Casper H.S. Dik) writes:
>   I've written a replacement getwd(3) for SunOS 4.x that returns ~user/tail
>   (with ~user expanded as in /etc/passwd) if the current directory
>   is a subdirectory of a user's home directory.
>   [The original might return: /tmp_mnt/foo/bar/bletch/usrs/casper/dir
>    the new returns /usr/casper/dir]
>   My question is: what utilities (if any) will break because of this?
>Ideally none would break, because any properly written program
>on SysV or SunOS would use getcwd(), not getwd().
>Any program that effectively does chdir(getwd()) would break
>with your getwd. ~ expansion is handled by applications,
>not libc and the kernel.

I _think_ he meant that whenever the old getwd() would return the actual
path to a users home directory, the new one will use the symbolic link
listed in /etc/passwd.  At least I infer that opinion the example he
gave.  He didn't really mean getwd would return ~ -- anyone smart enough
to write a library function like this would _probably_ be smart enough
to know that the shell expands ~.

It's probably not such a good idea to replace the library function,
though.  Applications which depend on the result of getwd() to be hard
paths free of symbolic links will break.  I don't know of any offhand
though...

--
Paul Falstad, pfalstad@phoenix.princeton.edu PLink:HYPNOS GEnie:P.FALSTAD
"Your attention, please.  Would anyone who knows where the white courtesy
phone is located please pick up the white courtesy phone."

casper@fwi.uva.nl (Casper H.S. Dik) (11/08/90)

eric@mks.com (Eric Gisin) writes:

    Ideally none would break, because any properly written program
    on SysV or SunOS would use getcwd(), not getwd().
    Any program that effectively does chdir(getwd()) would break
    with your getwd. ~ expansion is handled by applications,
    not libc and the kernel.

What I meant was that I use the pw_dir field from the password file.
In my private copy of the shared library this seems to work well.

Now what about those programs using getcwd()? 
Well, getcwd() calls popen() with the command pwd. Pwd would use my
getwd() except that pwd is a shell builtin and the shell is statically
linked. (This must indicate that sh(1) uses getwd and not getcwd,
for an infinite loop would result).

--
Casper H.S. Dik, casper@fwi.uva.nl,	NIC: !cd151

barmar@think.com (Barry Margolin) (11/08/90)

In article <ERIC.90Nov7131425@femto.mks.com> eric@mks.com (Eric Gisin) writes:
>In article <1431@carol.fwi.uva.nl> casper@fwi.uva.nl (Casper H.S. Dik) writes:
>   I've written a replacement getwd(3) for SunOS 4.x that returns ~user/tail
>   (with ~user expanded as in /etc/passwd) if the current directory
>Any program that effectively does chdir(getwd()) would break
>with your getwd. ~ expansion is handled by applications,
>not libc and the kernel.

Read what he said again: "with ~user expanded".  He was just using the ~
notation as a shorthand in his explanation.

Basically, the difference between his getwd() and the standard one is that
his will return a pathname that may include symbolic links, while the
standard one should always contain only hard links.  One property of the
standard return value is that if it returns "/foo/bar/baz" then you can be
sure that "/foo/bar/baz/.." and "/foo/bar" are equivalent; I can't think of
any applications that would depend on this.

--
Barry Margolin, Thinking Machines Corp.

barmar@think.com
{uunet,harvard}!think!barmar

Chuck.Phillips@FtCollins.NCR.COM (Chuck.Phillips) (11/11/90)

>>>>> On 7 Nov 90 09:57:49 GMT, casper@fwi.uva.nl (Casper H.S. Dik) said:
Casper> I've written a replacement getwd(3) for SunOS 4.x that returns
Casper> ~user/tail (with ~user expanded as in /etc/passwd) if the current
Casper> directory is a subdirectory of a user's home directory.
Casper> [The original might return: /tmp_mnt/foo/bar/bletch/usrs/casper/dir
Casper>  the new returns /usr/casper/dir]

Casper> I've installed it in my own copy of the shared library and thinks seem
Casper> to work fine.

Casper> My question is: what utilities (if any) will break because of this?

Interesting idea, but I'd be more than a little concerned about programs
that *assume* the path returned by getwd() is a valid path.  (That very
problem has caused some pain around here.)  By using your getwd() and
putting a bogus directory in /etc/passwd, you could seriously confuse a
program.

However, always stripping off the initial "/tmp_mnt" from a getwd() path is
a _good thing_ when running the automounter.  IMHO, Sun's version of
getwd() should do this by default.

Problem:
	1. User cd's into automounted directory.  Directory is either
	   mounted at that time or already mounted.
	2. The mount times out and file system is unmounted.
	3. User attempts to access file system again using a "/tmp_mnt/..."
	   path.
	4. It FAILS!  The automounter only pays attention to paths that
	   _don't_ begin with "/tmp_mnt", and the file system doesn't get
	   remounted.

We had one application that would work correctly, as long as you never
paused for ten minutes or longer when using it.  If you _did_ pause that
long or longer, the screen would go black and you'd have to reboot the
machine to recover.  _That_ was a fun problem to figure out!  :-)

I suspect there is a good reason for the /tmp_mnt parallel directory
hierarchy, like avoiding unnecessary stat()s of (or directory open()s in)
NFS file systems.

BTW, Laura Pearlman wrote a fast getwd() replacement that takes extra pains
to avoid unnecessary stat()s of remote directories (avoiding unnecessary
NFS overhead), although it requires an addition to the kernal.  She sent
the code to sun-spots and xanth last January.  Since we weren't, and still
aren't on the net :-(, I can't tell you what happened from there.

	Cheers,
--
Chuck Phillips  MS440
NCR Microelectronics 			chuck.phillips%ftcollins.ncr.com
2001 Danfield Ct.
Ft. Collins, CO.  80525   		...uunet!ncrlnk!ncr-mpd!bach!chuckp