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$");
29255303Sjilles
30255303Sjilles#include	<fcntl.h>
31255303Sjilles#include	<stdio.h>
32255303Sjilles#include	<string.h>
33255303Sjilles
34255303Sjilles/*
35255303Sjilles * O_ACCMODE is currently defined incorrectly. This is what it should be.
36255303Sjilles * Various code depends on the incorrect value.
37255303Sjilles */
38255303Sjilles#define CORRECT_O_ACCMODE (O_ACCMODE | O_EXEC)
39255303Sjilles
40255303Sjillesstatic int testnum = 1;
41255303Sjilles
42255303Sjillesstatic void
43255303Sjillesruntest(const char *fname, const char *mode)
44255303Sjilles{
45255303Sjilles	FILE *fp;
46255303Sjilles	int fd, flags, wantedflags;
47255303Sjilles
48255303Sjilles	fp = fopen(fname, mode);
49255303Sjilles	if (fp == NULL) {
50255303Sjilles		printf("not ok %d - fopen(\"%s\", \"%s\") failed\n",
51255303Sjilles		    testnum++, fname, mode);
52255303Sjilles		printf("not ok %d - FD_CLOEXEC # SKIP\n",
53255303Sjilles		    testnum++);
54255303Sjilles		return;
55255303Sjilles	}
56255303Sjilles	fd = fileno(fp);
57255303Sjilles	if (fd < 0)
58255303Sjilles		printf("not ok %d - fileno() failed\n", testnum++);
59255303Sjilles	else
60255303Sjilles		printf("ok %d - fopen(\"%s\", \"%s\") and fileno() succeeded\n",
61255303Sjilles		    testnum++, fname, mode);
62255303Sjilles	if (fcntl(fd, F_GETFD) == (strchr(mode, 'e') != NULL ? FD_CLOEXEC : 0))
63255303Sjilles		printf("ok %d - FD_CLOEXEC flag correct\n", testnum++);
64255303Sjilles	else
65255303Sjilles		printf("not ok %d - FD_CLOEXEC flag incorrect\n", testnum++);
66255303Sjilles	flags = fcntl(fd, F_GETFL);
67255303Sjilles	if (strchr(mode, '+'))
68255303Sjilles		wantedflags = O_RDWR | (*mode == 'a' ? O_APPEND : 0);
69255303Sjilles	else if (*mode == 'r')
70255303Sjilles		wantedflags = O_RDONLY;
71255303Sjilles	else if (*mode == 'w')
72255303Sjilles		wantedflags = O_WRONLY;
73255303Sjilles	else if (*mode == 'a')
74255303Sjilles		wantedflags = O_WRONLY | O_APPEND;
75255303Sjilles	else
76255303Sjilles		wantedflags = -1;
77255303Sjilles	if (wantedflags == -1)
78255303Sjilles		printf("not ok %d - unrecognized mode\n", testnum++);
79255303Sjilles	else if ((flags & (CORRECT_O_ACCMODE | O_APPEND)) == wantedflags)
80255303Sjilles		printf("ok %d - correct access mode\n", testnum++);
81255303Sjilles	else
82255303Sjilles		printf("not ok %d - incorrect access mode\n", testnum++);
83255303Sjilles	fclose(fp);
84255303Sjilles}
85255303Sjilles
86255303Sjilles/*
87255303Sjilles * Test program for fopen().
88255303Sjilles */
89255303Sjillesint
90255303Sjillesmain(int argc, char *argv[])
91255303Sjilles{
92255303Sjilles	printf("1..45\n");
93255303Sjilles	runtest("/dev/null", "r");
94255303Sjilles	runtest("/dev/null", "r+");
95255303Sjilles	runtest("/dev/null", "w");
96255303Sjilles	runtest("/dev/null", "w+");
97255303Sjilles	runtest("/dev/null", "a");
98255303Sjilles	runtest("/dev/null", "a+");
99255303Sjilles	runtest("/dev/null", "re");
100255303Sjilles	runtest("/dev/null", "r+e");
101255303Sjilles	runtest("/dev/null", "we");
102255303Sjilles	runtest("/dev/null", "w+e");
103255303Sjilles	runtest("/dev/null", "ae");
104255303Sjilles	runtest("/dev/null", "a+e");
105255303Sjilles	runtest("/dev/null", "re+");
106255303Sjilles	runtest("/dev/null", "we+");
107255303Sjilles	runtest("/dev/null", "ae+");
108255303Sjilles
109255303Sjilles	return 0;
110255303Sjilles}
111255303Sjilles
112255303Sjilles/* vim:ts=8:cin:sw=8
113255303Sjilles *  */
114