This is the mail archive of the glibc-bugs@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug libc/21902] New: RFE: set_fileno(fp, fd). use case: shell needs to change fd in a FILE


https://sourceware.org/bugzilla/show_bug.cgi?id=21902

            Bug ID: 21902
           Summary: RFE: set_fileno(fp, fd). use case: shell needs to
                    change fd in a FILE
           Product: glibc
           Version: unspecified
            Status: UNCONFIRMED
          Severity: normal
          Priority: P2
         Component: libc
          Assignee: unassigned at sourceware dot org
          Reporter: vda.linux at googlemail dot com
                CC: drepper.fsp at gmail dot com
  Target Milestone: ---

I'm using ordinary FILE i/o for reading scripts in the code of hush shell,
instead of rolling my own implementation, so that I can reuse buffering code in
libc, through the use of fgetc().

This works for almost all cases, except this one: if in script I have a
redirect which says shell wants to open a fd which happens to be equal to the
fd (say, 10) shell already used for script FILE object:

    exec 10>FILE

What other shells do in this situation is they simply dup and close script fd
[in real code, they use fcntl(F_DUPFD) instead of dup() since they want to
avoid getting low fds], so that fd is "moved" and no longer collides with the
redirect.

I can do this trick, but since I use FILE interface, then I need to inform libc
that it needs to use new fd for this FILE.

"fileno(fp) = new_fd;" is non-portable and does not work in glibc: it's a
function, not a macro referencing (fp)->field_holding_fd.

"fclose(fp); fp = fdopen(new_fd);" is not good since fp may have some buffered
input, which will be lost by such code.

How about adding a "set_fileno(fp, fd)" extension, with some easy define to
probe for to conditionally use it?

To make life easier for implementers, I propose that API definition of it
should say that any buffered input or output data is not discarded
or sent to previous fd during/after the call - the function only
changes internal fd. It does neither flushing nor seeking nor discarding of
buffers. Essentially, user has to take care and fflush(fp)
before he starts messing with fds, or buffered data may end up up written to a
wrong fd.

While bouncing around this idea on IRC with other people, some said it could be
a thing which would help them with another problem they had. They had a FILE
object which they wanted to stop using and free it, but to _not_ close the
underlying fd. Along the lines of:

fflush(fp);
fd = fileno(fp);
fclose_but_not_close(fp);

and having fd still open. (They could not work around with dup(fd) before
fclose(), since this was in a library code, fd had to stay the same due to
concurrency and API issues).

They say that if set_fileno() would exist and would allow set_fileno(fp, -1),
it would do what they want.

-- 
You are receiving this mail because:
You are on the CC list for the bug.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]