svn commit: r266971 - in head: lib/libc/stdio tools/regression/lib/libc/stdio
Pietro Cerutti
gahr at FreeBSD.org
Mon Jun 2 13:48:58 UTC 2014
Author: gahr (ports committer)
Date: Mon Jun 2 13:48:57 2014
New Revision: 266971
URL: http://svnweb.freebsd.org/changeset/base/266971
Log:
- Return NULL and set errno to EINVAL if size is 0 (as required by POSIX).
Update the manpage to reflect this change.
- Always set the current position to the first null-byte when opening in append
mode. This makes the implementation compatible with glibc's. Update the test
suite.
Reported by: pho
Approved by: cognet
Modified:
head/lib/libc/stdio/fmemopen.c
head/lib/libc/stdio/fopen.3
head/tools/regression/lib/libc/stdio/test-fmemopen.c
Modified: head/lib/libc/stdio/fmemopen.c
==============================================================================
--- head/lib/libc/stdio/fmemopen.c Mon Jun 2 10:14:03 2014 (r266970)
+++ head/lib/libc/stdio/fmemopen.c Mon Jun 2 13:48:57 2014 (r266971)
@@ -57,6 +57,14 @@ fmemopen(void * __restrict buf, size_t s
int flags, rc;
/*
+ * POSIX says we shall return EINVAL if size is 0.
+ */
+ if (size == 0) {
+ errno = EINVAL;
+ return (NULL);
+ }
+
+ /*
* Retrieve the flags as used by open(2) from the mode argument, and
* validate them.
*/
@@ -119,14 +127,7 @@ fmemopen(void * __restrict buf, size_t s
*/
switch (mode[0]) {
case 'a':
- if (ck->bin) {
- /*
- * This isn't useful, since the buffer isn't allowed
- * to grow.
- */
- ck->off = ck->len = size;
- } else
- ck->off = ck->len = strnlen(ck->buf, ck->size);
+ ck->off = ck->len = strnlen(ck->buf, ck->size);
break;
case 'r':
ck->len = size;
Modified: head/lib/libc/stdio/fopen.3
==============================================================================
--- head/lib/libc/stdio/fopen.3 Mon Jun 2 10:14:03 2014 (r266970)
+++ head/lib/libc/stdio/fopen.3 Mon Jun 2 13:48:57 2014 (r266971)
@@ -302,6 +302,15 @@ for any of the errors specified for the
.Xr fclose 3
and
.Xr fflush 3 .
+.Pp
+The
+.Fn fmemopen
+function
+may also fail and set
+.Va errno
+if the
+.Fa size
+argument is 0.
.Sh SEE ALSO
.Xr open 2 ,
.Xr fclose 3 ,
Modified: head/tools/regression/lib/libc/stdio/test-fmemopen.c
==============================================================================
--- head/tools/regression/lib/libc/stdio/test-fmemopen.c Mon Jun 2 10:14:03 2014 (r266970)
+++ head/tools/regression/lib/libc/stdio/test-fmemopen.c Mon Jun 2 13:48:57 2014 (r266971)
@@ -138,6 +138,13 @@ test_autoalloc()
/* Close the FILE *. */
rc = fclose(fp);
assert(rc == 0);
+
+ /* Open a FILE * using a wrong mode */
+ fp = fmemopen(NULL, 512, "r");
+ assert(fp == NULL);
+
+ fp = fmemopen(NULL, 512, "w");
+ assert(fp == NULL);
}
void
@@ -241,6 +248,44 @@ test_binary()
assert(rc == 0);
}
+void
+test_append_binary_pos()
+{
+ /*
+ * For compatibility with other implementations (glibc), we set the
+ * position to 0 when opening an automatically allocated binary stream
+ * for appending.
+ */
+
+ FILE *fp;
+
+ fp = fmemopen(NULL, 16, "ab+");
+ assert(ftell(fp) == 0L);
+ fclose(fp);
+
+ /*
+ * Make sure that a pre-allocated buffer behaves correctly.
+ */
+ char buf[] = "Hello";
+ fp = fmemopen(buf, sizeof(buf), "ab+");
+ assert(ftell(fp) == 5);
+ fclose(fp);
+}
+
+void
+test_size_0()
+{
+ /*
+ * POSIX mandates that we return EINVAL if size is 0
+ */
+
+ FILE *fp;
+
+ fp = fmemopen(NULL, 0, "r+");
+ assert(fp == NULL);
+ assert(errno == EINVAL);
+}
+
int
main(void)
{
@@ -248,5 +293,7 @@ main(void)
test_preexisting();
test_data_length();
test_binary();
+ test_append_binary_pos();
+ test_size_0();
return (0);
}
More information about the svn-src-all
mailing list