1255303Sjilles/*-
2255303Sjilles * Copyright (c) 2013 Jilles Tjoelker
3255303Sjilles * All rights reserved.
4255303Sjilles *
5255303Sjilles * Redistribution and use in source and binary forms, with or without
6255303Sjilles * modification, are permitted provided that the following conditions
7255303Sjilles * are met:
8255303Sjilles * 1. Redistributions of source code must retain the above copyright
9255303Sjilles *    notice, this list of conditions and the following disclaimer.
10255303Sjilles * 2. Redistributions in binary form must reproduce the above copyright
11255303Sjilles *    notice, this list of conditions and the following disclaimer in the
12255303Sjilles *    documentation and/or other materials provided with the distribution.
13255303Sjilles *
14255303Sjilles * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15255303Sjilles * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16255303Sjilles * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17255303Sjilles * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18255303Sjilles * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19255303Sjilles * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20255303Sjilles * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21255303Sjilles * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22255303Sjilles * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23255303Sjilles * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24255303Sjilles * SUCH DAMAGE.
25255303Sjilles */
26255303Sjilles
27255303Sjilles#include <sys/cdefs.h>
28255303Sjilles__FBSDID("$FreeBSD: releng/11.0/lib/libc/tests/stdio/fopen_test.c 290537 2015-11-08 06:37:50Z ngie $");
29255303Sjilles
30290537Sngie#include <fcntl.h>
31290537Sngie#include <paths.h>
32290537Sngie#include <stdio.h>
33290537Sngie#include <string.h>
34255303Sjilles
35290537Sngie#include <atf-c.h>
36290537Sngie
37255303Sjilles/*
38255303Sjilles * O_ACCMODE is currently defined incorrectly. This is what it should be.
39255303Sjilles * Various code depends on the incorrect value.
40255303Sjilles */
41255303Sjilles#define CORRECT_O_ACCMODE (O_ACCMODE | O_EXEC)
42255303Sjilles
43255303Sjillesstatic void
44255303Sjillesruntest(const char *fname, const char *mode)
45255303Sjilles{
46255303Sjilles	FILE *fp;
47290537Sngie	int exp_fget_ret, fget_ret, fd, flags, wantedflags;
48255303Sjilles
49255303Sjilles	fp = fopen(fname, mode);
50290537Sngie	ATF_REQUIRE_MSG(fp != NULL,
51290537Sngie	    "fopen(\"%s\", \"%s\") failed", fname, mode);
52255303Sjilles	fd = fileno(fp);
53290537Sngie	ATF_REQUIRE_MSG(fd >= 0, "fileno() failed for fopen");
54290537Sngie	exp_fget_ret = strchr(mode, 'e') != NULL ? FD_CLOEXEC : 0;
55290537Sngie	ATF_REQUIRE_MSG((fget_ret = fcntl(fd, F_GETFD)) == exp_fget_ret,
56290537Sngie	    "fcntl(.., F_GETFD) didn't FD_CLOEXEC as expected %d != %d",
57290537Sngie	    exp_fget_ret, fget_ret);
58255303Sjilles	flags = fcntl(fd, F_GETFL);
59255303Sjilles	if (strchr(mode, '+'))
60255303Sjilles		wantedflags = O_RDWR | (*mode == 'a' ? O_APPEND : 0);
61255303Sjilles	else if (*mode == 'r')
62255303Sjilles		wantedflags = O_RDONLY;
63255303Sjilles	else if (*mode == 'w')
64255303Sjilles		wantedflags = O_WRONLY;
65255303Sjilles	else if (*mode == 'a')
66255303Sjilles		wantedflags = O_WRONLY | O_APPEND;
67255303Sjilles	else
68255303Sjilles		wantedflags = -1;
69290537Sngie	fclose(fp);
70255303Sjilles	if (wantedflags == -1)
71290537Sngie		atf_tc_fail("unrecognized mode: %s", mode);
72290537Sngie	else if ((flags & (CORRECT_O_ACCMODE | O_APPEND)) != wantedflags)
73290537Sngie		atf_tc_fail("incorrect access mode: %s", mode);
74255303Sjilles}
75255303Sjilles
76290537SngieATF_TC_WITHOUT_HEAD(fopen_r_test);
77290537SngieATF_TC_BODY(fopen_r_test, tc)
78255303Sjilles{
79255303Sjilles
80290537Sngie	runtest(_PATH_DEVNULL, "r");
81255303Sjilles}
82255303Sjilles
83290537SngieATF_TC_WITHOUT_HEAD(fopen_r_append_test);
84290537SngieATF_TC_BODY(fopen_r_append_test, tc)
85290537Sngie{
86290537Sngie
87290537Sngie	runtest(_PATH_DEVNULL, "r+");
88290537Sngie}
89290537Sngie
90290537SngieATF_TC_WITHOUT_HEAD(fopen_w_test);
91290537SngieATF_TC_BODY(fopen_w_test, tc)
92290537Sngie{
93290537Sngie
94290537Sngie	runtest(_PATH_DEVNULL, "w");
95290537Sngie}
96290537Sngie
97290537SngieATF_TC_WITHOUT_HEAD(fopen_w_append_test);
98290537SngieATF_TC_BODY(fopen_w_append_test, tc)
99290537Sngie{
100290537Sngie
101290537Sngie	runtest(_PATH_DEVNULL, "w+");
102290537Sngie}
103290537Sngie
104290537SngieATF_TC_WITHOUT_HEAD(fopen_a_test);
105290537SngieATF_TC_BODY(fopen_a_test, tc)
106290537Sngie{
107290537Sngie
108290537Sngie	runtest(_PATH_DEVNULL, "a");
109290537Sngie}
110290537Sngie
111290537SngieATF_TC_WITHOUT_HEAD(fopen_a_append_test);
112290537SngieATF_TC_BODY(fopen_a_append_test, tc)
113290537Sngie{
114290537Sngie
115290537Sngie	runtest(_PATH_DEVNULL, "a+");
116290537Sngie}
117290537Sngie
118290537SngieATF_TC_WITHOUT_HEAD(fopen_re_test);
119290537SngieATF_TC_BODY(fopen_re_test, tc)
120290537Sngie{
121290537Sngie
122290537Sngie	runtest(_PATH_DEVNULL, "re");
123290537Sngie}
124290537Sngie
125290537SngieATF_TC_WITHOUT_HEAD(fopen_r_append_e_test);
126290537SngieATF_TC_BODY(fopen_r_append_e_test, tc)
127290537Sngie{
128290537Sngie
129290537Sngie	runtest(_PATH_DEVNULL, "r+e");
130290537Sngie}
131290537Sngie
132290537SngieATF_TC_WITHOUT_HEAD(fopen_we_test);
133290537SngieATF_TC_BODY(fopen_we_test, tc)
134290537Sngie{
135290537Sngie
136290537Sngie	runtest(_PATH_DEVNULL, "we");
137290537Sngie}
138290537Sngie
139290537SngieATF_TC_WITHOUT_HEAD(fopen_w_append_e_test);
140290537SngieATF_TC_BODY(fopen_w_append_e_test, tc)
141290537Sngie{
142290537Sngie
143290537Sngie	runtest(_PATH_DEVNULL, "w+e");
144290537Sngie}
145290537Sngie
146290537SngieATF_TC_WITHOUT_HEAD(fopen_ae_test);
147290537SngieATF_TC_BODY(fopen_ae_test, tc)
148290537Sngie{
149290537Sngie
150290537Sngie	runtest(_PATH_DEVNULL, "ae");
151290537Sngie}
152290537Sngie
153290537SngieATF_TC_WITHOUT_HEAD(fopen_a_append_e_test);
154290537SngieATF_TC_BODY(fopen_a_append_e_test, tc)
155290537Sngie{
156290537Sngie
157290537Sngie	runtest(_PATH_DEVNULL, "a+e");
158290537Sngie}
159290537Sngie
160290537SngieATF_TC_WITHOUT_HEAD(fopen_re_append_test);
161290537SngieATF_TC_BODY(fopen_re_append_test, tc)
162290537Sngie{
163290537Sngie
164290537Sngie	runtest(_PATH_DEVNULL, "re+");
165290537Sngie}
166290537Sngie
167290537SngieATF_TC_WITHOUT_HEAD(fopen_we_append_test);
168290537SngieATF_TC_BODY(fopen_we_append_test, tc)
169290537Sngie{
170290537Sngie
171290537Sngie	runtest(_PATH_DEVNULL, "we+");
172290537Sngie}
173290537Sngie
174290537SngieATF_TC_WITHOUT_HEAD(fopen_ae_append_test);
175290537SngieATF_TC_BODY(fopen_ae_append_test, tc)
176290537Sngie{
177290537Sngie
178290537Sngie	runtest(_PATH_DEVNULL, "ae+");
179290537Sngie}
180290537Sngie
181290537SngieATF_TP_ADD_TCS(tp)
182290537Sngie{
183290537Sngie
184290537Sngie	ATF_TP_ADD_TC(tp, fopen_r_test);
185290537Sngie	ATF_TP_ADD_TC(tp, fopen_r_append_test);
186290537Sngie	ATF_TP_ADD_TC(tp, fopen_w_test);
187290537Sngie	ATF_TP_ADD_TC(tp, fopen_w_append_test);
188290537Sngie	ATF_TP_ADD_TC(tp, fopen_a_test);
189290537Sngie	ATF_TP_ADD_TC(tp, fopen_a_append_test);
190290537Sngie	ATF_TP_ADD_TC(tp, fopen_re_test);
191290537Sngie	ATF_TP_ADD_TC(tp, fopen_r_append_e_test);
192290537Sngie	ATF_TP_ADD_TC(tp, fopen_we_test);
193290537Sngie	ATF_TP_ADD_TC(tp, fopen_w_append_e_test);
194290537Sngie	ATF_TP_ADD_TC(tp, fopen_ae_test);
195290537Sngie	ATF_TP_ADD_TC(tp, fopen_a_append_e_test);
196290537Sngie	ATF_TP_ADD_TC(tp, fopen_re_append_test);
197290537Sngie	ATF_TP_ADD_TC(tp, fopen_we_append_test);
198290537Sngie	ATF_TP_ADD_TC(tp, fopen_ae_append_test);
199290537Sngie
200290537Sngie	return (atf_no_error());
201290537Sngie}
202290537Sngie
203290537Sngie/*
204290537Sngie vim:ts=8:cin:sw=8
205290537Sngie */
206