summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorngie <ngie@FreeBSD.org>2015-01-20 21:59:48 +0000
committerngie <ngie@FreeBSD.org>2015-01-20 21:59:48 +0000
commita170f61a5a8db7610283797dbe8a3526038072e6 (patch)
tree3740f226c50ca7f3334ca876a6a6f82cb676ab63 /lib
parent63ef816492d021cead6a6f0bc9b9943ae24262d7 (diff)
downloadFreeBSD-src-a170f61a5a8db7610283797dbe8a3526038072e6.zip
FreeBSD-src-a170f61a5a8db7610283797dbe8a3526038072e6.tar.gz
MFC r267004,r274592:
r267004 (by gahr): - Use strlen instead of hardcoding a number - Terminate a sentence with a period Approved by: cognet r274592 (by ngie): Convert tools/regression/lib/libc/stdio/test-fmemopen into an ATF testcase and rename as lib/libc/stdio/fmemopen2_test Sponsored by: EMC / Isilon Storage Division
Diffstat (limited to 'lib')
-rw-r--r--lib/libc/tests/stdio/Makefile2
-rw-r--r--lib/libc/tests/stdio/fmemopen2_test.c300
2 files changed, 302 insertions, 0 deletions
diff --git a/lib/libc/tests/stdio/Makefile b/lib/libc/tests/stdio/Makefile
index 3512dd9..23d5c1e 100644
--- a/lib/libc/tests/stdio/Makefile
+++ b/lib/libc/tests/stdio/Makefile
@@ -2,6 +2,8 @@
TESTSDIR= ${TESTSBASE}/lib/libc/stdio
+ATF_TESTS_C= fmemopen2_test
+
NETBSD_ATF_TESTS_C= clearerr_test
NETBSD_ATF_TESTS_C+= fflush_test
NETBSD_ATF_TESTS_C+= fmemopen_test
diff --git a/lib/libc/tests/stdio/fmemopen2_test.c b/lib/libc/tests/stdio/fmemopen2_test.c
new file mode 100644
index 0000000..d137780
--- /dev/null
+++ b/lib/libc/tests/stdio/fmemopen2_test.c
@@ -0,0 +1,300 @@
+/*-
+Copyright (C) 2013 Pietro Cerutti <gahr@FreeBSD.org>
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+*/
+
+/*
+ * Test basic FILE * functions (fread, fwrite, fseek, fclose) against
+ * a FILE * retrieved using fmemopen()
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <strings.h>
+#include <atf-c.h>
+
+ATF_TC_WITHOUT_HEAD(test_preexisting);
+ATF_TC_BODY(test_preexisting, tc)
+{
+ /*
+ * Use a pre-existing buffer.
+ */
+
+ char buf[512];
+ char buf2[512];
+ char str[] = "Test writing some stuff";
+ char str2[] = "AAAAAAAAA";
+ char str3[] = "AAAA writing some stuff";
+ FILE *fp;
+ size_t nofw, nofr;
+ int rc;
+
+ /* Open a FILE * using fmemopen. */
+ fp = fmemopen(buf, sizeof(buf), "w");
+ ATF_REQUIRE(fp != NULL);
+
+ /* Write to the buffer. */
+ nofw = fwrite(str, 1, sizeof(str), fp);
+ ATF_REQUIRE(nofw == sizeof(str));
+
+ /* Close the FILE *. */
+ rc = fclose(fp);
+ ATF_REQUIRE(rc == 0);
+
+ /* Re-open the FILE * to read back the data. */
+ fp = fmemopen(buf, sizeof(buf), "r");
+ ATF_REQUIRE(fp != NULL);
+
+ /* Read from the buffer. */
+ bzero(buf2, sizeof(buf2));
+ nofr = fread(buf2, 1, sizeof(buf2), fp);
+ ATF_REQUIRE(nofr == sizeof(buf2));
+
+ /*
+ * Since a write on a FILE * retrieved by fmemopen
+ * will add a '\0' (if there's space), we can check
+ * the strings for equality.
+ */
+ ATF_REQUIRE(strcmp(str, buf2) == 0);
+
+ /* Close the FILE *. */
+ rc = fclose(fp);
+ ATF_REQUIRE(rc == 0);
+
+ /* Now open a FILE * on the first 4 bytes of the string. */
+ fp = fmemopen(str, 4, "w");
+ ATF_REQUIRE(fp != NULL);
+
+ /*
+ * Try to write more bytes than we shoud, we'll get a short count (4).
+ */
+ nofw = fwrite(str2, 1, sizeof(str2), fp);
+ ATF_REQUIRE(nofw == 4);
+
+ /* Close the FILE *. */
+ rc = fclose(fp);
+
+ /* Check that the string was not modified after the first 4 bytes. */
+ ATF_REQUIRE(strcmp(str, str3) == 0);
+}
+
+ATF_TC_WITHOUT_HEAD(test_autoalloc);
+ATF_TC_BODY(test_autoalloc, tc)
+{
+ /*
+ * Let fmemopen allocate the buffer.
+ */
+
+ char str[] = "A quick test";
+ FILE *fp;
+ long pos;
+ size_t nofw, nofr, i;
+ int rc;
+
+ /* Open a FILE * using fmemopen. */
+ fp = fmemopen(NULL, 512, "w+");
+ ATF_REQUIRE(fp != NULL);
+
+ /* fill the buffer */
+ for (i = 0; i < 512; i++) {
+ nofw = fwrite("a", 1, 1, fp);
+ ATF_REQUIRE(nofw == 1);
+ }
+
+ /* Get the current position into the stream. */
+ pos = ftell(fp);
+ ATF_REQUIRE(pos == 512);
+
+ /*
+ * Try to write past the end, we should get a short object count (0)
+ */
+ nofw = fwrite("a", 1, 1, fp);
+ ATF_REQUIRE(nofw == 0);
+
+ /* Close the FILE *. */
+ rc = fclose(fp);
+ ATF_REQUIRE(rc == 0);
+
+ /* Open a FILE * using a wrong mode */
+ fp = fmemopen(NULL, 512, "r");
+ ATF_REQUIRE(fp == NULL);
+
+ fp = fmemopen(NULL, 512, "w");
+ ATF_REQUIRE(fp == NULL);
+}
+
+ATF_TC_WITHOUT_HEAD(test_data_length);
+ATF_TC_BODY(test_data_length, tc)
+{
+ /*
+ * Here we test that a read operation doesn't go past the end of the
+ * data actually written, and that a SEEK_END seeks from the end of the
+ * data, not of the whole buffer.
+ */
+ FILE *fp;
+ char buf[512] = {'\0'};
+ char str[] = "Test data length. ";
+ char str2[] = "Do we have two sentences?";
+ char str3[sizeof(str) + sizeof(str2) -1];
+ long pos;
+ size_t nofw, nofr;
+ int rc;
+
+ /* Open a FILE * for updating our buffer. */
+ fp = fmemopen(buf, sizeof(buf), "w+");
+ ATF_REQUIRE(fp != NULL);
+
+ /* Write our string into the buffer. */
+ nofw = fwrite(str, 1, sizeof(str), fp);
+ ATF_REQUIRE(nofw == sizeof(str));
+
+ /*
+ * Now seek to the end and check that ftell
+ * gives us sizeof(str).
+ */
+ rc = fseek(fp, 0, SEEK_END);
+ ATF_REQUIRE(rc == 0);
+ pos = ftell(fp);
+ ATF_REQUIRE(pos == sizeof(str));
+
+ /* Close the FILE *. */
+ rc = fclose(fp);
+ ATF_REQUIRE(rc == 0);
+
+ /* Reopen the buffer for appending. */
+ fp = fmemopen(buf, sizeof(buf), "a+");
+ ATF_REQUIRE(fp != NULL);
+
+ /* We should now be writing after the first string. */
+ nofw = fwrite(str2, 1, sizeof(str2), fp);
+ ATF_REQUIRE(nofw == sizeof(str2));
+
+ /* Rewind the FILE *. */
+ rc = fseek(fp, 0, SEEK_SET);
+ ATF_REQUIRE(rc == 0);
+
+ /* Make sure we're at the beginning. */
+ pos = ftell(fp);
+ ATF_REQUIRE(pos == 0);
+
+ /* Read the whole buffer. */
+ nofr = fread(str3, 1, sizeof(buf), fp);
+ ATF_REQUIRE(nofr == sizeof(str3));
+
+ /* Make sure the two strings are there. */
+ ATF_REQUIRE(strncmp(str3, str, sizeof(str) - 1) == 0);
+ ATF_REQUIRE(strncmp(str3 + sizeof(str) - 1, str2, sizeof(str2)) == 0);
+
+ /* Close the FILE *. */
+ rc = fclose(fp);
+ ATF_REQUIRE(rc == 0);
+}
+
+ATF_TC_WITHOUT_HEAD(test_binary);
+ATF_TC_BODY(test_binary, tc)
+{
+ /*
+ * Make sure that NULL bytes are never appended when opening a buffer
+ * in binary mode.
+ */
+
+ FILE *fp;
+ char buf[20];
+ char str[] = "Test";
+ size_t nofw;
+ int rc, i;
+
+ /* Pre-fill the buffer. */
+ memset(buf, 'A', sizeof(buf));
+
+ /* Open a FILE * in binary mode. */
+ fp = fmemopen(buf, sizeof(buf), "w+b");
+ ATF_REQUIRE(fp != NULL);
+
+ /* Write some data into it. */
+ nofw = fwrite(str, 1, strlen(str), fp);
+ ATF_REQUIRE(nofw == strlen(str));
+
+ /* Make sure that the buffer doesn't contain any NULL bytes. */
+ for (i = 0; i < sizeof(buf); i++)
+ ATF_REQUIRE(buf[i] != '\0');
+
+ /* Close the FILE *. */
+ rc = fclose(fp);
+ ATF_REQUIRE(rc == 0);
+}
+
+ATF_TC_WITHOUT_HEAD(test_append_binary_pos);
+ATF_TC_BODY(test_append_binary_pos, tc)
+{
+ /*
+ * 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+");
+ ATF_REQUIRE(ftell(fp) == 0L);
+ fclose(fp);
+
+ /*
+ * Make sure that a pre-allocated buffer behaves correctly.
+ */
+ char buf[] = "Hello";
+ fp = fmemopen(buf, sizeof(buf), "ab+");
+ ATF_REQUIRE(ftell(fp) == strlen(buf));
+ fclose(fp);
+}
+
+ATF_TC_WITHOUT_HEAD(test_size_0);
+ATF_TC_BODY(test_size_0, tc)
+{
+ /*
+ * POSIX mandates that we return EINVAL if size is 0.
+ */
+
+ FILE *fp;
+
+ fp = fmemopen(NULL, 0, "r+");
+ ATF_REQUIRE(fp == NULL);
+ ATF_REQUIRE(errno == EINVAL);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, test_autoalloc);
+ ATF_TP_ADD_TC(tp, test_preexisting);
+ ATF_TP_ADD_TC(tp, test_data_length);
+ ATF_TP_ADD_TC(tp, test_binary);
+ ATF_TP_ADD_TC(tp, test_append_binary_pos);
+ ATF_TP_ADD_TC(tp, test_size_0);
+
+ return (atf_no_error());
+}
OpenPOWER on IntegriCloud