Rob Landley wrote, on 11 Apr 2022:
>
> A bunch of protocols (git, http, mbox, etc) start with lines of data followed 
> by
> a block of data, so it's natural to want to call getline() and then handle the
> data block. But getline() takes a FILE * and things like zlib and sendfile()
> take an integer file descriptor.
> 
> Posix lets me get the file descriptor out of a FILE * with fileno(), but the
> point of FILE * is to readahead and buffer. How do I get the buffered data out
> without reading more from the file descriptor?
> 
> I can't find a portable way to do this?

I tried this sequence of calls on a few systems, and it worked in the
way you would expect:

    fgets(buf, sizeof buf, fp);
    int fd = dup(fileno(fp));
    close(fileno(fp));
    while ((ret = fread(buf, 1, sizeof buf, fp)) > 0) { ... }
    read(fd, buf, sizeof buf);

It relies on fread() not detecting EBADF until it tries to read more
data from the underlying fd.

It has some caveats:

1. It needs a file descriptor to be available.

2. The close() will remove any fcntl() locks that the calling process
   holds for the file.

3. In a multi-threaded process it has the usual problem around fd
   inheritance, but that's addressed in Issue 8 with the addition
   of dup3().

Also, for the standard to require it to work, I think we would need to
tweak the EBADF error for fgetc() (which fread() references) to say:

    The file descriptor underlying stream is not a valid file
    descriptor open for reading and there is no buffered data
    available to be returned.

(adding the "and ..." part).

-- 
Geoff Clare <[email protected]>
The Open Group, Apex Plaza, Forbury Road, Reading, RG1 1AX, England

  • How do I get the buff... Rob Landley via austin-group-l at The Open Group
    • Re: How do I get... Rob Landley via austin-group-l at The Open Group
    • Re: How do I get... Rob Landley via austin-group-l at The Open Group
    • Re: How do I get... Rob Landley via austin-group-l at The Open Group
      • 答复: How do ... Danny Niu via austin-group-l at The Open Group
        • Re: 答复: ... Rob Landley via austin-group-l at The Open Group
          • Re: ... Chet Ramey via austin-group-l at The Open Group
            • ... Rob Landley via austin-group-l at The Open Group
              • ... Chet Ramey via austin-group-l at The Open Group
              • ... Rob Landley via austin-group-l at The Open Group
    • Re: How do I get... Geoff Clare via austin-group-l at The Open Group

Reply via email to