From owner-freebsd-current@FreeBSD.ORG Tue Mar 18 21:35:20 2014 Return-Path: Delivered-To: freebsd-current@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 874D1C85; Tue, 18 Mar 2014 21:35:20 +0000 (UTC) Received: from mx1.stack.nl (relay04.stack.nl [IPv6:2001:610:1108:5010::107]) (using TLSv1 with cipher ADH-CAMELLIA256-SHA (256/256 bits)) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id 4B595167; Tue, 18 Mar 2014 21:35:20 +0000 (UTC) Received: from snail.stack.nl (snail.stack.nl [IPv6:2001:610:1108:5010::131]) by mx1.stack.nl (Postfix) with ESMTP id A602AB80AB; Tue, 18 Mar 2014 22:35:16 +0100 (CET) Received: by snail.stack.nl (Postfix, from userid 1677) id 8730C28497; Tue, 18 Mar 2014 22:35:16 +0100 (CET) Date: Tue, 18 Mar 2014 22:35:16 +0100 From: Jilles Tjoelker To: Mariusz Zaborski Subject: Re: Hello fdclose Message-ID: <20140318213516.GA71491@stack.nl> References: MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.21 (2010-09-15) Cc: freebsd-current@freebsd.org, freebsd-arch@freebsd.org X-BeenThere: freebsd-current@freebsd.org X-Mailman-Version: 2.1.17 Precedence: list List-Id: Discussions about the use of FreeBSD-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 18 Mar 2014 21:35:20 -0000 On Tue, Mar 18, 2014 at 12:23:19AM +0100, Mariusz Zaborski wrote: > After our previous discuss [1] I prepare fdclosedir(3) function which > was committed by Pawel (cc'ed) in commit r254499. > A while ago I also prepare the fdclose function. Unfortunately, this > new function is a little bit more tricky then previous one. Can I ask > you for a review of this patch? Does this patch allow perl to stop writing to FILE._file? As pointed out in http://lists.freebsd.org/pipermail/freebsd-current/2013-January/039024.html perlio.c in the perl source contains a function PerlIOStdio_invalidate_fileno() that should modify a FILE such that fclose() does not close the file descriptor but still frees all memory (Perl has already called fflush()). Although using fdclose() could solve this without touching the internals of FILE, this will make perlio.c uglier with even more #ifdefs. > [snip] > --- //depot/user/oshogbo/capsicum/lib/libc/stdio/Symbol.map 2013-06-28 08:51:28.000000000 0000 > +++ /home/oshogbo/p4/capsicum/lib/libc/stdio/Symbol.map 2013-06-28 08:51:28.000000000 0000 > @@ -156,6 +156,7 @@ > putwc_l; > putwchar_l; > fmemopen; > + fdclose; > open_memstream; > open_wmemstream; > }; This should be in the FBSD_1.4 namespace (which does not exist yet). > [snip] > --- //depot/user/oshogbo/capsicum/lib/libc/stdio/fclose.c 2013-06-28 08:51:28.000000000 0000 > +++ /home/oshogbo/p4/capsicum/lib/libc/stdio/fclose.c 2013-06-28 08:51:28.000000000 0000 > [snip] > +int > +fdclose(FILE *fp) > +{ > + int fd, r, err; > + > + if (fp->_flags == 0) { /* not open! */ > + errno = EBADF; > + return (EOF); > + } > + > + r = 0; > + FLOCKFILE(fp); > + fd = fp->_file; > + if (fp->_close != __sclose) { > + r = EOF; > + errno = EOPNOTSUPP; > + } else if (fd < 0) { > + r = EOF; > + errno = EBADF; > + } > + if (r == EOF) { > + err = errno; > + (void)cleanfile(fp, true); > + errno = err; > + } else { > + r = cleanfile(fp, false); > + } > FUNLOCKFILE(fp); > + > + return (r == 0 ? fd : r); If a file descriptor would be returned but cleanfile() returns an error (e.g. write error on flush), the file descriptor is not returned and not closed. I think that in cases where fdclose() would be used, it is essential that the file descriptor is never closed. This means that the API needs to be different so it can report a write error but still return a file descriptor. One way to do this is to return the file descriptor by reference. Another is to expect the application to call fileno() and not return the descriptor from the new function. -- Jilles Tjoelker