1/*
2 * This file and its contents are supplied under the terms of the
3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 * You may only use this file in accordance with the terms of version
5 * 1.0 of the CDDL.
6 *
7 * A full copy of the text of the CDDL should have accompanied this
8 * source.  A copy of the CDDL is also available via the Internet at
9 * http://www.illumos.org/license/CDDL.
10 */
11
12/*
13 * Copyright 2020 Robert Mustacchi
14 */
15
16/*
17 * In a c99/xpg6 environment freopen(3C) allows you to specify a NULL path to
18 * try and change the fopen() flags. Verify that the memstream functions do not
19 * allow this. Note, freopen(3C) is defined to try and close the stream, hence
20 * you won't see anything here.
21 */
22
23#include <stdio.h>
24#include <stdio.h>
25#include <wchar.h>
26#include <err.h>
27#include <stdlib.h>
28#include <errno.h>
29
30const char *
31_umem_debug_init(void)
32{
33	return ("default,verbose");
34}
35
36const char *
37_umem_logging_init(void)
38{
39	return ("fail,contents");
40}
41
42static void
43check_reopen(FILE *f, const char *variant)
44{
45	FILE *new = freopen(NULL, "r", f);
46	if (new != NULL) {
47		errx(EXIT_FAILURE, "TEST FAILED: was able to freopen %s",
48		    variant);
49	}
50
51	if (errno != EBADF) {
52		errx(EXIT_FAILURE, "TEST FAILED: found wrong errno for %s: "
53		    "expected %d, found %d", EBADF, errno);
54	}
55
56	(void) printf("TEST PASSED: %s\n", variant);
57}
58
59int
60main(void)
61{
62	FILE *f;
63	char *c;
64	wchar_t *wc;
65	size_t sz;
66
67	f = fmemopen(NULL, 16, "a+");
68	if (f == NULL) {
69		err(EXIT_FAILURE, "failed to create fmemopen() stream");
70	}
71	check_reopen(f, "fmemopen()");
72
73	f = open_memstream(&c, &sz);
74	if (f == NULL) {
75		err(EXIT_FAILURE, "failed to create open_memstream() stream");
76	}
77	check_reopen(f, "open_memstream()");
78	free(c);
79
80	f = open_wmemstream(&wc, &sz);
81	if (f == NULL) {
82		err(EXIT_FAILURE, "failed to create open_wmemstream() stream");
83	}
84	check_reopen(f, "open_wmemstream()");
85	free(wc);
86
87	return (0);
88}
89