xref: /titanic_53/usr/src/test/libc-tests/tests/stdio/fileno.c (revision f65a228f854974d51b13928c21fa0ae281aa80af)
1*f65a228fSRobert Mustacchi /*
2*f65a228fSRobert Mustacchi  * This file and its contents are supplied under the terms of the
3*f65a228fSRobert Mustacchi  * Common Development and Distribution License ("CDDL"), version 1.0.
4*f65a228fSRobert Mustacchi  * You may only use this file in accordance with the terms of version
5*f65a228fSRobert Mustacchi  * 1.0 of the CDDL.
6*f65a228fSRobert Mustacchi  *
7*f65a228fSRobert Mustacchi  * A full copy of the text of the CDDL should have accompanied this
8*f65a228fSRobert Mustacchi  * source.  A copy of the CDDL is also available via the Internet at
9*f65a228fSRobert Mustacchi  * http://www.illumos.org/license/CDDL.
10*f65a228fSRobert Mustacchi  */
11*f65a228fSRobert Mustacchi 
12*f65a228fSRobert Mustacchi /*
13*f65a228fSRobert Mustacchi  * Copyright 2020 Robert Mustacchi
14*f65a228fSRobert Mustacchi  */
15*f65a228fSRobert Mustacchi 
16*f65a228fSRobert Mustacchi /*
17*f65a228fSRobert Mustacchi  * Tests to verify fileno(3C) behavior. This test explicitly leaks fds and FILE
18*f65a228fSRobert Mustacchi  * structures to make it easier to verify the subsequent fd behavior works and
19*f65a228fSRobert Mustacchi  * is apparent through the FILE *.
20*f65a228fSRobert Mustacchi  */
21*f65a228fSRobert Mustacchi 
22*f65a228fSRobert Mustacchi #include <stdio.h>
23*f65a228fSRobert Mustacchi #include <unistd.h>
24*f65a228fSRobert Mustacchi #include <err.h>
25*f65a228fSRobert Mustacchi #include <stdlib.h>
26*f65a228fSRobert Mustacchi #include <sys/types.h>
27*f65a228fSRobert Mustacchi #include <sys/stat.h>
28*f65a228fSRobert Mustacchi #include <fcntl.h>
29*f65a228fSRobert Mustacchi #include <wchar.h>
30*f65a228fSRobert Mustacchi 
31*f65a228fSRobert Mustacchi #define	FNO_DUPFD	150
32*f65a228fSRobert Mustacchi 
33*f65a228fSRobert Mustacchi static uint_t fno_nfails;
34*f65a228fSRobert Mustacchi static uint_t fno_ntests;
35*f65a228fSRobert Mustacchi static int fno_nextfd;
36*f65a228fSRobert Mustacchi 
37*f65a228fSRobert Mustacchi const char *
_umem_debug_init(void)38*f65a228fSRobert Mustacchi _umem_debug_init(void)
39*f65a228fSRobert Mustacchi {
40*f65a228fSRobert Mustacchi 	return ("default,verbose");
41*f65a228fSRobert Mustacchi }
42*f65a228fSRobert Mustacchi 
43*f65a228fSRobert Mustacchi const char *
_umem_logging_init(void)44*f65a228fSRobert Mustacchi _umem_logging_init(void)
45*f65a228fSRobert Mustacchi {
46*f65a228fSRobert Mustacchi 	return ("fail,contents");
47*f65a228fSRobert Mustacchi }
48*f65a228fSRobert Mustacchi 
49*f65a228fSRobert Mustacchi 
50*f65a228fSRobert Mustacchi static void
check_file(FILE * fp,int fd,const char * msg)51*f65a228fSRobert Mustacchi check_file(FILE *fp, int fd, const char *msg)
52*f65a228fSRobert Mustacchi {
53*f65a228fSRobert Mustacchi 	int act = fileno(fp);
54*f65a228fSRobert Mustacchi 	if (act != fd) {
55*f65a228fSRobert Mustacchi 		(void) printf("TEST FAILED: %s: expected fd %d, found %d\n",
56*f65a228fSRobert Mustacchi 		    msg, fd, act);
57*f65a228fSRobert Mustacchi 		fno_nfails++;
58*f65a228fSRobert Mustacchi 	} else {
59*f65a228fSRobert Mustacchi 		(void) printf("TEST PASSED: %s\n", msg);
60*f65a228fSRobert Mustacchi 	}
61*f65a228fSRobert Mustacchi 	fno_ntests++;
62*f65a228fSRobert Mustacchi }
63*f65a228fSRobert Mustacchi 
64*f65a228fSRobert Mustacchi static void
check_open_n(int n)65*f65a228fSRobert Mustacchi check_open_n(int n)
66*f65a228fSRobert Mustacchi {
67*f65a228fSRobert Mustacchi 	int fdbase;
68*f65a228fSRobert Mustacchi 	uint_t i;
69*f65a228fSRobert Mustacchi 
70*f65a228fSRobert Mustacchi 	for (i = 0, fdbase = fno_nextfd; i < n; i++, fdbase++) {
71*f65a228fSRobert Mustacchi 		FILE *f = fopen("/dev/null", "w+");
72*f65a228fSRobert Mustacchi 		if (f == NULL) {
73*f65a228fSRobert Mustacchi 			err(EXIT_FAILURE, "failed to open /dev/null");
74*f65a228fSRobert Mustacchi 		}
75*f65a228fSRobert Mustacchi 		check_file(f, fdbase, "Consecutive FDs");
76*f65a228fSRobert Mustacchi 	}
77*f65a228fSRobert Mustacchi }
78*f65a228fSRobert Mustacchi 
79*f65a228fSRobert Mustacchi static void
check_memstream(void)80*f65a228fSRobert Mustacchi check_memstream(void)
81*f65a228fSRobert Mustacchi {
82*f65a228fSRobert Mustacchi 	FILE *fmem, *omem, *wmem;
83*f65a228fSRobert Mustacchi 	char *buf;
84*f65a228fSRobert Mustacchi 	wchar_t *wbuf;
85*f65a228fSRobert Mustacchi 	size_t size;
86*f65a228fSRobert Mustacchi 
87*f65a228fSRobert Mustacchi 	fmem = fmemopen(NULL, 10, "w+");
88*f65a228fSRobert Mustacchi 	if (fmem == NULL) {
89*f65a228fSRobert Mustacchi 		err(EXIT_FAILURE, "failed to fmemopen()");
90*f65a228fSRobert Mustacchi 	}
91*f65a228fSRobert Mustacchi 
92*f65a228fSRobert Mustacchi 	omem = open_memstream(&buf, &size);
93*f65a228fSRobert Mustacchi 	if (omem == NULL) {
94*f65a228fSRobert Mustacchi 		err(EXIT_FAILURE, "failed to open_memstream()");
95*f65a228fSRobert Mustacchi 	}
96*f65a228fSRobert Mustacchi 
97*f65a228fSRobert Mustacchi 	wmem = open_wmemstream(&wbuf, &size);
98*f65a228fSRobert Mustacchi 	if (wmem == NULL) {
99*f65a228fSRobert Mustacchi 		err(EXIT_FAILURE, "failed to open_wmemstream()");
100*f65a228fSRobert Mustacchi 	}
101*f65a228fSRobert Mustacchi 
102*f65a228fSRobert Mustacchi 	check_file(fmem, -1, "basic fmemopen()");
103*f65a228fSRobert Mustacchi 	check_file(omem, -1, "basic open_memstream()");
104*f65a228fSRobert Mustacchi 	check_file(wmem, -1, "basic open_wmemstream()");
105*f65a228fSRobert Mustacchi }
106*f65a228fSRobert Mustacchi 
107*f65a228fSRobert Mustacchi static void
check_fdopen(void)108*f65a228fSRobert Mustacchi check_fdopen(void)
109*f65a228fSRobert Mustacchi {
110*f65a228fSRobert Mustacchi 	int fd, dupfd;
111*f65a228fSRobert Mustacchi 	FILE *f;
112*f65a228fSRobert Mustacchi 
113*f65a228fSRobert Mustacchi 	fd = open("/dev/null", O_RDWR);
114*f65a228fSRobert Mustacchi 	if (fd < 0) {
115*f65a228fSRobert Mustacchi 		err(EXIT_FAILURE, "failed to open /dev/null");
116*f65a228fSRobert Mustacchi 	}
117*f65a228fSRobert Mustacchi 	fno_nextfd = fd + 1;
118*f65a228fSRobert Mustacchi 
119*f65a228fSRobert Mustacchi 	f = fdopen(fd, "r+");
120*f65a228fSRobert Mustacchi 	if (f == NULL) {
121*f65a228fSRobert Mustacchi 		err(EXIT_FAILURE, "failed to fdopen /dev/null");
122*f65a228fSRobert Mustacchi 	}
123*f65a228fSRobert Mustacchi 	check_file(f, fd, "fdopen");
124*f65a228fSRobert Mustacchi 
125*f65a228fSRobert Mustacchi 	if ((dupfd = dup2(fd, FNO_DUPFD)) != FNO_DUPFD) {
126*f65a228fSRobert Mustacchi 		err(EXIT_FAILURE, "failed to dup2 /dev/null");
127*f65a228fSRobert Mustacchi 	}
128*f65a228fSRobert Mustacchi 	f = fdopen(dupfd, "r+");
129*f65a228fSRobert Mustacchi 	if (f == NULL) {
130*f65a228fSRobert Mustacchi 		err(EXIT_FAILURE, "failed to fdopen dup2'd /dev/null");
131*f65a228fSRobert Mustacchi 	}
132*f65a228fSRobert Mustacchi 	check_file(f, dupfd, "fdopen of dup2'd file");
133*f65a228fSRobert Mustacchi 
134*f65a228fSRobert Mustacchi 	f = freopen("/dev/zero", "r+", f);
135*f65a228fSRobert Mustacchi 	if (f == NULL) {
136*f65a228fSRobert Mustacchi 		err(EXIT_FAILURE, "failed to freopen dup2'd FILE *");
137*f65a228fSRobert Mustacchi 	}
138*f65a228fSRobert Mustacchi 	check_file(f, fno_nextfd, "freopen dup2'd FILE *");
139*f65a228fSRobert Mustacchi 	fno_nextfd++;
140*f65a228fSRobert Mustacchi }
141*f65a228fSRobert Mustacchi 
142*f65a228fSRobert Mustacchi static void
check_alternate(void)143*f65a228fSRobert Mustacchi check_alternate(void)
144*f65a228fSRobert Mustacchi {
145*f65a228fSRobert Mustacchi 	wchar_t *c;
146*f65a228fSRobert Mustacchi 	size_t s, i;
147*f65a228fSRobert Mustacchi 
148*f65a228fSRobert Mustacchi 	for (i = 0; i < 10; i++) {
149*f65a228fSRobert Mustacchi 		FILE *f, *save;
150*f65a228fSRobert Mustacchi 		f = fmemopen(NULL, 10, "a+");
151*f65a228fSRobert Mustacchi 		if (f == NULL) {
152*f65a228fSRobert Mustacchi 			err(EXIT_FAILURE, "failed to create fmemopen stream");
153*f65a228fSRobert Mustacchi 		}
154*f65a228fSRobert Mustacchi 		check_file(f, -1, "alternating memstream, fopen (fmemopen)");
155*f65a228fSRobert Mustacchi 
156*f65a228fSRobert Mustacchi 		save = f;
157*f65a228fSRobert Mustacchi 		f = fopen("/dev/zero", "r+");
158*f65a228fSRobert Mustacchi 		if (f == NULL) {
159*f65a228fSRobert Mustacchi 			err(EXIT_FAILURE, "failed to open /dev/zero");
160*f65a228fSRobert Mustacchi 		}
161*f65a228fSRobert Mustacchi 		check_file(f, fno_nextfd, "alternating memstream, fopen "
162*f65a228fSRobert Mustacchi 		    "(file)");
163*f65a228fSRobert Mustacchi 		fno_nextfd++;
164*f65a228fSRobert Mustacchi 
165*f65a228fSRobert Mustacchi 		f = open_wmemstream(&c, &s);
166*f65a228fSRobert Mustacchi 		if (f == NULL) {
167*f65a228fSRobert Mustacchi 			err(EXIT_FAILURE, "failed to create open_wmemstream() "
168*f65a228fSRobert Mustacchi 			    "stream");
169*f65a228fSRobert Mustacchi 		}
170*f65a228fSRobert Mustacchi 		check_file(f, -1, "alternating memstream, fopen (wmemstream)");
171*f65a228fSRobert Mustacchi 
172*f65a228fSRobert Mustacchi 		f = freopen("/dev/null", "r+", save);
173*f65a228fSRobert Mustacchi 		if (f == NULL) {
174*f65a228fSRobert Mustacchi 			err(EXIT_FAILURE, "failed to freopen /dev/null from "
175*f65a228fSRobert Mustacchi 			    "fmemopen()");
176*f65a228fSRobert Mustacchi 		}
177*f65a228fSRobert Mustacchi 		check_file(f, fno_nextfd, "alternating memstream, fopen "
178*f65a228fSRobert Mustacchi 		    "(reopen)");
179*f65a228fSRobert Mustacchi 
180*f65a228fSRobert Mustacchi 		f = freopen("/dev/zero", "a+", f);
181*f65a228fSRobert Mustacchi 		check_file(f, fno_nextfd, "alternating memstream, fopen "
182*f65a228fSRobert Mustacchi 		    "(reopen file)");
183*f65a228fSRobert Mustacchi 		fno_nextfd++;
184*f65a228fSRobert Mustacchi 	}
185*f65a228fSRobert Mustacchi }
186*f65a228fSRobert Mustacchi 
187*f65a228fSRobert Mustacchi int
main(void)188*f65a228fSRobert Mustacchi main(void)
189*f65a228fSRobert Mustacchi {
190*f65a228fSRobert Mustacchi 	check_file(stdin, STDIN_FILENO, "default stdin fd is correct");
191*f65a228fSRobert Mustacchi 	check_file(stdout, STDOUT_FILENO, "default stdout fd is correct");
192*f65a228fSRobert Mustacchi 	check_file(stderr, STDERR_FILENO, "default stderr fd is correct");
193*f65a228fSRobert Mustacchi 
194*f65a228fSRobert Mustacchi 	/*
195*f65a228fSRobert Mustacchi 	 * Establish our base fd. The test runner can open files on our behalf.
196*f65a228fSRobert Mustacchi 	 */
197*f65a228fSRobert Mustacchi 	fno_nextfd = open("/dev/null", O_RDONLY);
198*f65a228fSRobert Mustacchi 	if (fno_nextfd < 0) {
199*f65a228fSRobert Mustacchi 		err(EXIT_FAILURE, "failed to open /dev/null");
200*f65a228fSRobert Mustacchi 	}
201*f65a228fSRobert Mustacchi 	fno_nextfd++;
202*f65a228fSRobert Mustacchi 	check_open_n(10);
203*f65a228fSRobert Mustacchi 	fno_nextfd += 10;
204*f65a228fSRobert Mustacchi 	check_memstream();
205*f65a228fSRobert Mustacchi 	check_fdopen();
206*f65a228fSRobert Mustacchi 	check_alternate();
207*f65a228fSRobert Mustacchi 
208*f65a228fSRobert Mustacchi 	printf("%d/%d tests passed\n", fno_ntests - fno_nfails, fno_ntests);
209*f65a228fSRobert Mustacchi 	return (fno_nfails > 0 ? EXIT_FAILURE : EXIT_SUCCESS);
210*f65a228fSRobert Mustacchi }
211