On Tue, Jul 24, 2012 at 6:50 PM, Nadav Har'El <[email protected]>wrote:
> > This is a very interesting analysis, which I've never considered before. > > With pipes, we can perhaps argue the owner is wrong - that we're talking > about a "fake" file so Linux could have invented a different owner for > it. > Everything is a file, as we know, even a pipe. The ownership is important, and was switched from (presumably) the euid to 0 at some point, causing the described problem. I don't know why and I'd like to know. or maybe it's a bug? > However, there's an even bigger problem I think: Consider a situation > where /proc/self/fd/2 points not to a pipe, but to an on-disk file: > > This file may belong to another user - it could have been passed to the > current process by inheritance, or over a unix-domain socket or > whatever. The current process *is* able to use the file descriptor, but > it won't be able to open /proc/self/fd/2. And this can't even be fixed > because the file this points to has certain owner and permission bits, > and the kernel can't mess with those (like it theoretically could with the > fake pipe file in your example). > Isn't it the same as redirecting stderr to a real file and finding out that you don't have permissions to write to it? > I do think this is a logic bug, and the reason why it came to be is, > I believe, the following: > > Old versions of Unix following 8th Edition Research Unix had a similar > feature called /dev/fd/... (see http://man.cat-v.org/unix_8th/4/fd). > There was a small, but for your purpose very important, difference > between how /dev/fd worked then, and how /proc/self/fd/... works in > Linux. "/dev/fd/2" wasn't a symbolic link (symbolic links were new to > Unix at the time, and were not commonly used in any case). It was a > special device (you had just 127 of them). When any process open()ed > this device, the open would always succeed - the manual specified that > open("/dev/fd/n", mode) is identical to dup(n). No additional permission > testing would be done. /dev/fd/2 (and the identical /dev/stderr) would > work exactly like you wanted. > [By this time I have already grabbed a copy of APUE from a colleague's desk and found all of the above written there, including the statement that /dev/stderr was equivalent to /dev/fd/2. In fact, if memory serves, in the dark bygone days - possibly in the previous millennium - /dev/stderr used to be a symlink to /dev/fd/2. My memory has been noticed to be faulty occasionally in the past.] This is exactly the difference - /dev/fd/2 was "special" and today's /dev/stderr is not. I generally subscribe to the philosophy of having as few special cases as possible, so treating /dev/stderr as a regular file (with open(), etc) rather than as a special file actually appeals to my sense of aesthetics. But then care should be taken not to fail where failure is not expected - in this case, permissions should be right. [There may, theoretically, be a good security reason why the pipe belongs to root now, but I am not aware of any.] > Linux deviated from this implementation for several reasons, one of them > being that is a cool feature to do "ls -l /proc/self/fd" and see the > names of all the open files. (there are several other important reasons > that we can discuss if you want). This alternative implementation broke > the correct behavior that Unix's /dev/fd/2 had - as you discovered. > > I don't know if Linux should be fixed at this point, as so much water > has passed under the bridge since Unix implemented /dev/stderr > correctly. I think /dev/stderr (and stdin, stdout) at least could > easily have been fixed - even if the rest of /proc/fd is more difficult > to fix. > > But I think it's important that this caveat is documented in proc(5), > And in bash(1), as I pointed out in my reply to Amos. > > I remember when I learned Unix, it took me a while to understand what > the strange incantations like > > something >filename 2>&1 > > actually did. But when I finally understood how it works (i.e., uses > dup(2)), I never had any problem with this syntax. I do not have any problem with the syntax. I do have to work with other people and less experienced folks may - and do - have problems with the admittedly rather arcane rules. Doing ">/dev/stderr" is much clearer and cleaner and readily readable and understandable (to say nothing of being very similar to g?awk that is so often used together with shell scripts - there "/dev/stderr" *is* treated specially). The desire to express myself clearly and cause as little confusion as possible led me to prefer ">/dev/stderr". > And understanding > what these do is important, because the authors of CSH obviously didn't > and thus completely ruined that shell's redirection capabilities > (see the very first entry in > http://www.faqs.org/faqs/unix-faq/shell/csh-whynot/ ) > Don't start... ;-) -- Oleg Goldshmidt | [email protected] <[email protected]>
_______________________________________________ Linux-il mailing list [email protected] http://mailman.cs.huji.ac.il/mailman/listinfo/linux-il
