1*bdb5d51cSrillig /* $NetBSD: t_fmemopen.c,v 1.7 2021/09/11 18:18:28 rillig Exp $ */
293b7363cStnozaki
393b7363cStnozaki /*-
493b7363cStnozaki * Copyright (c)2010 Takehiko NOZAKI,
593b7363cStnozaki * All rights reserved.
693b7363cStnozaki *
793b7363cStnozaki * Redistribution and use in source and binary forms, with or without
893b7363cStnozaki * modification, are permitted provided that the following conditions
993b7363cStnozaki * are met:
1093b7363cStnozaki * 1. Redistributions of source code must retain the above copyright
1193b7363cStnozaki * notice, this list of conditions and the following disclaimer.
1293b7363cStnozaki * 2. Redistributions in binary form must reproduce the above copyright
1393b7363cStnozaki * notice, this list of conditions and the following disclaimer in the
1493b7363cStnozaki * documentation and/or other materials provided with the distribution.
1593b7363cStnozaki *
1693b7363cStnozaki * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1793b7363cStnozaki * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1893b7363cStnozaki * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1993b7363cStnozaki * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
2093b7363cStnozaki * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2193b7363cStnozaki * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2293b7363cStnozaki * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2393b7363cStnozaki * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2493b7363cStnozaki * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2593b7363cStnozaki * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2693b7363cStnozaki * SUCH DAMAGE.
2793b7363cStnozaki *
2893b7363cStnozaki */
2993b7363cStnozaki
3093b7363cStnozaki #if defined(__NetBSD__)
3193b7363cStnozaki #include <atf-c.h>
3293b7363cStnozaki #else
3393b7363cStnozaki #if defined(__linux__)
3493b7363cStnozaki #define _GNU_SOURCE
3593b7363cStnozaki #include <features.h>
3693b7363cStnozaki #endif
3793b7363cStnozaki #include <assert.h>
3893b7363cStnozaki #include <stdio.h>
3993b7363cStnozaki #define ATF_TC(arg0) static void arg0##_head(void)
4093b7363cStnozaki #define ATF_TC_HEAD(arg0, arg1) static void arg0##_head()
4193b7363cStnozaki #define atf_tc_set_md_var(arg0, arg1, ...) do { \
4293b7363cStnozaki printf(__VA_ARGS__); \
4393b7363cStnozaki puts(""); \
4493b7363cStnozaki } while (/*CONSTCOND*/0)
4593b7363cStnozaki #define ATF_TC_BODY(arg0, arg1) static void arg0##_body()
4693b7363cStnozaki #define ATF_CHECK(arg0) assert(arg0)
4793b7363cStnozaki #define ATF_TP_ADD_TCS(arg0) int main(void)
4893b7363cStnozaki #define ATF_TP_ADD_TC(arg0, arg1) arg1##_head(); arg1##_body()
4993b7363cStnozaki #define atf_no_error() 0
5093b7363cStnozaki #endif
5193b7363cStnozaki
5293b7363cStnozaki #include <errno.h>
53ef311a87Sdholland #include <stdint.h>
5493b7363cStnozaki #include <stdio.h>
5593b7363cStnozaki #include <limits.h>
5693b7363cStnozaki #include <stdlib.h>
5793b7363cStnozaki #include <string.h>
5893b7363cStnozaki
5993b7363cStnozaki const char *mode_rwa[] = {
6093b7363cStnozaki "r", "rb", "r+", "rb+", "r+b",
6193b7363cStnozaki "w", "wb", "w+", "wb+", "w+b",
6293b7363cStnozaki "a", "ab", "a+", "ab+", "a+b",
6393b7363cStnozaki NULL
6493b7363cStnozaki };
6593b7363cStnozaki
6693b7363cStnozaki const char *mode_r[] = { "r", "rb", "r+", "rb+", "r+b", NULL };
6793b7363cStnozaki const char *mode_w[] = { "w", "wb", "w+", "wb+", "w+b", NULL };
6893b7363cStnozaki const char *mode_a[] = { "a", "ab", "a+", "ab+", "a+b", NULL };
6993b7363cStnozaki
7093b7363cStnozaki struct testcase {
7193b7363cStnozaki const char *s;
720f10aa9dSchristos off_t n;
7393b7363cStnozaki } testcases[] = {
7493b7363cStnozaki #define TESTSTR(s) { s, sizeof(s)-1 }
7593b7363cStnozaki TESTSTR("\0he quick brown fox jumps over the lazy dog"),
7693b7363cStnozaki TESTSTR("T\0e quick brown fox jumps over the lazy dog"),
7793b7363cStnozaki TESTSTR("Th\0 quick brown fox jumps over the lazy dog"),
7893b7363cStnozaki TESTSTR("The\0quick brown fox jumps over the lazy dog"),
7993b7363cStnozaki TESTSTR("The \0uick brown fox jumps over the lazy dog"),
8093b7363cStnozaki TESTSTR("The q\0ick brown fox jumps over the lazy dog"),
8193b7363cStnozaki TESTSTR("The qu\0ck brown fox jumps over the lazy dog"),
8293b7363cStnozaki TESTSTR("The qui\0k brown fox jumps over the lazy dog"),
8393b7363cStnozaki TESTSTR("The quic\0 brown fox jumps over the lazy dog"),
8493b7363cStnozaki TESTSTR("The quick\0brown fox jumps over the lazy dog"),
8593b7363cStnozaki TESTSTR("The quick \0rown fox jumps over the lazy dog"),
8693b7363cStnozaki TESTSTR("The quick b\0own fox jumps over the lazy dog"),
8793b7363cStnozaki TESTSTR("The quick br\0wn fox jumps over the lazy dog"),
8893b7363cStnozaki TESTSTR("The quick bro\0n fox jumps over the lazy dog"),
8993b7363cStnozaki TESTSTR("The quick brow\0 fox jumps over the lazy dog"),
9093b7363cStnozaki TESTSTR("The quick brown\0fox jumps over the lazy dog"),
9193b7363cStnozaki TESTSTR("The quick brown \0ox jumps over the lazy dog"),
9293b7363cStnozaki TESTSTR("The quick brown f\0x jumps over the lazy dog"),
9393b7363cStnozaki TESTSTR("The quick brown fo\0 jumps over the lazy dog"),
9493b7363cStnozaki TESTSTR("The quick brown fox\0jumps over the lazy dog"),
9593b7363cStnozaki TESTSTR("The quick brown fox \0umps over the lazy dog"),
9693b7363cStnozaki TESTSTR("The quick brown fox j\0mps over the lazy dog"),
9793b7363cStnozaki TESTSTR("The quick brown fox ju\0ps over the lazy dog"),
9893b7363cStnozaki TESTSTR("The quick brown fox jum\0s over the lazy dog"),
9993b7363cStnozaki TESTSTR("The quick brown fox jump\0 over the lazy dog"),
10093b7363cStnozaki TESTSTR("The quick brown fox jumps\0over the lazy dog"),
10193b7363cStnozaki TESTSTR("The quick brown fox jumps \0ver the lazy dog"),
10293b7363cStnozaki TESTSTR("The quick brown fox jumps o\0er the lazy dog"),
10393b7363cStnozaki TESTSTR("The quick brown fox jumps ov\0r the lazy dog"),
10493b7363cStnozaki TESTSTR("The quick brown fox jumps ove\0 the lazy dog"),
10593b7363cStnozaki TESTSTR("The quick brown fox jumps over\0the lazy dog"),
10693b7363cStnozaki TESTSTR("The quick brown fox jumps over \0he lazy dog"),
10793b7363cStnozaki TESTSTR("The quick brown fox jumps over t\0e lazy dog"),
10893b7363cStnozaki TESTSTR("The quick brown fox jumps over th\0 lazy dog"),
10993b7363cStnozaki TESTSTR("The quick brown fox jumps over the\0lazy dog"),
11093b7363cStnozaki TESTSTR("The quick brown fox jumps over the \0azy dog"),
11193b7363cStnozaki TESTSTR("The quick brown fox jumps over the l\0zy dog"),
11293b7363cStnozaki TESTSTR("The quick brown fox jumps over the la\0y dog"),
11393b7363cStnozaki TESTSTR("The quick brown fox jumps over the laz\0 dog"),
11493b7363cStnozaki TESTSTR("The quick brown fox jumps over the lazy\0dog"),
11593b7363cStnozaki TESTSTR("The quick brown fox jumps over the lazy \0og"),
11693b7363cStnozaki TESTSTR("The quick brown fox jumps over the lazy d\0g"),
11793b7363cStnozaki TESTSTR("The quick brown fox jumps over the lazy do\0"),
11893b7363cStnozaki TESTSTR("The quick brown fox jumps over the lazy dog"),
11993b7363cStnozaki { NULL, 0 },
12093b7363cStnozaki };
12193b7363cStnozaki
12293b7363cStnozaki ATF_TC(test00);
ATF_TC_HEAD(test00,tc)12393b7363cStnozaki ATF_TC_HEAD(test00, tc)
12493b7363cStnozaki {
12593b7363cStnozaki atf_tc_set_md_var(tc, "descr", "test00");
12693b7363cStnozaki }
ATF_TC_BODY(test00,tc)12793b7363cStnozaki ATF_TC_BODY(test00, tc)
12893b7363cStnozaki {
12993b7363cStnozaki const char **p;
13093b7363cStnozaki char buf[BUFSIZ];
13193b7363cStnozaki FILE *fp;
13293b7363cStnozaki
13393b7363cStnozaki for (p = &mode_rwa[0]; *p != NULL; ++p) {
13493b7363cStnozaki fp = fmemopen(&buf[0], sizeof(buf), *p);
13593b7363cStnozaki /*
13693b7363cStnozaki * Upon successful completion, fmemopen() shall return a pointer to the
13793b7363cStnozaki * object controlling the stream.
13893b7363cStnozaki */
13993b7363cStnozaki ATF_CHECK(fp != NULL);
14093b7363cStnozaki
14193b7363cStnozaki ATF_CHECK(fclose(fp) == 0);
14293b7363cStnozaki }
14393b7363cStnozaki }
14493b7363cStnozaki
14593b7363cStnozaki ATF_TC(test01);
ATF_TC_HEAD(test01,tc)14693b7363cStnozaki ATF_TC_HEAD(test01, tc)
14793b7363cStnozaki {
14893b7363cStnozaki atf_tc_set_md_var(tc, "descr", "test01");
14993b7363cStnozaki }
ATF_TC_BODY(test01,tc)15093b7363cStnozaki ATF_TC_BODY(test01, tc)
15193b7363cStnozaki {
15293b7363cStnozaki const char **p;
15393b7363cStnozaki const char *mode[] = {
15493b7363cStnozaki "r+", "rb+", "r+b",
15593b7363cStnozaki "w+", "wb+", "w+b",
15693b7363cStnozaki "a+", "ab+", "a+b",
15793b7363cStnozaki NULL
15893b7363cStnozaki };
15993b7363cStnozaki FILE *fp;
16093b7363cStnozaki
16193b7363cStnozaki for (p = &mode[0]; *p != NULL; ++p) {
16293b7363cStnozaki /*
16393b7363cStnozaki * If a null pointer is specified as the buf argument, fmemopen() shall
16493b7363cStnozaki * allocate size bytes of memory as if by a call to malloc().
16593b7363cStnozaki */
16693b7363cStnozaki fp = fmemopen(NULL, BUFSIZ, *p);
16793b7363cStnozaki ATF_CHECK(fp != NULL);
16893b7363cStnozaki
16993b7363cStnozaki /*
17093b7363cStnozaki * If buf is a null pointer, the initial position shall always be set
17193b7363cStnozaki * to the beginning of the buffer.
17293b7363cStnozaki */
17393b7363cStnozaki ATF_CHECK(ftello(fp) == (off_t)0);
17493b7363cStnozaki
17593b7363cStnozaki ATF_CHECK(fclose(fp) == 0);
17693b7363cStnozaki }
17793b7363cStnozaki }
17893b7363cStnozaki
17993b7363cStnozaki ATF_TC(test02);
ATF_TC_HEAD(test02,tc)18093b7363cStnozaki ATF_TC_HEAD(test02, tc)
18193b7363cStnozaki {
18293b7363cStnozaki atf_tc_set_md_var(tc, "descr", "test02");
18393b7363cStnozaki }
ATF_TC_BODY(test02,tc)18493b7363cStnozaki ATF_TC_BODY(test02, tc)
18593b7363cStnozaki {
18693b7363cStnozaki const char **p;
18793b7363cStnozaki char buf[BUFSIZ];
18893b7363cStnozaki FILE *fp;
18993b7363cStnozaki
19093b7363cStnozaki for (p = &mode_r[0]; *p != NULL; ++p) {
19193b7363cStnozaki
19293b7363cStnozaki memset(&buf[0], 0x1, sizeof(buf));
19393b7363cStnozaki fp = fmemopen(&buf[0], sizeof(buf), *p);
19493b7363cStnozaki ATF_CHECK(fp != NULL);
19593b7363cStnozaki
19693b7363cStnozaki /*
19793b7363cStnozaki * This position is initially set to either the beginning of the buffer
19893b7363cStnozaki * (for r and w modes)
19993b7363cStnozaki */
20093b7363cStnozaki ATF_CHECK((unsigned char)buf[0] == 0x1);
20193b7363cStnozaki ATF_CHECK(ftello(fp) == (off_t)0);
20293b7363cStnozaki
20393b7363cStnozaki /*
20493b7363cStnozaki * The stream also maintains the size of the current buffer contents.
20593b7363cStnozaki * For modes r and r+ the size is set to the value given by the size argument.
20693b7363cStnozaki */
20793b7363cStnozaki #if !defined(__GLIBC__)
20893b7363cStnozaki ATF_CHECK(fseeko(fp, (off_t)0, SEEK_END) == 0);
20993b7363cStnozaki ATF_CHECK(ftello(fp) == (off_t)sizeof(buf));
21093b7363cStnozaki #endif
21193b7363cStnozaki ATF_CHECK(fclose(fp) == 0);
21293b7363cStnozaki }
21393b7363cStnozaki }
21493b7363cStnozaki
21593b7363cStnozaki ATF_TC(test03);
ATF_TC_HEAD(test03,tc)21693b7363cStnozaki ATF_TC_HEAD(test03, tc)
21793b7363cStnozaki {
21893b7363cStnozaki atf_tc_set_md_var(tc, "descr", "test03");
21993b7363cStnozaki }
ATF_TC_BODY(test03,tc)22093b7363cStnozaki ATF_TC_BODY(test03, tc)
22193b7363cStnozaki {
22293b7363cStnozaki const char **p;
22393b7363cStnozaki char buf[BUFSIZ];
22493b7363cStnozaki FILE *fp;
22593b7363cStnozaki
22693b7363cStnozaki for (p = &mode_w[0]; *p != NULL; ++p) {
22793b7363cStnozaki
22893b7363cStnozaki memset(&buf[0], 0x1, sizeof(buf));
22993b7363cStnozaki fp = fmemopen(&buf[0], sizeof(buf), *p);
23093b7363cStnozaki ATF_CHECK(fp != NULL);
23193b7363cStnozaki
23293b7363cStnozaki /*
23393b7363cStnozaki * This position is initially set to either the beginning of the buffer
23493b7363cStnozaki * (for r and w modes)
23593b7363cStnozaki */
23693b7363cStnozaki ATF_CHECK(buf[0] == '\0');
23793b7363cStnozaki ATF_CHECK(ftello(fp) == (off_t)0);
23893b7363cStnozaki
23993b7363cStnozaki /*
24093b7363cStnozaki * For modes w and w+ the initial size is zero
24193b7363cStnozaki */
24293b7363cStnozaki ATF_CHECK(fseeko(fp, (off_t)0, SEEK_END) == 0);
24393b7363cStnozaki ATF_CHECK(ftello(fp) == (off_t)0);
24493b7363cStnozaki
24593b7363cStnozaki ATF_CHECK(fclose(fp) == 0);
24693b7363cStnozaki }
24793b7363cStnozaki }
24893b7363cStnozaki
24993b7363cStnozaki ATF_TC(test04);
ATF_TC_HEAD(test04,tc)25093b7363cStnozaki ATF_TC_HEAD(test04, tc)
25193b7363cStnozaki {
25293b7363cStnozaki atf_tc_set_md_var(tc, "descr", "test04");
25393b7363cStnozaki }
ATF_TC_BODY(test04,tc)25493b7363cStnozaki ATF_TC_BODY(test04, tc)
25593b7363cStnozaki {
25693b7363cStnozaki const char **p;
25793b7363cStnozaki char buf[BUFSIZ];
25893b7363cStnozaki FILE *fp;
25993b7363cStnozaki
26093b7363cStnozaki /*
26193b7363cStnozaki * or to the first null byte in the buffer (for a modes)
26293b7363cStnozaki */
26393b7363cStnozaki for (p = &mode_a[0]; *p != NULL; ++p) {
26493b7363cStnozaki
26593b7363cStnozaki memset(&buf[0], 0x1, sizeof(buf));
26693b7363cStnozaki fp = fmemopen(&buf[0], sizeof(buf), *p);
26793b7363cStnozaki ATF_CHECK(fp != NULL);
26893b7363cStnozaki
26993b7363cStnozaki ATF_CHECK((unsigned char)buf[0] == 0x1);
27093b7363cStnozaki
27193b7363cStnozaki /* If no null byte is found in append mode,
27293b7363cStnozaki * the initial position is set to one byte after the end of the buffer.
27393b7363cStnozaki */
27493b7363cStnozaki #if !defined(__GLIBC__)
27593b7363cStnozaki ATF_CHECK(ftello(fp) == (off_t)sizeof(buf));
27693b7363cStnozaki #endif
27793b7363cStnozaki
27893b7363cStnozaki /*
27993b7363cStnozaki * and for modes a and a+ the initial size is either the position of the
28093b7363cStnozaki * first null byte in the buffer or the value of the size argument
28193b7363cStnozaki * if no null byte is found.
28293b7363cStnozaki */
28393b7363cStnozaki #if !defined(__GLIBC__)
28493b7363cStnozaki ATF_CHECK(fseeko(fp, (off_t)0, SEEK_END) == 0);
28593b7363cStnozaki ATF_CHECK(ftello(fp) == (off_t)sizeof(buf));
28693b7363cStnozaki #endif
28793b7363cStnozaki
28893b7363cStnozaki ATF_CHECK(fclose(fp) == 0);
28993b7363cStnozaki }
29093b7363cStnozaki }
29193b7363cStnozaki
29293b7363cStnozaki ATF_TC(test05);
ATF_TC_HEAD(test05,tc)29393b7363cStnozaki ATF_TC_HEAD(test05, tc)
29493b7363cStnozaki {
29593b7363cStnozaki atf_tc_set_md_var(tc, "descr", "test05");
29693b7363cStnozaki }
ATF_TC_BODY(test05,tc)29793b7363cStnozaki ATF_TC_BODY(test05, tc)
29893b7363cStnozaki {
29993b7363cStnozaki const char **p;
30093b7363cStnozaki FILE *fp;
30193b7363cStnozaki char buf[BUFSIZ];
30293b7363cStnozaki
30393b7363cStnozaki for (p = &mode_rwa[0]; *p != NULL; ++p) {
30493b7363cStnozaki /*
30593b7363cStnozaki * Otherwise, a null pointer shall be returned, and errno shall be set
30693b7363cStnozaki * to indicate the error.
30793b7363cStnozaki */
30893b7363cStnozaki errno = 0;
30993b7363cStnozaki fp = fmemopen(NULL, (size_t)0, *p);
31093b7363cStnozaki ATF_CHECK(fp == NULL);
31193b7363cStnozaki ATF_CHECK(errno == EINVAL);
31293b7363cStnozaki
31393b7363cStnozaki errno = 0;
31493b7363cStnozaki fp = fmemopen((void *)&buf[0], 0, *p);
31593b7363cStnozaki ATF_CHECK(fp == NULL);
31693b7363cStnozaki ATF_CHECK(errno == EINVAL);
31793b7363cStnozaki }
31893b7363cStnozaki }
31993b7363cStnozaki
32093b7363cStnozaki ATF_TC(test06);
ATF_TC_HEAD(test06,tc)32193b7363cStnozaki ATF_TC_HEAD(test06, tc)
32293b7363cStnozaki {
32393b7363cStnozaki atf_tc_set_md_var(tc, "descr", "test06");
32493b7363cStnozaki }
ATF_TC_BODY(test06,tc)32593b7363cStnozaki ATF_TC_BODY(test06, tc)
32693b7363cStnozaki {
32793b7363cStnozaki const char **p;
32893b7363cStnozaki const char *mode[] = { "", " ", "???", NULL };
32993b7363cStnozaki FILE *fp;
33093b7363cStnozaki
33193b7363cStnozaki for (p = &mode[0]; *p != NULL; ++p) {
33293b7363cStnozaki /*
33393b7363cStnozaki * The value of the mode argument is not valid.
33493b7363cStnozaki */
33593b7363cStnozaki fp = fmemopen(NULL, 1, *p);
33693b7363cStnozaki ATF_CHECK(fp == NULL);
33793b7363cStnozaki ATF_CHECK(errno == EINVAL);
33893b7363cStnozaki }
33993b7363cStnozaki }
34093b7363cStnozaki
34193b7363cStnozaki ATF_TC(test07);
ATF_TC_HEAD(test07,tc)34293b7363cStnozaki ATF_TC_HEAD(test07, tc)
34393b7363cStnozaki {
34493b7363cStnozaki atf_tc_set_md_var(tc, "descr", "test07");
34593b7363cStnozaki }
ATF_TC_BODY(test07,tc)34693b7363cStnozaki ATF_TC_BODY(test07, tc)
34793b7363cStnozaki {
34893b7363cStnozaki #if !defined(__GLIBC__)
34993b7363cStnozaki const char **p;
35093b7363cStnozaki const char *mode[] = {
35193b7363cStnozaki "r", "rb",
35293b7363cStnozaki "w", "wb",
35393b7363cStnozaki "a", "ab",
35493b7363cStnozaki NULL
35593b7363cStnozaki };
35693b7363cStnozaki FILE *fp;
35793b7363cStnozaki
35893b7363cStnozaki for (p = &mode[0]; *p != NULL; ++p) {
35993b7363cStnozaki /*
36093b7363cStnozaki * Because this feature is only useful when the stream is opened for updating
36193b7363cStnozaki * (because there is no way to get a pointer to the buffer) the fmemopen()
36293b7363cStnozaki * call may fail if the mode argument does not include a '+'.
36393b7363cStnozaki */
36493b7363cStnozaki errno = 0;
36593b7363cStnozaki fp = fmemopen(NULL, 1, *p);
36693b7363cStnozaki ATF_CHECK(fp == NULL);
36793b7363cStnozaki ATF_CHECK(errno == EINVAL);
36893b7363cStnozaki }
36993b7363cStnozaki #endif
37093b7363cStnozaki }
37193b7363cStnozaki
37293b7363cStnozaki ATF_TC(test08);
ATF_TC_HEAD(test08,tc)37393b7363cStnozaki ATF_TC_HEAD(test08, tc)
37493b7363cStnozaki {
37593b7363cStnozaki atf_tc_set_md_var(tc, "descr", "test08");
37693b7363cStnozaki }
ATF_TC_BODY(test08,tc)37793b7363cStnozaki ATF_TC_BODY(test08, tc)
37893b7363cStnozaki {
37993b7363cStnozaki #if !defined(__GLIBC__)
38093b7363cStnozaki const char **p;
38193b7363cStnozaki const char *mode[] = {
38293b7363cStnozaki "r+", "rb+", "r+b",
38393b7363cStnozaki "w+", "wb+", "w+b",
38493b7363cStnozaki "a+", "ab+", "a+b",
38593b7363cStnozaki NULL
38693b7363cStnozaki };
38793b7363cStnozaki FILE *fp;
38893b7363cStnozaki
38993b7363cStnozaki for (p = &mode[0]; *p != NULL; ++p) {
39093b7363cStnozaki /*
39193b7363cStnozaki * The buf argument is a null pointer and the allocation of a buffer of
39293b7363cStnozaki * length size has failed.
39393b7363cStnozaki */
39493b7363cStnozaki fp = fmemopen(NULL, SIZE_MAX, *p);
39593b7363cStnozaki ATF_CHECK(fp == NULL);
39693b7363cStnozaki ATF_CHECK(errno == ENOMEM);
39793b7363cStnozaki }
39893b7363cStnozaki #endif
39993b7363cStnozaki }
40093b7363cStnozaki
40193b7363cStnozaki /*
40293b7363cStnozaki * test09 - test14:
40393b7363cStnozaki * An attempt to seek a memory buffer stream to a negative position or to a
40493b7363cStnozaki * position larger than the buffer size given in the size argument shall fail.
40593b7363cStnozaki */
40693b7363cStnozaki
40793b7363cStnozaki ATF_TC(test09);
ATF_TC_HEAD(test09,tc)40893b7363cStnozaki ATF_TC_HEAD(test09, tc)
40993b7363cStnozaki {
41093b7363cStnozaki atf_tc_set_md_var(tc, "descr", "test09");
41193b7363cStnozaki }
ATF_TC_BODY(test09,tc)41293b7363cStnozaki ATF_TC_BODY(test09, tc)
41393b7363cStnozaki {
41493b7363cStnozaki struct testcase *t;
41593b7363cStnozaki const char **p;
41693b7363cStnozaki char buf[BUFSIZ];
41793b7363cStnozaki FILE *fp;
41893b7363cStnozaki off_t i;
41993b7363cStnozaki
42093b7363cStnozaki for (t = &testcases[0]; t->s != NULL; ++t) {
42193b7363cStnozaki for (p = &mode_rwa[0]; *p != NULL; ++p) {
42293b7363cStnozaki
42393b7363cStnozaki memcpy(&buf[0], t->s, t->n);
42493b7363cStnozaki fp = fmemopen(&buf[0], t->n, *p);
42593b7363cStnozaki ATF_CHECK(fp != NULL);
42693b7363cStnozaki
42793b7363cStnozaki /*
42893b7363cStnozaki * test fmemopen_seek(SEEK_SET)
42993b7363cStnozaki */
43093b7363cStnozaki /* zero */
43193b7363cStnozaki ATF_CHECK(fseeko(fp, (off_t)0, SEEK_SET) == 0);
43293b7363cStnozaki ATF_CHECK(ftello(fp) == (off_t)0);
43393b7363cStnozaki
43493b7363cStnozaki /* positive */
43593b7363cStnozaki for (i = (off_t)1; i <= (off_t)t->n; ++i) {
43693b7363cStnozaki ATF_CHECK(fseeko(fp, i, SEEK_SET) == 0);
43793b7363cStnozaki ATF_CHECK(ftello(fp) == i);
43893b7363cStnozaki }
43993b7363cStnozaki /* positive + OOB */
44093b7363cStnozaki ATF_CHECK(fseeko(fp, t->n + 1, SEEK_SET) == -1);
44193b7363cStnozaki ATF_CHECK(ftello(fp) == t->n);
44293b7363cStnozaki
44393b7363cStnozaki /* negative + OOB */
44493b7363cStnozaki ATF_CHECK(fseeko(fp, (off_t)-1, SEEK_SET) == -1);
44593b7363cStnozaki ATF_CHECK(ftello(fp) == t->n);
44693b7363cStnozaki
44793b7363cStnozaki ATF_CHECK(fclose(fp) == 0);
44893b7363cStnozaki }
44993b7363cStnozaki }
45093b7363cStnozaki }
45193b7363cStnozaki
45293b7363cStnozaki const char *mode_rw[] = {
45393b7363cStnozaki "r", "rb", "r+", "rb+", "r+b",
45493b7363cStnozaki "w", "wb", "w+", "wb+", "w+b",
45593b7363cStnozaki NULL
45693b7363cStnozaki };
45793b7363cStnozaki
45893b7363cStnozaki ATF_TC(test10);
ATF_TC_HEAD(test10,tc)45993b7363cStnozaki ATF_TC_HEAD(test10, tc)
46093b7363cStnozaki {
46193b7363cStnozaki atf_tc_set_md_var(tc, "descr", "test10");
46293b7363cStnozaki }
ATF_TC_BODY(test10,tc)46393b7363cStnozaki ATF_TC_BODY(test10, tc)
46493b7363cStnozaki {
46593b7363cStnozaki struct testcase *t;
466d56fcfc9Schristos off_t i;
46793b7363cStnozaki const char **p;
46893b7363cStnozaki char buf[BUFSIZ];
46993b7363cStnozaki FILE *fp;
47093b7363cStnozaki
47193b7363cStnozaki for (t = &testcases[0]; t->s != NULL; ++t) {
47293b7363cStnozaki for (p = &mode_rw[0]; *p != NULL; ++p) {
47393b7363cStnozaki
47493b7363cStnozaki memcpy(&buf[0], t->s, t->n);
47593b7363cStnozaki fp = fmemopen(&buf[0], t->n, *p);
47693b7363cStnozaki ATF_CHECK(fp != NULL);
47793b7363cStnozaki
47893b7363cStnozaki /*
47993b7363cStnozaki * test fmemopen_seek(SEEK_CUR)
48093b7363cStnozaki */
48193b7363cStnozaki ATF_CHECK(ftello(fp) == (off_t)0);
48293b7363cStnozaki
48393b7363cStnozaki /* zero */
48493b7363cStnozaki ATF_CHECK(fseeko(fp, (off_t)0, SEEK_CUR) == 0);
48593b7363cStnozaki ATF_CHECK(ftello(fp) == (off_t)0);
48693b7363cStnozaki
48793b7363cStnozaki /* negative & OOB */
48893b7363cStnozaki ATF_CHECK(fseeko(fp, (off_t)-1, SEEK_CUR) == -1);
48993b7363cStnozaki ATF_CHECK(ftello(fp) == (off_t)0);
49093b7363cStnozaki
49193b7363cStnozaki /* positive */
49293b7363cStnozaki for (i = 0; i < (off_t)t->n; ++i) {
49393b7363cStnozaki ATF_CHECK(fseeko(fp, (off_t)1, SEEK_CUR) == 0);
49493b7363cStnozaki ATF_CHECK(ftello(fp) == i + 1);
49593b7363cStnozaki }
49693b7363cStnozaki
49793b7363cStnozaki /* positive & OOB */
49893b7363cStnozaki ATF_CHECK(fseeko(fp, (off_t)1, SEEK_CUR) == -1);
49993b7363cStnozaki ATF_CHECK(ftello(fp) == (off_t)t->n);
50093b7363cStnozaki
50193b7363cStnozaki ATF_CHECK(fclose(fp) == 0);
50293b7363cStnozaki }
50393b7363cStnozaki }
50493b7363cStnozaki }
50593b7363cStnozaki
50693b7363cStnozaki ATF_TC(test11);
ATF_TC_HEAD(test11,tc)50793b7363cStnozaki ATF_TC_HEAD(test11, tc)
50893b7363cStnozaki {
50993b7363cStnozaki atf_tc_set_md_var(tc, "descr", "test11");
51093b7363cStnozaki }
ATF_TC_BODY(test11,tc)51193b7363cStnozaki ATF_TC_BODY(test11, tc)
51293b7363cStnozaki {
51393b7363cStnozaki struct testcase *t;
51493b7363cStnozaki off_t len, rest, i;
51593b7363cStnozaki const char **p;
51693b7363cStnozaki char buf[BUFSIZ];
51793b7363cStnozaki FILE *fp;
51893b7363cStnozaki
51993b7363cStnozaki /* test fmemopen_seek(SEEK_CUR) */
52093b7363cStnozaki for (t = &testcases[0]; t->s != NULL; ++t) {
52193b7363cStnozaki len = (off_t)strnlen(t->s, t->n);
52293b7363cStnozaki rest = (off_t)t->n - len;
52393b7363cStnozaki for (p = &mode_a[0]; *p != NULL; ++p) {
52493b7363cStnozaki
52593b7363cStnozaki memcpy(&buf[0], t->s, t->n);
52693b7363cStnozaki fp = fmemopen(&buf[0], t->n, *p);
52793b7363cStnozaki ATF_CHECK(fp != NULL);
52893b7363cStnozaki /*
52993b7363cStnozaki * test fmemopen_seek(SEEK_CUR)
53093b7363cStnozaki */
53193b7363cStnozaki #if defined(__GLIBC__)
53293b7363cStnozaki if (i < (off_t)t->n) {
53393b7363cStnozaki #endif
53493b7363cStnozaki /* zero */
53593b7363cStnozaki ATF_CHECK(fseeko(fp, (off_t)0, SEEK_CUR) == 0);
53693b7363cStnozaki ATF_CHECK(ftello(fp) == len);
53793b7363cStnozaki
53893b7363cStnozaki /* posive */
53993b7363cStnozaki for (i = (off_t)1; i <= rest; ++i) {
54093b7363cStnozaki ATF_CHECK(fseeko(fp, (off_t)1, SEEK_CUR) == 0);
54193b7363cStnozaki ATF_CHECK(ftello(fp) == len + i);
54293b7363cStnozaki }
54393b7363cStnozaki
54493b7363cStnozaki /* positive + OOB */
54593b7363cStnozaki ATF_CHECK(fseeko(fp, (off_t)1, SEEK_CUR) == -1);
54693b7363cStnozaki ATF_CHECK(ftello(fp) == (off_t)t->n);
54793b7363cStnozaki
54893b7363cStnozaki /* negative */
54993b7363cStnozaki for (i = (off_t)1; i <= (off_t)t->n; ++i) {
55093b7363cStnozaki ATF_CHECK(fseeko(fp, (off_t)-1, SEEK_CUR) == 0);
55193b7363cStnozaki ATF_CHECK(ftello(fp) == (off_t)t->n - i);
55293b7363cStnozaki }
55393b7363cStnozaki
55493b7363cStnozaki /* negative + OOB */
55593b7363cStnozaki ATF_CHECK(fseeko(fp, (off_t)-1, SEEK_CUR) == -1);
55693b7363cStnozaki ATF_CHECK(ftello(fp) == (off_t)0);
55793b7363cStnozaki
55893b7363cStnozaki #if defined(__GLIBC__)
55993b7363cStnozaki }
56093b7363cStnozaki #endif
56193b7363cStnozaki ATF_CHECK(fclose(fp) == 0);
56293b7363cStnozaki }
56393b7363cStnozaki }
56493b7363cStnozaki }
56593b7363cStnozaki
56693b7363cStnozaki ATF_TC(test12);
ATF_TC_HEAD(test12,tc)56793b7363cStnozaki ATF_TC_HEAD(test12, tc)
56893b7363cStnozaki {
56993b7363cStnozaki atf_tc_set_md_var(tc, "descr", "test12");
57093b7363cStnozaki }
ATF_TC_BODY(test12,tc)57193b7363cStnozaki ATF_TC_BODY(test12, tc)
57293b7363cStnozaki {
57393b7363cStnozaki struct testcase *t;
57493b7363cStnozaki off_t len, rest, i;
57593b7363cStnozaki const char **p;
57693b7363cStnozaki char buf[BUFSIZ];
57793b7363cStnozaki FILE *fp;
57893b7363cStnozaki
57993b7363cStnozaki /* test fmemopen_seek(SEEK_END) */
58093b7363cStnozaki for (t = &testcases[0]; t->s != NULL; ++t) {
58193b7363cStnozaki len = (off_t)strnlen(t->s, t->n);
58293b7363cStnozaki rest = t->n - len;
58393b7363cStnozaki for (p = &mode_r[0]; *p != NULL; ++p) {
58493b7363cStnozaki
58593b7363cStnozaki memcpy(buf, t->s, t->n);
58693b7363cStnozaki fp = fmemopen(&buf[0], t->n, *p);
58793b7363cStnozaki ATF_CHECK(fp != NULL);
58893b7363cStnozaki
58993b7363cStnozaki /*
59093b7363cStnozaki * test fmemopen_seek(SEEK_END)
59193b7363cStnozaki */
59293b7363cStnozaki #if !defined(__GLIBC__)
59393b7363cStnozaki ATF_CHECK(ftello(fp) == (off_t)0);
59493b7363cStnozaki
59593b7363cStnozaki /* zero */
59693b7363cStnozaki ATF_CHECK(fseeko(fp, (off_t)0, SEEK_END) == 0);
59793b7363cStnozaki ATF_CHECK(ftello(fp) == len);
59893b7363cStnozaki
59993b7363cStnozaki /* positive + OOB */
60093b7363cStnozaki ATF_CHECK(fseeko(fp, rest + 1, SEEK_END) == -1);
60193b7363cStnozaki ATF_CHECK(ftello(fp) == len);
60293b7363cStnozaki
60393b7363cStnozaki /* negative + OOB */
60493b7363cStnozaki ATF_CHECK(fseeko(fp, -(len + 1), SEEK_END) == -1);
60593b7363cStnozaki ATF_CHECK(ftello(fp) == len);
60693b7363cStnozaki
60793b7363cStnozaki /* positive */
60893b7363cStnozaki for (i = 1; i <= rest; ++i) {
60993b7363cStnozaki ATF_CHECK(fseeko(fp, i, SEEK_END) == 0);
61093b7363cStnozaki ATF_CHECK(ftello(fp) == len + i);
61193b7363cStnozaki }
61293b7363cStnozaki
61393b7363cStnozaki /* negative */
61493b7363cStnozaki for (i = 1; i < len; ++i) {
61593b7363cStnozaki ATF_CHECK(fseeko(fp, -i, SEEK_END) == 0);
61693b7363cStnozaki ATF_CHECK(ftello(fp) == len - i);
61793b7363cStnozaki }
61893b7363cStnozaki #endif
61993b7363cStnozaki ATF_CHECK(fclose(fp) == 0);
62093b7363cStnozaki }
62193b7363cStnozaki }
62293b7363cStnozaki }
62393b7363cStnozaki
62493b7363cStnozaki ATF_TC(test13);
ATF_TC_HEAD(test13,tc)62593b7363cStnozaki ATF_TC_HEAD(test13, tc)
62693b7363cStnozaki {
62793b7363cStnozaki atf_tc_set_md_var(tc, "descr", "test13");
62893b7363cStnozaki }
ATF_TC_BODY(test13,tc)62993b7363cStnozaki ATF_TC_BODY(test13, tc)
63093b7363cStnozaki {
63193b7363cStnozaki struct testcase *t;
632d56fcfc9Schristos off_t i;
63393b7363cStnozaki const char **p;
63493b7363cStnozaki char buf[BUFSIZ];
63593b7363cStnozaki FILE *fp;
63693b7363cStnozaki
63793b7363cStnozaki /* test fmemopen_seek(SEEK_END) */
63893b7363cStnozaki for (t = &testcases[0]; t->s != NULL; ++t) {
63993b7363cStnozaki for (p = &mode_w[0]; *p != NULL; ++p) {
64093b7363cStnozaki
64193b7363cStnozaki memcpy(buf, t->s, t->n);
64293b7363cStnozaki fp = fmemopen(&buf[0], t->n, *p);
64393b7363cStnozaki ATF_CHECK(fp != NULL);
64493b7363cStnozaki /*
64593b7363cStnozaki * test fmemopen_seek(SEEK_END)
64693b7363cStnozaki */
64793b7363cStnozaki #if !defined(__GLIBC__)
64893b7363cStnozaki ATF_CHECK(ftello(fp) == (off_t)0);
64993b7363cStnozaki ATF_CHECK(buf[0] == '\0');
65093b7363cStnozaki
65193b7363cStnozaki /* zero */
65293b7363cStnozaki ATF_CHECK(fseeko(fp, (off_t)0, SEEK_END) == 0);
65393b7363cStnozaki ATF_CHECK(ftello(fp) == (off_t)0);
65493b7363cStnozaki
65593b7363cStnozaki /* positive + OOB */
65693b7363cStnozaki ATF_CHECK(fseeko(fp, (off_t)t->n + 1, SEEK_END) == -1);
65793b7363cStnozaki ATF_CHECK(ftello(fp) == (off_t)0);
65893b7363cStnozaki
65993b7363cStnozaki /* negative + OOB */
66093b7363cStnozaki ATF_CHECK(fseeko(fp, -1, SEEK_END) == -1);
66193b7363cStnozaki ATF_CHECK(ftello(fp) == (off_t)0);
66293b7363cStnozaki
66393b7363cStnozaki /* positive */
66493b7363cStnozaki for (i = 1; i <= t->n; ++i) {
66593b7363cStnozaki ATF_CHECK(fseeko(fp, i, SEEK_END) == 0);
66693b7363cStnozaki ATF_CHECK(ftello(fp) == i);
66793b7363cStnozaki }
66893b7363cStnozaki #endif
66993b7363cStnozaki ATF_CHECK(fclose(fp) == 0);
67093b7363cStnozaki }
67193b7363cStnozaki }
67293b7363cStnozaki }
67393b7363cStnozaki
67493b7363cStnozaki ATF_TC(test14);
ATF_TC_HEAD(test14,tc)67593b7363cStnozaki ATF_TC_HEAD(test14, tc)
67693b7363cStnozaki {
67793b7363cStnozaki atf_tc_set_md_var(tc, "descr", "test14");
67893b7363cStnozaki }
ATF_TC_BODY(test14,tc)67993b7363cStnozaki ATF_TC_BODY(test14, tc)
68093b7363cStnozaki {
68193b7363cStnozaki struct testcase *t;
68293b7363cStnozaki off_t len, rest, i;
68393b7363cStnozaki const char **p;
68493b7363cStnozaki char buf[BUFSIZ];
68593b7363cStnozaki FILE *fp;
68693b7363cStnozaki
68793b7363cStnozaki /* test fmemopen_seek(SEEK_END) */
68893b7363cStnozaki for (t = &testcases[0]; t->s != NULL; ++t) {
68993b7363cStnozaki len = (off_t)strnlen(t->s, t->n);
69093b7363cStnozaki rest = (off_t)t->n - len;
69193b7363cStnozaki for (p = &mode_a[0]; *p != NULL; ++p) {
69293b7363cStnozaki
69393b7363cStnozaki memcpy(buf, t->s, t->n);
69493b7363cStnozaki fp = fmemopen(&buf[0], t->n, *p);
69593b7363cStnozaki ATF_CHECK(fp != NULL);
69693b7363cStnozaki /*
69793b7363cStnozaki * test fmemopen_seek(SEEK_END)
69893b7363cStnozaki */
69993b7363cStnozaki #if !defined(__GLIBC__)
70093b7363cStnozaki ATF_CHECK(ftello(fp) == len);
70193b7363cStnozaki
70293b7363cStnozaki /* zero */
70393b7363cStnozaki ATF_CHECK(fseeko(fp, 0, SEEK_END) == 0);
70493b7363cStnozaki ATF_CHECK(ftello(fp) == len);
70593b7363cStnozaki
70693b7363cStnozaki /* positive + OOB */
70793b7363cStnozaki ATF_CHECK(fseeko(fp, rest + 1, SEEK_END) == -1);
70893b7363cStnozaki ATF_CHECK(ftello(fp) == len);
70993b7363cStnozaki
71093b7363cStnozaki /* negative + OOB */
71193b7363cStnozaki ATF_CHECK(fseeko(fp, -(len + 1), SEEK_END) == -1);
71293b7363cStnozaki ATF_CHECK(ftello(fp) == len);
71393b7363cStnozaki
71493b7363cStnozaki /* positive */
71593b7363cStnozaki for (i = 1; i <= rest; ++i) {
71693b7363cStnozaki ATF_CHECK(fseeko(fp, i, SEEK_END) == 0);
71793b7363cStnozaki ATF_CHECK(ftello(fp) == len + i);
71893b7363cStnozaki }
71993b7363cStnozaki
72093b7363cStnozaki /* negative */
72193b7363cStnozaki for (i = 1; i < len; ++i) {
72293b7363cStnozaki ATF_CHECK(fseeko(fp, -i, SEEK_END) == 0);
72393b7363cStnozaki ATF_CHECK(ftello(fp) == len - i);
72493b7363cStnozaki }
72593b7363cStnozaki #endif
72693b7363cStnozaki ATF_CHECK(fclose(fp) == 0);
72793b7363cStnozaki }
72893b7363cStnozaki }
72993b7363cStnozaki }
73093b7363cStnozaki
73193b7363cStnozaki const char *mode_rw1[] = {
73293b7363cStnozaki "r", "rb", "r+", "rb+", "r+b",
73393b7363cStnozaki "w+", "wb+",
73493b7363cStnozaki NULL
73593b7363cStnozaki };
73693b7363cStnozaki
73793b7363cStnozaki /* test15 - 18:
73893b7363cStnozaki * When a stream open for writing is flushed or closed, a null byte is written
73993b7363cStnozaki * at the current position or at the end of the buffer, depending on the size
74093b7363cStnozaki * of the contents.
74193b7363cStnozaki */
74293b7363cStnozaki
74393b7363cStnozaki ATF_TC(test15);
ATF_TC_HEAD(test15,tc)74493b7363cStnozaki ATF_TC_HEAD(test15, tc)
74593b7363cStnozaki {
74693b7363cStnozaki atf_tc_set_md_var(tc, "descr", "test15");
74793b7363cStnozaki }
ATF_TC_BODY(test15,tc)74893b7363cStnozaki ATF_TC_BODY(test15, tc)
74993b7363cStnozaki {
75093b7363cStnozaki struct testcase *t;
75193b7363cStnozaki const char **p;
7520f10aa9dSchristos char buf0[BUFSIZ];
75393b7363cStnozaki FILE *fp;
7540f10aa9dSchristos int i;
75593b7363cStnozaki
75693b7363cStnozaki for (t = &testcases[0]; t->s != NULL; ++t) {
75793b7363cStnozaki for (p = &mode_rw1[0]; *p != NULL; ++p) {
75893b7363cStnozaki
75993b7363cStnozaki memcpy(&buf0[0], t->s, t->n);
76093b7363cStnozaki fp = fmemopen(&buf0[0], t->n, *p);
76193b7363cStnozaki ATF_CHECK(fp != NULL);
76293b7363cStnozaki /*
76393b7363cStnozaki * test fmemopen_read + fgetc(3)
76493b7363cStnozaki */
7650f10aa9dSchristos for (i = 0; i < t->n; ++i) {
76693b7363cStnozaki ATF_CHECK(ftello(fp) == (off_t)i);
76793b7363cStnozaki ATF_CHECK(fgetc(fp) == buf0[i]);
76893b7363cStnozaki ATF_CHECK(feof(fp) == 0);
76993b7363cStnozaki ATF_CHECK(ftello(fp) == (off_t)i + 1);
77093b7363cStnozaki }
77193b7363cStnozaki ATF_CHECK(fgetc(fp) == EOF);
77293b7363cStnozaki ATF_CHECK(feof(fp) != 0);
77393b7363cStnozaki ATF_CHECK(ftello(fp) == (off_t)t->n);
77493b7363cStnozaki ATF_CHECK(fclose(fp) == 0);
77593b7363cStnozaki }
77693b7363cStnozaki }
77793b7363cStnozaki }
77893b7363cStnozaki
77993b7363cStnozaki ATF_TC(test16);
ATF_TC_HEAD(test16,tc)78093b7363cStnozaki ATF_TC_HEAD(test16, tc)
78193b7363cStnozaki {
78293b7363cStnozaki atf_tc_set_md_var(tc, "descr", "test16");
78393b7363cStnozaki }
ATF_TC_BODY(test16,tc)78493b7363cStnozaki ATF_TC_BODY(test16, tc)
78593b7363cStnozaki {
78693b7363cStnozaki struct testcase *t;
78793b7363cStnozaki const char **p;
78893b7363cStnozaki char buf0[BUFSIZ], buf1[BUFSIZ];
78993b7363cStnozaki FILE *fp;
79093b7363cStnozaki
79193b7363cStnozaki for (t = &testcases[0]; t->s != NULL; ++t) {
79293b7363cStnozaki for (p = &mode_rw1[0]; *p != NULL; ++p) {
79393b7363cStnozaki
79493b7363cStnozaki memcpy(&buf0[0], t->s, t->n);
79593b7363cStnozaki buf1[t->n] = 0x1;
79693b7363cStnozaki fp = fmemopen(&buf0[0], t->n, *p);
79793b7363cStnozaki ATF_CHECK(fp != NULL);
79893b7363cStnozaki /*
79993b7363cStnozaki * test fmemopen_read + fread(4)
80093b7363cStnozaki */
80193b7363cStnozaki ATF_CHECK(ftello(fp) == (off_t)0);
8020f10aa9dSchristos ATF_CHECK(fread(&buf1[0], 1, sizeof(buf1), fp) == (size_t)t->n);
80393b7363cStnozaki ATF_CHECK(feof(fp) != 0);
80493b7363cStnozaki ATF_CHECK(memcmp(&buf0[0], &buf1[0], t->n) == 0);
80593b7363cStnozaki ATF_CHECK((unsigned char)buf1[t->n] == 0x1);
80693b7363cStnozaki
80793b7363cStnozaki ATF_CHECK(fclose(fp) == 0);
80893b7363cStnozaki }
80993b7363cStnozaki }
81093b7363cStnozaki }
81193b7363cStnozaki
81293b7363cStnozaki const char *mode_a1[] = { "a+", "ab+", NULL };
81393b7363cStnozaki
81493b7363cStnozaki ATF_TC(test17);
ATF_TC_HEAD(test17,tc)81593b7363cStnozaki ATF_TC_HEAD(test17, tc)
81693b7363cStnozaki {
81793b7363cStnozaki atf_tc_set_md_var(tc, "descr", "test17");
81893b7363cStnozaki }
ATF_TC_BODY(test17,tc)81993b7363cStnozaki ATF_TC_BODY(test17, tc)
82093b7363cStnozaki {
82193b7363cStnozaki struct testcase *t;
8220f10aa9dSchristos size_t len;
8230f10aa9dSchristos int i;
82493b7363cStnozaki const char **p;
82593b7363cStnozaki char buf[BUFSIZ];
82693b7363cStnozaki FILE *fp;
82793b7363cStnozaki
82893b7363cStnozaki for (t = &testcases[0]; t->s != NULL; ++t) {
82993b7363cStnozaki len = strnlen(t->s, t->n);
83093b7363cStnozaki for (p = &mode_a1[0]; *p != NULL; ++p) {
83193b7363cStnozaki
83293b7363cStnozaki memcpy(&buf[0], t->s, t->n);
83393b7363cStnozaki fp = fmemopen(&buf[0], t->n, *p);
83493b7363cStnozaki ATF_CHECK(fp != NULL);
83593b7363cStnozaki /*
83693b7363cStnozaki * test fmemopen_read + fgetc(3)
83793b7363cStnozaki */
83893b7363cStnozaki #if defined(__GLIBC__)
83993b7363cStnozaki if (i < t->n) {
84093b7363cStnozaki #endif
84193b7363cStnozaki for (i = len; i < t->n; ++i) {
84293b7363cStnozaki ATF_CHECK(ftello(fp) == (off_t)i);
84393b7363cStnozaki ATF_CHECK(fgetc(fp) == buf[i]);
84493b7363cStnozaki ATF_CHECK(feof(fp) == 0);
84593b7363cStnozaki ATF_CHECK(ftello(fp) == (off_t)i + 1);
84693b7363cStnozaki }
84793b7363cStnozaki ATF_CHECK(fgetc(fp) == EOF);
84893b7363cStnozaki ATF_CHECK(feof(fp) != 0);
84993b7363cStnozaki ATF_CHECK(ftello(fp) == (off_t)t->n);
85093b7363cStnozaki rewind(fp);
8510f10aa9dSchristos for (i = 0; i < t->n; ++i) {
85293b7363cStnozaki ATF_CHECK(ftello(fp) == (off_t)i);
85393b7363cStnozaki ATF_CHECK(fgetc(fp) == buf[i]);
85493b7363cStnozaki ATF_CHECK(feof(fp) == 0);
85593b7363cStnozaki ATF_CHECK(ftello(fp) == (off_t)i + 1);
85693b7363cStnozaki }
85793b7363cStnozaki ATF_CHECK(fgetc(fp) == EOF);
85893b7363cStnozaki ATF_CHECK(feof(fp) != 0);
85993b7363cStnozaki ATF_CHECK(ftello(fp) == (off_t)t->n);
86093b7363cStnozaki #if defined(__GLIBC__)
86193b7363cStnozaki }
86293b7363cStnozaki #endif
86393b7363cStnozaki ATF_CHECK(fclose(fp) == 0);
86493b7363cStnozaki }
86593b7363cStnozaki }
86693b7363cStnozaki }
86793b7363cStnozaki
86893b7363cStnozaki ATF_TC(test18);
ATF_TC_HEAD(test18,tc)86993b7363cStnozaki ATF_TC_HEAD(test18, tc)
87093b7363cStnozaki {
87193b7363cStnozaki atf_tc_set_md_var(tc, "descr", "test18");
87293b7363cStnozaki }
ATF_TC_BODY(test18,tc)87393b7363cStnozaki ATF_TC_BODY(test18, tc)
87493b7363cStnozaki {
87593b7363cStnozaki struct testcase *t;
8760f10aa9dSchristos size_t len;
87793b7363cStnozaki const char **p;
87893b7363cStnozaki char buf0[BUFSIZ], buf1[BUFSIZ];
87993b7363cStnozaki FILE *fp;
88093b7363cStnozaki
88193b7363cStnozaki for (t = &testcases[0]; t->s != NULL; ++t) {
88293b7363cStnozaki len = strnlen(t->s, t->n);
88393b7363cStnozaki for (p = &mode_a1[0]; *p != NULL; ++p) {
88493b7363cStnozaki
88593b7363cStnozaki memcpy(&buf0[0], t->s, t->n);
88693b7363cStnozaki buf1[t->n - len] = 0x1;
88793b7363cStnozaki fp = fmemopen(&buf0[0], t->n, *p);
88893b7363cStnozaki ATF_CHECK(fp != NULL);
88993b7363cStnozaki /*
89093b7363cStnozaki * test fmemopen_read + fread(3)
89193b7363cStnozaki */
89293b7363cStnozaki #if defined(__GLIBC__)
89393b7363cStnozaki if (i < t->n) {
89493b7363cStnozaki #endif
89593b7363cStnozaki ATF_CHECK(ftello(fp) == (off_t)len);
89693b7363cStnozaki ATF_CHECK(fread(&buf1[0], 1, sizeof(buf1), fp)
89793b7363cStnozaki == t->n - len);
89893b7363cStnozaki ATF_CHECK(feof(fp) != 0);
89993b7363cStnozaki ATF_CHECK(!memcmp(&buf0[len], &buf1[0], t->n - len));
90093b7363cStnozaki ATF_CHECK((unsigned char)buf1[t->n - len] == 0x1);
90193b7363cStnozaki rewind(fp);
90293b7363cStnozaki buf1[t->n] = 0x1;
90393b7363cStnozaki ATF_CHECK(ftello(fp) == (off_t)0);
90493b7363cStnozaki ATF_CHECK(fread(&buf1[0], 1, sizeof(buf1), fp)
9050f10aa9dSchristos == (size_t)t->n);
90693b7363cStnozaki ATF_CHECK(feof(fp) != 0);
90793b7363cStnozaki ATF_CHECK(!memcmp(&buf0[0], &buf1[0], t->n));
90893b7363cStnozaki ATF_CHECK((unsigned char)buf1[t->n] == 0x1);
90993b7363cStnozaki #if defined(__GLIBC__)
91093b7363cStnozaki }
91193b7363cStnozaki #endif
91293b7363cStnozaki ATF_CHECK(fclose(fp) == 0);
91393b7363cStnozaki }
91493b7363cStnozaki }
91593b7363cStnozaki }
91693b7363cStnozaki
91793b7363cStnozaki /*
91893b7363cStnozaki * test19 - test22:
91993b7363cStnozaki * If a stream open for update is flushed or closed and the last write has
92093b7363cStnozaki * advanced the current buffer size, a null byte is written at the end of the
92193b7363cStnozaki * buffer if it fits.
92293b7363cStnozaki */
92393b7363cStnozaki
92493b7363cStnozaki const char *mode_rw2[] = {
92593b7363cStnozaki "r+", "rb+", "r+b",
92693b7363cStnozaki "w", "wb", "w+", "wb+", "w+b",
92793b7363cStnozaki NULL
92893b7363cStnozaki };
92993b7363cStnozaki
93093b7363cStnozaki ATF_TC(test19);
ATF_TC_HEAD(test19,tc)93193b7363cStnozaki ATF_TC_HEAD(test19, tc)
93293b7363cStnozaki {
93393b7363cStnozaki atf_tc_set_md_var(tc, "descr", "test19");
93493b7363cStnozaki }
ATF_TC_BODY(test19,tc)93593b7363cStnozaki ATF_TC_BODY(test19, tc)
93693b7363cStnozaki {
93793b7363cStnozaki struct testcase *t;
9380f10aa9dSchristos int i;
93993b7363cStnozaki const char **p;
94093b7363cStnozaki char buf[BUFSIZ];
94193b7363cStnozaki FILE *fp;
94293b7363cStnozaki
94393b7363cStnozaki for (t = &testcases[0]; t->s != NULL; ++t) {
94493b7363cStnozaki for (p = &mode_rw2[0]; *p != NULL; ++p) {
94593b7363cStnozaki
94693b7363cStnozaki memcpy(&buf[0], t->s, t->n);
94793b7363cStnozaki buf[t->n] = 0x1;
94893b7363cStnozaki fp = fmemopen(&buf[0], t->n + 1, *p);
94993b7363cStnozaki ATF_CHECK(fp != NULL);
95093b7363cStnozaki setbuf(fp, NULL);
95193b7363cStnozaki /*
95293b7363cStnozaki * test fmemopen_write + fputc(3)
95393b7363cStnozaki */
9540f10aa9dSchristos for (i = 0; i < t->n; ++i) {
95593b7363cStnozaki ATF_CHECK(ftello(fp) == (off_t)i);
95693b7363cStnozaki ATF_CHECK(fputc(t->s[i], fp) == t->s[i]);
95793b7363cStnozaki ATF_CHECK(buf[i] == t->s[i]);
95893b7363cStnozaki ATF_CHECK(ftello(fp) == (off_t)i + 1);
95993b7363cStnozaki ATF_CHECK(buf[i] == t->s[i]);
96093b7363cStnozaki #if !defined(__GLIBC__)
96193b7363cStnozaki ATF_CHECK(buf[i + 1] == '\0');
96293b7363cStnozaki #endif
96393b7363cStnozaki }
96493b7363cStnozaki
96593b7363cStnozaki /* don't accept non nul character at end of buffer */
96693b7363cStnozaki ATF_CHECK(fputc(0x1, fp) == EOF);
967a0de0d0dSchristos ATF_CHECK_MSG(ftello(fp) == (off_t)t->n,
96836b9c1faSmartin "%jd != %jd", (intmax_t)ftello(fp),
96936b9c1faSmartin (intmax_t)t->n);
97093b7363cStnozaki ATF_CHECK(feof(fp) == 0);
97193b7363cStnozaki
97293b7363cStnozaki /* accept nul character at end of buffer */
97393b7363cStnozaki ATF_CHECK(fputc('\0', fp) == '\0');
97493b7363cStnozaki ATF_CHECK(ftello(fp) == (off_t)t->n + 1);
97593b7363cStnozaki ATF_CHECK(feof(fp) == 0);
97693b7363cStnozaki
97793b7363cStnozaki /* reach EOF */
97893b7363cStnozaki ATF_CHECK(fputc('\0', fp) == EOF);
97993b7363cStnozaki ATF_CHECK(ftello(fp) == (off_t)t->n + 1);
98093b7363cStnozaki
98193b7363cStnozaki /* compare */
98293b7363cStnozaki ATF_CHECK(memcmp(&buf[0], t->s, t->n) == 0);
98393b7363cStnozaki ATF_CHECK(buf[t->n] == '\0');
98493b7363cStnozaki
98593b7363cStnozaki ATF_CHECK(fclose(fp) == 0);
98693b7363cStnozaki }
98793b7363cStnozaki }
98893b7363cStnozaki }
98993b7363cStnozaki
99093b7363cStnozaki ATF_TC(test20);
ATF_TC_HEAD(test20,tc)99193b7363cStnozaki ATF_TC_HEAD(test20, tc)
99293b7363cStnozaki {
99393b7363cStnozaki atf_tc_set_md_var(tc, "descr", "test20");
99493b7363cStnozaki }
ATF_TC_BODY(test20,tc)99593b7363cStnozaki ATF_TC_BODY(test20, tc)
99693b7363cStnozaki {
99793b7363cStnozaki struct testcase *t;
99893b7363cStnozaki const char **p;
99993b7363cStnozaki char buf[BUFSIZ];
100093b7363cStnozaki FILE *fp;
100193b7363cStnozaki
100293b7363cStnozaki for (t = &testcases[0]; t->s != NULL; ++t) {
100393b7363cStnozaki for (p = &mode_rw2[0]; *p != NULL; ++p) {
100493b7363cStnozaki
100593b7363cStnozaki memcpy(&buf[0], t->s, t->n);
100693b7363cStnozaki buf[t->n] = 0x1;
100793b7363cStnozaki fp = fmemopen(&buf[0], t->n + 1, *p);
100893b7363cStnozaki ATF_CHECK(fp != NULL);
100993b7363cStnozaki setbuf(fp, NULL);
10100f10aa9dSchristos ATF_CHECK(fwrite(t->s, 1, t->n, fp) == (size_t)t->n);
101193b7363cStnozaki /*
101293b7363cStnozaki * test fmemopen_write + fwrite(3)
101393b7363cStnozaki */
101493b7363cStnozaki #if !defined(__GLIBC__)
101593b7363cStnozaki ATF_CHECK(buf[t->n] == '\0');
101693b7363cStnozaki
101793b7363cStnozaki /* don't accept non nul character at end of buffer */
101893b7363cStnozaki ATF_CHECK(fwrite("\x1", 1, 1, fp) == 0);
101993b7363cStnozaki ATF_CHECK(ftello(fp) == (off_t)t->n);
102093b7363cStnozaki ATF_CHECK(feof(fp) == 0);
102193b7363cStnozaki #endif
102293b7363cStnozaki
102393b7363cStnozaki /* accept nul character at end of buffer */
102493b7363cStnozaki ATF_CHECK(fwrite("\x0", 1, 1, fp) == 1);
102593b7363cStnozaki ATF_CHECK(ftello(fp) == (off_t)t->n + 1);
102693b7363cStnozaki ATF_CHECK(feof(fp) == 0);
102793b7363cStnozaki
102893b7363cStnozaki /* reach EOF */
102993b7363cStnozaki ATF_CHECK(fputc('\0', fp) == EOF);
103093b7363cStnozaki ATF_CHECK(ftello(fp) == (off_t)t->n + 1);
103193b7363cStnozaki
103293b7363cStnozaki /* compare */
103393b7363cStnozaki ATF_CHECK(memcmp(&buf[0], t->s, t->n) == 0);
103493b7363cStnozaki ATF_CHECK(buf[t->n] == '\0');
103593b7363cStnozaki
103693b7363cStnozaki ATF_CHECK(fclose(fp) == 0);
103793b7363cStnozaki }
103893b7363cStnozaki }
103993b7363cStnozaki }
104093b7363cStnozaki
104193b7363cStnozaki ATF_TC(test21);
ATF_TC_HEAD(test21,tc)104293b7363cStnozaki ATF_TC_HEAD(test21, tc)
104393b7363cStnozaki {
104493b7363cStnozaki atf_tc_set_md_var(tc, "descr", "test21");
104593b7363cStnozaki }
ATF_TC_BODY(test21,tc)104693b7363cStnozaki ATF_TC_BODY(test21, tc)
104793b7363cStnozaki {
104893b7363cStnozaki struct testcase *t;
10490f10aa9dSchristos int len, i;
105093b7363cStnozaki const char **p;
105193b7363cStnozaki char buf[BUFSIZ];
105293b7363cStnozaki FILE *fp;
105393b7363cStnozaki
105493b7363cStnozaki for (t = &testcases[0]; t->s != NULL; ++t) {
105593b7363cStnozaki len = strnlen(t->s, t->n);
105693b7363cStnozaki for (p = &mode_a[0]; *p != NULL; ++p) {
105793b7363cStnozaki memcpy(&buf[0], t->s, t->n);
105893b7363cStnozaki fp = fmemopen(&buf[0], t->n, *p);
105993b7363cStnozaki ATF_CHECK(fp != NULL);
106093b7363cStnozaki setbuf(fp, NULL);
106193b7363cStnozaki /*
106293b7363cStnozaki * test fmemopen_write + fputc(3)
106393b7363cStnozaki */
106493b7363cStnozaki if (len < t->n) {
106593b7363cStnozaki for (i = len; i < t->n - 1; ++i) {
106693b7363cStnozaki ATF_CHECK(ftello(fp) == (off_t)i);
106793b7363cStnozaki ATF_CHECK(fputc(t->s[i - len], fp)
106893b7363cStnozaki == t->s[i - len]);
106993b7363cStnozaki ATF_CHECK(buf[i] == t->s[i - len]);
107093b7363cStnozaki ATF_CHECK(ftello(fp) == (off_t)i + 1);
107193b7363cStnozaki #if !defined(__GLIBC__)
107293b7363cStnozaki ATF_CHECK(buf[i + 1] == '\0');
107393b7363cStnozaki #endif
107493b7363cStnozaki }
107593b7363cStnozaki
107693b7363cStnozaki /* don't accept non nul character at end of buffer */
107793b7363cStnozaki ATF_CHECK(ftello(fp) == (off_t)t->n - 1);
107893b7363cStnozaki ATF_CHECK(fputc(0x1, fp) == EOF);
107993b7363cStnozaki ATF_CHECK(ftello(fp) == (off_t)t->n - 1);
108093b7363cStnozaki
108193b7363cStnozaki /* accept nul character at end of buffer */
108293b7363cStnozaki ATF_CHECK(ftello(fp) == (off_t)t->n - 1);
108393b7363cStnozaki ATF_CHECK(fputc('\0', fp) == '\0');
108493b7363cStnozaki ATF_CHECK(ftello(fp) == (off_t)t->n);
108593b7363cStnozaki }
108693b7363cStnozaki
108793b7363cStnozaki /* reach EOF */
108893b7363cStnozaki ATF_CHECK(ftello(fp) == (off_t)t->n);
108993b7363cStnozaki ATF_CHECK(fputc('\0', fp) == EOF);
109093b7363cStnozaki ATF_CHECK(ftello(fp) == (off_t)t->n);
109193b7363cStnozaki
109293b7363cStnozaki ATF_CHECK(fclose(fp) == 0);
109393b7363cStnozaki }
109493b7363cStnozaki }
109593b7363cStnozaki }
109693b7363cStnozaki
109793b7363cStnozaki ATF_TC(test22);
ATF_TC_HEAD(test22,tc)109893b7363cStnozaki ATF_TC_HEAD(test22, tc)
109993b7363cStnozaki {
110093b7363cStnozaki atf_tc_set_md_var(tc, "descr", "test22");
110193b7363cStnozaki }
ATF_TC_BODY(test22,tc)110293b7363cStnozaki ATF_TC_BODY(test22, tc)
110393b7363cStnozaki {
110493b7363cStnozaki struct testcase *t0, *t1;
11050f10aa9dSchristos size_t len0, len1, nleft;
110693b7363cStnozaki const char **p;
110793b7363cStnozaki char buf[BUFSIZ];
110893b7363cStnozaki FILE *fp;
110993b7363cStnozaki
111093b7363cStnozaki for (t0 = &testcases[0]; t0->s != NULL; ++t0) {
111193b7363cStnozaki len0 = strnlen(t0->s, t0->n);
111293b7363cStnozaki for (t1 = &testcases[0]; t1->s != NULL; ++t1) {
111393b7363cStnozaki len1 = strnlen(t1->s, t1->n);
111493b7363cStnozaki for (p = &mode_a[0]; *p != NULL; ++p) {
111593b7363cStnozaki
111693b7363cStnozaki memcpy(&buf[0], t0->s, t0->n);
111793b7363cStnozaki fp = fmemopen(&buf[0], t0->n, *p);
111893b7363cStnozaki ATF_CHECK(fp != NULL);
111993b7363cStnozaki setbuf(fp, NULL);
112093b7363cStnozaki /*
112193b7363cStnozaki * test fmemopen_write + fwrite(3)
112293b7363cStnozaki */
112393b7363cStnozaki nleft = t0->n - len0;
112493b7363cStnozaki #if !defined(__GLIBC__)
112593b7363cStnozaki if (nleft == 0 || len1 == nleft - 1) {
112693b7363cStnozaki ATF_CHECK(fwrite(t1->s, 1, t1->n, fp)
112793b7363cStnozaki == nleft);
112893b7363cStnozaki ATF_CHECK(ftell(fp) == t1->n);
112993b7363cStnozaki } else {
113093b7363cStnozaki ATF_CHECK(fwrite(t1->s, 1, t1->n, fp)
113193b7363cStnozaki == nleft - 1);
113293b7363cStnozaki ATF_CHECK(ftell(fp) == t1->n - 1);
113393b7363cStnozaki }
113493b7363cStnozaki #endif
113593b7363cStnozaki ATF_CHECK(fclose(fp) == 0);
113693b7363cStnozaki }
113793b7363cStnozaki }
113893b7363cStnozaki }
113993b7363cStnozaki }
114093b7363cStnozaki
ATF_TP_ADD_TCS(tp)114193b7363cStnozaki ATF_TP_ADD_TCS(tp)
114293b7363cStnozaki {
114393b7363cStnozaki ATF_TP_ADD_TC(tp, test00);
114493b7363cStnozaki ATF_TP_ADD_TC(tp, test01);
114593b7363cStnozaki ATF_TP_ADD_TC(tp, test02);
114693b7363cStnozaki ATF_TP_ADD_TC(tp, test03);
114793b7363cStnozaki ATF_TP_ADD_TC(tp, test04);
114893b7363cStnozaki ATF_TP_ADD_TC(tp, test05);
114993b7363cStnozaki ATF_TP_ADD_TC(tp, test06);
115093b7363cStnozaki ATF_TP_ADD_TC(tp, test07);
115193b7363cStnozaki ATF_TP_ADD_TC(tp, test08);
115293b7363cStnozaki ATF_TP_ADD_TC(tp, test09);
115393b7363cStnozaki ATF_TP_ADD_TC(tp, test10);
115493b7363cStnozaki ATF_TP_ADD_TC(tp, test11);
115593b7363cStnozaki ATF_TP_ADD_TC(tp, test12);
115693b7363cStnozaki ATF_TP_ADD_TC(tp, test13);
115793b7363cStnozaki ATF_TP_ADD_TC(tp, test14);
115893b7363cStnozaki ATF_TP_ADD_TC(tp, test15);
115993b7363cStnozaki ATF_TP_ADD_TC(tp, test16);
116093b7363cStnozaki ATF_TP_ADD_TC(tp, test17);
116193b7363cStnozaki ATF_TP_ADD_TC(tp, test18);
116293b7363cStnozaki ATF_TP_ADD_TC(tp, test19);
116393b7363cStnozaki ATF_TP_ADD_TC(tp, test20);
116493b7363cStnozaki ATF_TP_ADD_TC(tp, test21);
116593b7363cStnozaki ATF_TP_ADD_TC(tp, test22);
116693b7363cStnozaki
116793b7363cStnozaki return atf_no_error();
116893b7363cStnozaki }
1169