[Vm-dev] FilePlugin and reading from stdio

Eliot Miranda eliot.miranda at gmail.com
Fri Sep 23 17:22:08 UTC 2016


Hi Holger,

On Fri, Sep 23, 2016 at 12:33 AM, Holger Freyther <holger at freyther.de>
wrote:

>
> Good Morning,
>
> I am working on some primitives to allow to populate a SQFile* based on
> int fd/FILE* and tried to understand the semantics of isStdioStream. When
> opening a non-file (e.g. a file descriptor returned from inotify_init1) I
> noticed this gem:
>
>
>                 bytesRead = 0;
>                 do {
>                         clearerr(file);
>                         if (fread(dst, 1, 1, file) == 1) {
>                                 bytesRead += 1;
>                                 if (dst[bytesRead-1] == '\n'
>                                  || dst[bytesRead-1] == '\r')
>                                         break;
>                         }
>                 }
>                 while (bytesRead <= 0 && ferror(file) && errno == EINTR);
>
> * >>#primRead:into:startingAt:count: will ignore count and only fill one
> byte at max. After the first successful fread  the while loop will be left.
> The if for checking for a \n or \r could be deleted. I assume the intention
> was to read until bytesRead == count or \n\r? So e.g. even count: 0 will be
> ignored and turned into a '1'.
>

Right.  I added code to make reads from stdin work.  I was implementing the
following arm for stdin:

    else
        do {
            clearerr(file);
            bytesRead = fread(dst, 1, count, file);
        }
        while (bytesRead <= 0 && ferror(file) && errno == EINTR);

i.e. the preexisting code insisted on only reading one character at a time.

And as the comment says:

        /* Line buffering in fread can't be relied upon, at least on Mac OS
X
         * and mingw win32.  So do it the hard way.
         */
        bytesRead = 0;
        do {
            clearerr(file);
            if (fread(dst, 1, 1, file) == 1) {
                bytesRead += 1;
                if (dst[bytesRead-1] == '\n'
                 || dst[bytesRead-1] == '\r')
                    break;
            }
        }
        while (bytesRead <= 0 && ferror(file) && errno == EINTR);


> * To me line buffering looks a bit like a workaround but if we want this
> semantic for stdio can't we use fgets?
>

That seems like a good idea.  So you're proposing

            fgets(dst,1,file)

right?  Much nicer.  To whoever implements this please test on Windows and
Mac OS and Linux.


> regards
>         holger


_,,,^..^,,,_
best, Eliot
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.squeakfoundation.org/pipermail/vm-dev/attachments/20160923/978a8aef/attachment.htm


More information about the Vm-dev mailing list