The Artima Developer Community
Sponsored Link

Ruby Buzz Forum
Linux, realpath, suckage

0 replies on 1 page.

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 0 replies on 1 page
Daniel Berger

Posts: 1383
Nickname: djberg96
Registered: Sep, 2004

Daniel Berger is a Ruby Programmer who also dabbles in C and Perl
Linux, realpath, suckage Posted: Jul 11, 2006 2:41 PM
Reply to this message Reply

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.
Latest Ruby Buzz Posts
Latest Ruby Buzz Posts by Daniel Berger
Latest Posts From Testing 1,2,3...

Advertisement
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.

To wit:
>uname -a
2.6.8.1-12mdksmp

>ls -l /dev/stdout
lrwxrwxrwx  1 root root 15 Apr 21 10:55 /dev/stdout -> /proc/self/fd/1

>ls -l /proc/self/fd/1
lrwx------  1 djberge djberge 64 Jul 11 15:42 /proc/self/fd/1 -> /dev/pts/4

>ls -l /dev/pts/4
crw--w----  1 djberge tty 136, 4 Jul 11 15:56 /dev/pts/4

Ok, so we would expect that the realpath of '/dev/stdout' would be '/dev/pts/4'. Tanaka's Pathname#realpath gets it right:
require 'pathname'
puts Pathname.new('/dev/stdout').realpath.to_s # '/dev/pts/4'

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.

Read: Linux, realpath, suckage

Topic: Symbols, meta-programming and leaks. On harakiri and DoSing Rails? Previous Topic   Next Topic Topic: ZenObfuscate now available

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use