Re: unwanted double reads in /proc routines



Thanks for your comments.
Yes, they were helpful.

Meanwhile I could solve the issue.

1) 'cat' issues a read with len=1024, which I guess is one page.
So it behaves like a normal fread() would, if issued with same length.

2) Since the routine in the driver returns only 2 bytes, another read is
issued to fetch the obviously missing bytes.
I guess this from the fact, that fetching 2 bytes with an ordinary fread()
causes only a single read, as it should be.
I guessed that the eof==1 would be enough to suppress this additional read,
but that was obviously a wrong assumption.

3) Another fault was that in the original routine, the calling function
expected a string of 160 bytes + NUL = 161 bytes.
Therefore, fread was called with len=161.
The driver's read function, however, ended with return strlen(buf).
'man strlen' tells, that
"The strlen() function calculates the length of the string s,
not including the terminating `\0' character."
So 160 was returned, while 161 were expected. This caused the additional
read!
I just had to add the NUL character, increasing the return value by 1.
Which means, that there's no faulty behavior.

4) I could also watch double reads: the first with offset=0, the second with
an offset = bytes of the first read. However, because of the other effects,
and after stracing the calling functions, I'd say that the offset is handled
correctly.
At least it was possible to request a number of bytes, and cause only a
single read, if the returned number of bytes matched the requested len.
However, this was not feasible with 'cat' because of its default len of
1024.

Maybe there's an additional issue if the requested len matches the page size
or a multiple of it. Probably the underlying lib function is not sure if the
returned len=1024 is only because it couldn't transfer more than one page
or if this is really the whole content. (To my opinion eof=1 should solve
this). I'd agree that returning a '0' like in:
if (offset != 0) {
*eof = 1;
return 0;
}
works to "heal" the strange eof treatment.
However, I'd improve this proposal and compare the offset to the correct len
of the whole transmission.

In my application this doesn't work, since data are volatile and every read
provides new data. Double reads would lead to data losses, which I cannot
allow. But now it works, after all.

Bernhard
.



Relevant Pages

  • Writing in the middle of a file
    ... reports that the offset *is* 20. ... % cat letter.txt ... Love, Patrick ...
    (comp.lang.tcl)
  • Re: Linux kernel file offset pointer races
    ... >> parallel processes really need to share the offset? ... the process running would not know what offset to give "cat b" ... send the line "unsubscribe linux-kernel" in ...
    (Linux-Kernel)
  • feof(), fseek(), fread()
    ... If fseek() always clears EOF, is there a way for me to freadfrom an ... offset of a file and still be able to detect EOF?i.e. ... withouting using ... frequentlyand do fread() from that offset. ...
    (comp.lang.c)
  • Re: [9fans] rc question
    ... if you're expecting the cat to start at offset 0, ... (the dup only ups the refcount on the underlying Chan, ... cpu% echo one two three four five six> x ... to set the offset. ...
    (comp.os.plan9)
  • Re: /proc/file read drops data
    ... Did notice, if you do do echo first for a couple of times, and then do ... cat /proc/sample, the cat does not return what it read immediately, and ... update continuousely the offset, event it will grow across page ... boundaries, and I am not if they pages ever get released. ...
    (comp.os.linux.embedded)