Hi,

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?

Thanks,
Mariusz

[1] http://lists.freebsd.org/pipermail/freebsd-arch/2013-August/014688.html
--- //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 <osho...@freebsd.org>
+.\" 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 <osho...@freebsd.org>
+ * All rights reserved.
  *
  * This code is derived from software contributed to Berkeley by
  * Chris Torek.
@@ -38,6 +39,7 @@
 
 #include "namespace.h"
 #include <errno.h>
+#include <stdbool.h>
 #include <stdio.h>
 #include <stdlib.h>
 #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);
 }
_______________________________________________
freebsd-current@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-unsubscr...@freebsd.org"

Reply via email to