Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 11 Jan 2015 19:15:29 +0000 (UTC)
From:      Garrett Cooper <ngie@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org
Subject:   svn commit: r277016 - in stable/10: lib/libc/stdio tools/regression/lib/libc/stdio
Message-ID:  <201501111915.t0BJFTnN094156@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: ngie
Date: Sun Jan 11 19:15:28 2015
New Revision: 277016
URL: https://svnweb.freebsd.org/changeset/base/277016

Log:
  MFC discussed with: jilles, -developers
  
  MFC r266971:
  
    - 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:
  stable/10/lib/libc/stdio/fmemopen.c
  stable/10/lib/libc/stdio/fopen.3
  stable/10/tools/regression/lib/libc/stdio/test-fmemopen.c
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/lib/libc/stdio/fmemopen.c
==============================================================================
--- stable/10/lib/libc/stdio/fmemopen.c	Sun Jan 11 19:01:28 2015	(r277015)
+++ stable/10/lib/libc/stdio/fmemopen.c	Sun Jan 11 19:15:28 2015	(r277016)
@@ -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: stable/10/lib/libc/stdio/fopen.3
==============================================================================
--- stable/10/lib/libc/stdio/fopen.3	Sun Jan 11 19:01:28 2015	(r277015)
+++ stable/10/lib/libc/stdio/fopen.3	Sun Jan 11 19:15:28 2015	(r277016)
@@ -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: stable/10/tools/regression/lib/libc/stdio/test-fmemopen.c
==============================================================================
--- stable/10/tools/regression/lib/libc/stdio/test-fmemopen.c	Sun Jan 11 19:01:28 2015	(r277015)
+++ stable/10/tools/regression/lib/libc/stdio/test-fmemopen.c	Sun Jan 11 19:15:28 2015	(r277016)
@@ -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);
 }



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201501111915.t0BJFTnN094156>