From owner-svn-src-all@FreeBSD.ORG Mon Jun 2 13:48:58 2014 Return-Path: Delivered-To: svn-src-all@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 236B47B0; Mon, 2 Jun 2014 13:48:58 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 0FB2426CA; Mon, 2 Jun 2014 13:48:58 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.8/8.14.8) with ESMTP id s52DmvvE028593; Mon, 2 Jun 2014 13:48:57 GMT (envelope-from gahr@svn.freebsd.org) Received: (from gahr@localhost) by svn.freebsd.org (8.14.8/8.14.8/Submit) id s52DmvME028590; Mon, 2 Jun 2014 13:48:57 GMT (envelope-from gahr@svn.freebsd.org) Message-Id: <201406021348.s52DmvME028590@svn.freebsd.org> From: Pietro Cerutti Date: Mon, 2 Jun 2014 13:48:57 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r266971 - in head: lib/libc/stdio tools/regression/lib/libc/stdio X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 02 Jun 2014 13:48:58 -0000 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); }