You apparently can't share named pipe instances. They short-circuit. When I
open four command shells, do a mkfifo /tmp/fifo, and then do the following:
Shell one and two:
cat /tmp/mkfifo
Shell three and four:
cat > /tmp/mkfifo
Both of the write windows go into the FIRST read window. The second read
window continues to block on the open, getting nothing.
Is this documented somewhere? This wasn't the behavior I expected out of the
suckers. Read blocks until somebody does a write, and write blocks until
somebody does a read, but other writes don't block as long as there's at
least one reader, and the second read blocks until the first goes away. It's
not symmetrical. I can go back to "open /tmp/$pid, read, write, unlink
/tmp/$pid", but it's annoying.
This behavior is posix, perhaps? (2.4.17 kernel if that makes a difference.
It's probably intentional, it's just weird...)
I ran into THIS problem because pipe(3) has an even STRANGER behavior. It
does NOT like being mixed with dup2(). Pesudo-code:
int pipes[2];
pipe(pipes)
dup2(pipes[0],0);
close(pipes[0]);
Boom: the pipe is no longer usable. The stdin instance of it is closed too.
Read from it you get an error. (But if I DON'T close it, I'm leaking file
handles, aren't I? AAAAAAAAH!)
Sigh. It's friday evening. I should go do something else for a while...
Rob
On Fri, Jan 25, 2002 at 01:13:58PM -0500, Rob Landley wrote:
>
> int pipes[2];
>
> pipe(pipes)
> dup2(pipes[0],0);
> close(pipes[0]);
>
> Boom: the pipe is no longer usable. The stdin instance of it is closed too.
> Read from it you get an error. (But if I DON'T close it, I'm leaking file
> handles, aren't I? AAAAAAAAH!)
Did you close stdin before the pipe()? If so, the read end of the pipe
will get descriptor 0, the dup2() has actually no effect, and with the
close() you just closed stdin again.
Andreas
--
Andreas Ferber - dev/consulting GmbH - Bielefeld, FRG
---------------------------------------------------------
+49 521 1365800 - [email protected] - http://www.devcon.net
Followup to: <20020126021610.YKAU20810.femail29.sdc1.sfba.home.com@there>
By author: Rob Landley <[email protected]>
In newsgroup: linux.dev.kernel
>
> You apparently can't share named pipe instances. They short-circuit. When I
> open four command shells, do a mkfifo /tmp/fifo, and then do the following:
>
> Shell one and two:
>
> cat /tmp/mkfifo
>
> Shell three and four:
>
> cat > /tmp/mkfifo
>
> Both of the write windows go into the FIRST read window. The second read
> window continues to block on the open, getting nothing.
>
A pipe is *one* communications channel.
A socket is *a communications channel creator*.
It sounds like what you're expecting is what would happen if we
allowed open() on a Unix domain socket to do the obvious thing (can
we, pretty please?)
-hpa
--
<[email protected]> at work, <[email protected]> in private!
"Unix gives you enough rope to shoot yourself in the foot."
http://www.zytor.com/~hpa/puzzle.txt <[email protected]>
On Sat, Jan 26, 2002 at 01:07:06AM -0800, H. Peter Anvin wrote:
It sounds like what you're expecting is what would happen if we
allowed open() on a Unix domain socket to do the obvious thing (can
we, pretty please?)
Why? Do any other OS's support this? It seems pointless if it's
nonportable, but, if for arguments sake, several other OSs provide
this then I guess we could for compatability reasons... and I assume
with this proposal open would be jost socket/connect --- accept
behavior would still require accept?
--cw
Chris Wedgwood wrote:
> On Sat, Jan 26, 2002 at 01:07:06AM -0800, H. Peter Anvin wrote:
>
> It sounds like what you're expecting is what would happen if we
> allowed open() on a Unix domain socket to do the obvious thing (can
> we, pretty please?)
>
> Why? Do any other OS's support this? It seems pointless if it's
> nonportable, but, if for arguments sake, several other OSs provide
> this then I guess we could for compatability reasons... and I assume
> with this proposal open would be jost socket/connect --- accept
> behavior would still require accept?
>
Yes, that I would. Why is it so "pointless if it's nonportable?" Under
that argument Linux should never be able to do anything that any other
OS hasn't already done. What it does it it makes it very easy to
replace a file-based convention -- say, purely as an example,
~/.signature -- with a process-based one. A FIFO won't do, since it
only contains one data stream and therefore can become corrupt if opened
by more than one process.
There should be no reason to limit the utility of common operations.
open() is one of the fundamental operations -- you can open *anything*
in the namespace, except, for no good reason, Unix domain sockets.
-hpa