why isn't stdio full-duplex? 
Author Message
 why isn't stdio full-duplex?

[Skeptical about topicality, but it could apply to C also, I think. -mod]

if i fopen() a stream for both reading and writing, stdio is careful
to (and i'm only talking with certainty about the Torek/BSD version
here) flush all writes before allowing me to do a read, but it will
_toss_ all unread data before doing a write.

i think i can understand the historical basis for this:
        - with files, it's more correct anyway, because after you _do_
          that write, the data that stdio got from the file for you that
          you haven't read yet doesn't really "exist" anymore , in some
          sense.
        - with traditional pipes, you can only read _or_ write them, but
          not both.
        - with tty's, you're usually (but not always!) using stdin
          and stdout to deal with the pre-opened fd 0 and fd 1, so
          the problem doesn't come up.
        - AT&T didn't _have_ sockets, so they didn't care about _that_
          case. :-)

what i can't understand is how in the world of BSD networking nobody
ever changed stdio so that i can fdopen(some_socket, "rw") (or whatever)
and get a (FILE *) that i can use for both reading and writing.  you see
a lot of code that has to go out of its way to open two handles, when
one should do the trick.

what am i missing?  is there something non-obviously hard about
accomplishing this?  stdio already allocates and frees its buffer on the
fly as it needs them (for instance when switching from buffered to
unbuffered i/o), so couldn't it just maintain two buffers when it needs
to?

--
---------------------
    paul fox                            american internet corporation



Tue, 17 Nov 1998 03:00:00 GMT  
 why isn't stdio full-duplex?

|>
|> if i fopen() a stream for both reading and writing, stdio is careful
|> to (and i'm only talking with certainty about the Torek/BSD version
|> here) flush all writes before allowing me to do a read, but it will
|> _toss_ all unread data before doing a write.

I assume you know that the proper way to switch between reading and writing
is to do a file positioning command or a fflush every time you switch.  This
is independent of any implementation.

|> i think i can understand the historical basis for this:
|>   - with files, it's more correct anyway, because after you _do_
|>     that write, the data that stdio got from the file for you that
|>     you haven't read yet doesn't really "exist" anymore , in some
|>     sense.
|>   - with traditional pipes, you can only read _or_ write them, but
|>     not both.
|>   - with tty's, you're usually (but not always!) using stdin
|>     and stdout to deal with the pre-opened fd 0 and fd 1, so
|>     the problem doesn't come up.
|>   - AT&T didn't _have_ sockets, so they didn't care about _that_
|>     case. :-)
|>
|> what i can't understand is how in the world of BSD networking nobody
|> ever changed stdio so that i can fdopen(some_socket, "rw") (or whatever)
|> and get a (FILE *) that i can use for both reading and writing.  you see
|> a lot of code that has to go out of its way to open two handles, when
|> one should do the trick.

I don't believe this is ever necessary if you are dealing with a request/response
packet driven system, where the communicating processes work in lock-step.

On the other hand, the overhead of an addition FILE structure is so little
compared to the file buffer that using two FILE* has practically no advantage
over using one (besides a simpler naming scheme).  As you note, the current
behavior is more correct for files anyway.

Konrad Schwarz



Wed, 18 Nov 1998 03:00:00 GMT  
 why isn't stdio full-duplex?


writes:

|> [Skeptical about topicality, but it could apply to C also, I think. -mod]

|> if i fopen() a stream for both reading and writing, stdio is careful
|> to (and i'm only talking with certainty about the Torek/BSD version
|> here) flush all writes before allowing me to do a read, but it will
|> _toss_ all unread data before doing a write.

|> i think i can understand the historical basis for this:
|>   - with files, it's more correct anyway, because after you _do_
|>     that write, the data that stdio got from the file for you that
|>     you haven't read yet doesn't really "exist" anymore , in some
|>     sense.
|>   - with traditional pipes, you can only read _or_ write them, but
|>     not both.
|>   - with tty's, you're usually (but not always!) using stdin
|>     and stdout to deal with the pre-opened fd 0 and fd 1, so
|>     the problem doesn't come up.
|>   - AT&T didn't _have_ sockets, so they didn't care about _that_
|>     case. :-)

|> what i can't understand is how in the world of BSD networking nobody
|> ever changed stdio so that i can fdopen(some_socket, "rw") (or whatever)
|> and get a (FILE *) that i can use for both reading and writing.  you see
|> a lot of code that has to go out of its way to open two handles, when
|> one should do the trick.

|> what am i missing?  is there something non-obviously hard about
|> accomplishing this?  stdio already allocates and frees its buffer on the
|> fly as it needs them (for instance when switching from buffered to
|> unbuffered i/o), so couldn't it just maintain two buffers when it needs
|> to?

The problem is defining when it needs to.  The problem is also defining
the meaning of fseek, for example.

