This post originated from an RSS feed registered with Ruby Buzz
by Daniel Berger.
Original Post: Linux, realpath, suckage
Feed Title: Testing 1,2,3...
Feed URL: http://djberg96.livejournal.com/data/rss
Feed Description: A blog on Ruby and other stuff.
I discovered today that my implementation of Pathname#realpath does not handle symbolic links properly. Specifically, it doesn't reduce it to a root path. No big deal, really.
For the C version I figured, hey, there's a realpath() function I can use, right? Nope. Once again the Unix guys screw up, this time Linux. Here's a truly bizarre rationalization from the man page:
Avoid using this function. It is broken by design since (unless using the non-standard resolved_path == NULL feature) it is impossible to determine a suitable size for the output buffer, resolved_path. According to POSIX a buffer of size PATH_MAX suffices, but PATH_MAX need not be a defined constant, and may have to be obtained using pathconf(). And asking pathconf() does not really help, since on the one hand POSIX warns that the result of pathconf() may be huge and unsuitable for mallocing memory. And on the other hand pathconf() may return -1 to signify that PATH_MAX is not bounded.
<sarcasm>Oh, no! Whatever will we do if PATH_MAX is set to -1?!</sarcasm>
Here's a idea - make a command decision and set it to 1024 if its less than zero or greater than 1024. Yes, yes, I know. Utterly brilliant. Only I could have thought of that. I mean, wow. Setting an arbitrary limit and telling everyone else to PISS OFF, I DON'T GIVE A FUCK ABOUT THE EDGE CASES, is like, whoa, too radical.
PS - I'd love to know what platforms set PATH_MAX to -1. But I digress.
Anyway, it turns out that this comment about this function being broken has absolutely nothing to do with char buffers. IT JUST DOESN'T WORK.
Unfortunately, the realpath() function on Linux botches it and returns '/dev/pts/0'. As you can see above, /dev/pts/4 is NOT a symbolic link to /dev/pts/0. Why does it return /dev/pts/0 then? I have no idea. Special case maybe? Maybe it can't handle a link to a link? Maybe its a hard link? If so, it isn't documented afaik.
Solaris seems to get it right, btw, and doesn't whine about char buffers. It sets PATH_MAX to 1024 and handles links to links just fine from what little testing I did.
Well, it's all academic at this point, since it looks like I'll have to roll a custom implementation to make sure it works on all platforms.