--- //depot/user/oshogbo/capsicum/include/stdio.h 2013-06-28 08:51:28.000000000 0000 +++ /home/oshogbo/p4/capsicum/include/stdio.h 2013-06-28 08:51:28.000000000 0000 @@ -396,6 +396,7 @@ int asprintf(char **, const char *, ...) __printflike(2, 3); char *ctermid_r(char *); void fcloseall(void); +int fdclose(FILE *); char *fgetln(FILE *, size_t *); const char *fmtcheck(const char *, const char *) __format_arg(2); int fpurge(FILE *); --- //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; }; --- //depot/user/oshogbo/capsicum/lib/libc/stdio/fclose.3 2013-06-28 08:51:28.000000000 0000 +++ /home/oshogbo/p4/capsicum/lib/libc/stdio/fclose.3 2013-06-28 08:51:28.000000000 0000 @@ -1,5 +1,6 @@ -.\" Copyright (c) 1990, 1991, 1993 -.\" The Regents of the University of California. All rights reserved. +.\" Copyright (c) 1990, 1991, 1993 The Regents of the University of California. +.\" Copyright (c) 2014 Mariusz Zaborski +.\" All rights reserved. .\" .\" This code is derived from software contributed to Berkeley by .\" Chris Torek and the American National Standards Committee X3, @@ -32,11 +33,12 @@ .\" @(#)fclose.3 8.1 (Berkeley) 6/4/93 .\" $FreeBSD: head/lib/libc/stdio/fclose.3 165903 2007-01-09 00:28:16Z imp $ .\" -.Dd April 22, 2006 +.Dd March 17, 2014 .Dt FCLOSE 3 .Os .Sh NAME .Nm fclose , +.Nm fdclose , .Nm fcloseall .Nd close a stream .Sh LIBRARY @@ -45,6 +47,8 @@ .In stdio.h .Ft int .Fn fclose "FILE *stream" +.Ft int +.Fn fdclose "FILE *stream" .Ft void .Fn fcloseall void .Sh DESCRIPTION @@ -59,22 +63,64 @@ .Xr fflush 3 . .Pp The +.Fn fdclose +function is equivalent to the +.Fn fclose +function except that this function returns file descriptor instead of +closing it. +.Pp +The .Fn fcloseall function calls .Fn fclose on all open streams. .Sh RETURN VALUES -Upon successful completion 0 is returned. +The +.Fn fcloseall +function return no value. +.Pp +Upon successful completion +.Fn fclose +return 0. +Otherwise, +.Dv EOF +is returned and the global variable +.Va errno +is set to indicate the error. +.Pp +The +.Fn fdclose +function return the file descriptor if successfull. Otherwise, .Dv EOF is returned and the global variable .Va errno is set to indicate the error. +.Pp In either case no further access to the stream is possible. .Sh ERRORS +.Bl -tag -width Er +.It Bq Er EOPNOTSUPP The +.Fa _close +method in +.Fa stream +argument to +.Fn fdclose , +was not default. +.It Bq Er EBADF +The +.Fa stream +argument to +.Fn fdclose , +does not contains valid file descriptor. +.El +.Pp +The .Fn fclose -function +and +.Fn fdclose +functions may also fail and set .Va errno for any of the errors specified for the routines @@ -84,7 +130,9 @@ .Sh NOTES The .Fn fclose -function +and +.Fn fdclose +functions does not handle NULL arguments; they will result in a segmentation violation. This is intentional - it makes it easier to make sure programs written @@ -104,8 +152,13 @@ function conforms to .St -isoC . -.Pp +.Sh History The .Fn fcloseall function first appeared in .Fx 7.0 . +.Pp +The +.Fn fdclose +function first appeared in +.Fx 11.0 . --- //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 @@ -1,6 +1,7 @@ /*- - * Copyright (c) 1990, 1993 - * The Regents of the University of California. All rights reserved. + * Copyright (c) 1990, 1993 The Regents of the University of California. + * Copyright (c) 2014 Mariusz Zaborski + * All rights reserved. * * This code is derived from software contributed to Berkeley by * Chris Torek. @@ -38,6 +39,7 @@ #include "namespace.h" #include +#include #include #include #include "un-namespace.h" @@ -45,19 +47,17 @@ #include "libc_private.h" #include "local.h" -int -fclose(FILE *fp) +static int +cleanfile(FILE *fp, bool c) { int r; - if (fp->_flags == 0) { /* not open! */ - errno = EBADF; - return (EOF); + r = fp->_flags & __SWR ? __sflush(fp) : 0; + if (c) { + if (fp->_close != NULL && (*fp->_close)(fp->_cookie) < 0) + r = EOF; } - FLOCKFILE(fp); - r = fp->_flags & __SWR ? __sflush(fp) : 0; - if (fp->_close != NULL && (*fp->_close)(fp->_cookie) < 0) - r = EOF; + if (fp->_flags & __SMBF) free((char *)fp->_bf._base); if (HASUB(fp)) @@ -80,6 +80,55 @@ STDIO_THREAD_LOCK(); fp->_flags = 0; /* Release this FILE for reuse. */ STDIO_THREAD_UNLOCK(); + + return (r); +} + +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); +} + +int +fclose(FILE *fp) +{ + int r; + + if (fp->_flags == 0) { /* not open! */ + errno = EBADF; + return (EOF); + } + + FLOCKFILE(fp); + r = cleanfile(fp, true); + FUNLOCKFILE(fp); + return (r); }