C++ went this route (with its streambuf).  It has certain advantages in
a few limit cases (a C++ stream can be a memory buffer), but if you look
in detail at the definitions required for buffering and seeking,
particularly the dependancies with regards to seek, you will see that it
is not necessarily evident.  (In some cases, like a file, seeking
affects both the read and the write position simultaneously.  In others,
like a memory buffer, you can seek independantly on the read and write
side.)

With regards to sockets, IMHO, there are two totally independant
streams.  So it seems normal that you need two FILE* to process them.
--

GABI Software, Sarl., 8 rue des Francs Bourgeois, 67000 Strasbourg, France
Conseils en informatique industrielle --
                            -- Beratung in industrieller Datenverarbeitung



Wed, 18 Nov 1998 03:00:00 GMT  
 why isn't stdio full-duplex?

Quote:

>[Skeptical about topicality, but it could apply to C also, I think. -mod]

>if i fopen() a stream for both reading and writing, stdio is careful
>to (and i'm only talking with certainty about the Torek/BSD version
>here) flush all writes before allowing me to do a read, but it will
>_toss_ all unread data before doing a write.

Yes, it is certainly allowed to do that.

Quote:
>i think i can understand the historical basis for this:
>        - with files, it's more correct anyway, because after you _do_
>          that write, the data that stdio got from the file for you that
>          you haven't read yet doesn't really "exist" anymore , in some
>          sense.

More specifically if you write data to a file, reposition to where you were
before and read, you'll get the data you just wrote rather than what was
there originally. This only breaks down when the 'file' is a non-seekable
device.

Quote:
>        - with traditional pipes, you can only read _or_ write them, but
>          not both.
>        - with tty's, you're usually (but not always!) using stdin
>          and stdout to deal with the pre-opened fd 0 and fd 1, so
>          the problem doesn't come up.

But it demonstrates a simple and effective way of dealing with the problem.

Quote:
>        - AT&T didn't _have_ sockets, so they didn't care about _that_
>          case. :-)
>From this perspective there's not a lot of difference between sockets and

ttys.

Quote:
>what i can't understand is how in the world of BSD networking nobody
>ever changed stdio so that i can fdopen(some_socket, "rw") (or whatever)
>and get a (FILE *) that i can use for both reading and writing.  you see
>a lot of code that has to go out of its way to open two handles, when
>one should do the trick.

I suspect that most software would continue to use two handles even if
it were able to do it with one. The problem is that on a single stream
you can't have asjacent read and write operations, you must have an
intervening positioning call (fseek, fsetpos, rewind) or in the case of
switching from writing to reading you can also use fflush. By using
separate streams you don't have to worry about things like that.

In principle there's no reason why you can't open two streams on the same
fd (although some implementations are broken in this regard). The bottom
line is that requiring two streams for independent reading and writing
is no great hardship. Indeed it keeps the programming model simple while
maintaining flexibility (e.g. independently setting the read/write
buffering).

Quote:
>what am i missing?  is there something non-obviously hard about
>accomplishing this?  stdio already allocates and frees its buffer on the
>fly as it needs them (for instance when switching from buffered to
>unbuffered i/o),

No, you're only allowed to call setbuf/setvbuf before the first read or
write operation, so the buffer is (in principle) only allocated once.

--
-----------------------------------------


-----------------------------------------



Thu, 19 Nov 1998 03:00:00 GMT  
 why isn't stdio full-duplex?

| if i fopen() a stream for both reading and writing, stdio is careful
| to (and i'm only talking with certainty about the Torek/BSD version
| here) flush all writes before allowing me to do a read, but it will
| _toss_ all unread data before doing a write.
|
| i think i can understand the historical basis for this:

        (reasons deleted)

Or possibly:

        - Without some clever state encoding, getc/putc now has one more
          conditional in it than before, and that extra compare/jump can really
          slow things down.  I've done this in the past (for the Data General
          MV/Eclipse stdio implementation).
--
Michael Meissner, Cygnus Support (East Coast)
Suite 105, 48 Grove Street, Somerville, MA 02144, USA



Fri, 20 Nov 1998 03:00:00 GMT  
 
 [ 5 post ] 

 Relevant Pages 

1. Systems report disk full but really isn't (CopyFile fails)

2. Systems report disk full but really isn't (CopyFile failes)

3. NULL isn't 0/0 isn't NULL

4. Full duplex audio?

5. Full Duplex Asynchronous Named Pipes

6. full-duplex recording and playback

7. CSocket and full duplex (two threads)

8. Full duplex audio on an iPAQ

9. Top Left Icon - Why Isn't it Showing Up Correctly

10. Why isn't malloc necessary here?

11. HELP - why isn't ld working

12. why isn't there a strcasestr ?

 

 
Powered by phpBB® Forum Software