"Nadav Har'El" <[email protected]> writes: > No, this cannot happen. write(2) cannot fail because of permission > problems, only the open(2) can.
Actually, if the file was not open for writing write(2) will return EBADF. ;-) While there are, indeed, many ways to acquire a fd the "normal" case, e.g., for echo "fubar" > $HOME/tmp/myfakestdout (this is same as my redirecton, only with a "real" file on a disk) involves an open() call and a dup2(3,1) (assuming open() returns 3). If you do not have write permissions on the file open() will return EACCESS and you will see "Permission denied" on your stderr stream. > Like I explained, they *can't* be done right (when right mean "just > like dup(2) would work) when it comes to ordinary files (not pipes). > > The only way to do this right, as far as I can see, is for > /dev/stderr and friends *not* to be symbolic links. Sorry, I don't really see what symlinks have to do with it. I think /dev/stderr and friends have been symlinks since forever (even Stevens says so, and, sadly, he passed away years ago), and everything worked just fine when * /dev/stderr was a symlink to /dev/fd/2 * /dev/stderr is a symlink to a tty character device * /dev/stderr was a symlink to a pipe with appropiate ownership The problem *only* occurs when /dev/stderr is a symlink to a pipe owned by a different user (root, specifically), and while group ownership is appropriate there is no group write permission. I think the "symlink" and "pipe" parts are irrelevant, as is the "using open()" part - these are just implementation details. After all, even for the good old /dev/fd/2 there was an open() call, the special implementation part was that the mode argument was ignored. Incidentally, if I read Stevens right this had nothing to do with bash - the behaviour would be the same if you opened /dev/fd/* in your own code as well. Or if you opened /dev/stderr in your own code. As far as I understand this special treatment was built into open(2). I didn't immediately see anything special in the logic of, say, do_filp_open() in the kernel's fs/namei.c. As far as I could see symlinks are followed unil resolved (the branch labeled "do_link") and then the real work is done (the "do_last" label). At some point there is a check for special_file (in do_dentry_open() in fs/open.c) but this checks whether the file is a character device or a block device or a pipe or a socket and seems intended for some sort of bookkeeping rather than actively ignoring the mode (which would not sound logical). Not sure - too tired. As I mentioned before, doing nothing special would be, in fact, elegant, but then it shouldn't fail... ;-) I am inclined to suspect that the pipe that the kernel creates has wrong ownership/permissions, and if/when that is fixed everything will be sane again. -- Oleg Goldshmidt | [email protected] _______________________________________________ Linux-il mailing list [email protected] http://mailman.cs.huji.ac.il/mailman/listinfo/linux-il
