Mail Archives: djgpp-workers/1998/03/23/08:57:26
Eli Zaretskii wrote:
>
> There's a problem in the current libc which I'd like to solve in
> v2.02. One of its consequences is the following lossage:
>
> C:\DJGPP\BIN> grep foobar *
> grep: writing output: No space left on device (ENOSPC)
>
> This happens if one of the files has the ^Z character embedded in it.
>
> This is caused by the assumption in the low-level libc functions which
> write data, that if you instruct DOS to write a buffer and DOS writes
> only part thereof, the reason is that the disk is full, and so they
> set errno to ENOSPC.
Isn't the REAL problem here that the ^Z should never get returned by a
read operation from a character device/file. IMO the way text-data is
stored should be entirely transparent to the user program (AFAIK POSIX
requires this), this means that the read functions should do CR/LF to NL
and ^Z to EOF translations. AFAIK this is enough to ensure that ^Z never
gets passed to the write functions. A write function can optionally
append a ^Z upon close-time.
> This assumption breaks if the data is written to the console which
> hasn't been switched to raw mode (i.e., the I/O is done in text
> mode). DOS stops writing and returns prematurely when asked to write
> data with embedded ^Z characters to a character device in cooked
> mode.
>
> Here's the problem: DOS doesn't give any indication that would allow
> to distinguish between the disk full case and the ^Z case. The only
> thing we can do is to assume that if the handle points to a character
> device that's in cooked mode, we have the ^Z case. We can certainly
> do so in the case of the console device (it obviously cannot become
> ``full''). I'm not certain about other devices, though. For example,
> what if somebody writes to COM1, and the other side breaks the
> connection?
IMO, there are only two cases: text files/devices and binary
files/devices. I don't see any use for making a distinction between
cooked-mode devices and files (I almost wrote cooked devices :-) )
> Assuming we can distinguish between these two cases, the next question
> is what to do about that. It seems that the best alternative is to
> filter ^Z out of the data, as if it were not there. Any other
> alternative would mean trouble in some cases. For example, if the
> buffer begins with ^Z, if we don't write it and return 0, many
> programs will take that as an error and print an error message. (Btw,
> an attempt to have that error message make some sense was the original
> motivation for assigning ENOSPC to errno in these cases.)
Assuming that ^Z still needs correct handling on output:
IMO, a ^Z (at any place in the output data) should turn a file in EOF
mode, and let write and family ignore any further output to that file
(until the EOF indicator gets reset).
The fact that 0 will be returned is in fact an error condition in this
case since a ^Z should never have got read.
> Filtering ^Z is easily done in functions which examine each character
> in the buffer (e.g., `write'). In other cases, I suggest only to
> handle the case where ^Z is the first character in the buffer. If ^Z
> is somewhere in the middle, the caller will get a smaller return value
> than the size of buffer it wanted to write, and will typically try to
> write the rest of the buffer beginning with the next unwritten
> character, which is ^Z.
Why would a user make the assumption that after a partial write, the
remainder will get written succesful?
> 1) Is it okay to assume that premature end of output to the console
> device in cooked mode means ^Z? How about other character
> devices?
> 2) Does anybody see any problems with filtering ^Z out
> of data when writing to the console device in cooked mode? How
> about other character devices?
> 3) Is the filtering method outlined above good enough? Does anybody
> see a better way?
I expressed my opinion about these above.
--
\ Vik /-_-_-_-_-_-_/
\___/ Heyndrickx /
\ /-_-_-_-_-_-_/
- Raw text -