bin/75767: WANTED: "fdclose" function in libc

Giorgos Keramidas keramida at freebsd.org
Tue Jan 4 00:40:26 GMT 2005


The following reply was made to PR bin/75767; it has been noted by GNATS.

From: Giorgos Keramidas <keramida at freebsd.org>
To: "Ronald F.Guilmette" <rfg at monkeys.com>
Cc: bug-followup at freebsd.org
Subject: Re: bin/75767: WANTED: "fdclose" function in libc
Date: Tue, 4 Jan 2005 02:38:13 +0200

 On 2005-01-03 13:50, "Ronald F.Guilmette" <rfg at monkeys.com> wrote:
 > In certain contexts, and when using certain programming styles, it is
 > important to be able to symmetrically "undo" the effects of various
 > calls to various standard library (libc) routines.
 >
 > At present, due to the lack of an "fdclose" primitive in libc, it is
 > not easily possible to symmetrically undo the effects of a call to the
 > "fdopen" function.  One may call fclose on an open stdio file pointer,
 > however the fclose function actually has two effects, i.e.:
 >
 > 1) recycling the stdio file descriptor that was allocated by the prior
 >    call to fdopen() into the pool of available stdio file descriptors
 >    and...
 >
 > 2) calling close(2) on the underlying UNIX file descriptor.
 >
 > Unfortunately, only the first of these two effects actually
 > constitutes a symmetric undo-ing of the actions performed by a call to
 > fdopen.  The second effect is an unfortunate (and undesirable)
 > side-effect of fclose in some instances.
 >
 > Thus, it would be useful to have a new function in libc, i.e. an
 > "fdclose" function whose only effect would be to recycle a stdio file
 > descriptor into the pool of free/available stdio file descriptors
 > *without* also closing the underlying UNIX file descriptor.
 
 I believe there is no easy way to fdclose() a FILE object _and_ do it in
 a way that would satisfy all the potential uses of such a function.
 Some of the problems that an implementation would have to face are
 immediate results of the buffered nature of FILE streams:
 
   a) Should any pending writes be flushed out before the FILE object is
      destroyed?
 
   b) What should the implementation do with any data that has been
      "read-ahead" and cannot be pushed back to an input stream?
 
 I don't think there is a Right Thing(TM) for all the possible cases.
 Especially if the FILE object is attached to a device node, which may or
 may not support data read-ahead, pushing back of input data, rewinding
 on every open(), etc.
 
 > Add a new "fdclose" function to libc.  This should have the same
 > effects as fclose, except that it should *not* close the underlying
 > UNIX file descriptor.
 
 You can probably emulate most of the behavior of fdclose() when such a
 need arises with something like this:
 
 % #include <errno.h>
 % #include <stdio.h>
 % #include <unistd.h>
 %
 % int
 % fdclose(FILE *fp)
 % {
 %         int fd, nfd;
 %         int status;
 %
 %         if (fp == NULL || (fd = fileno(fp)) < 0)
 %                 goto out;
 %         if ((nfd = dup(fd)) < 0 || (status = fclose(fp)) != 0 ||
 %             dup2(nfd, fd) < 0 || close(nfd) < 0)
 %                 goto syserr;
 %         return (0);
 %
 % out:
 %         errno = EINVAL;
 % syserr:
 %         return (-1);
 % }


More information about the freebsd-bugs mailing list