| Summary: | File descriptors created by pipe are both read/write | ||||||
|---|---|---|---|---|---|---|---|
| Product: | Base System | Reporter: | kwilliams <kwilliams> | ||||
| Component: | kern | Assignee: | freebsd-bugs (Nobody) <bugs> | ||||
| Status: | Closed Not Accepted | ||||||
| Severity: | Affects Only Me | CC: | jilles | ||||
| Priority: | --- | ||||||
| Version: | CURRENT | ||||||
| Hardware: | Any | ||||||
| OS: | Any | ||||||
| Attachments: |
|
||||||
The FreeBSD man page pipe(2) clearly documents that pipes are bidirectional and that this is not portable.
Bidirectional pipes were first introduced with STREAMS in System V release 4, one of POSIX's source implementations, so POSIX would not disallow them. Since SUSv3 and POSIX.1-2001, there has been explicit allowance in the "pipe" page:
> It is unspecified whether fildes[0] is also open for writing and whether
> fildes[1] is also open for reading.
I agree that this feature is somewhat questionable. It may hide bugs and its deliberate use is more prone to deadlocks than unidirectional pipes are, but I don't think it should be removed.
I'm sorry but dropping the feature of bidirectional pipes is not planned. |
Created attachment 171448 [details] test program demonstrating the issue pipe(2) is documented by as returning 2 file descriptors, one for reading the other for writing. "Data can be written to the file descriptor fildes[1] and read from the file descriptor fildes[0]. A read on the file descriptor fildes[0] shall access data written to the file descriptor fildes[1] on a first-in-first-out basis." The actual implementation ends up wiring fd[0] to fd[1] such that writes on fd[1] provide data that can be read on fd[0] (as required). Oddly writes to fd[0] provide data that can be read in fd[1]. This deviates from the Posix spec (or at least stomps fully into the 'grey' area), resulting in FBSD utilities being rendered portable between unix-like distros. The attached test program demonstrates this behavior. On strictly compliant distros the attached code will result in the child write and parent read failing.