1254888Sjilles/*-
2254888Sjilles * Copyright (c) 2013 Jilles Tjoelker
3254888Sjilles * All rights reserved.
4254888Sjilles *
5254888Sjilles * Redistribution and use in source and binary forms, with or without
6254888Sjilles * modification, are permitted provided that the following conditions
7254888Sjilles * are met:
8254888Sjilles * 1. Redistributions of source code must retain the above copyright
9254888Sjilles *    notice, this list of conditions and the following disclaimer.
10254888Sjilles * 2. Redistributions in binary form must reproduce the above copyright
11254888Sjilles *    notice, this list of conditions and the following disclaimer in the
12254888Sjilles *    documentation and/or other materials provided with the distribution.
13254888Sjilles *
14254888Sjilles * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15254888Sjilles * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16254888Sjilles * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17254888Sjilles * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18254888Sjilles * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19254888Sjilles * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20254888Sjilles * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21254888Sjilles * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22254888Sjilles * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23254888Sjilles * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24254888Sjilles * SUCH DAMAGE.
25254888Sjilles *
26254888Sjilles * $FreeBSD$
27254888Sjilles */
28254888Sjilles
29254888Sjilles#include <sys/cdefs.h>
30254888Sjilles
31254888Sjilles#include <fcntl.h>
32254888Sjilles#include <stdio.h>
33254888Sjilles#include <unistd.h>
34254888Sjilles
35254888Sjilles/*
36254888Sjilles * O_ACCMODE is currently defined incorrectly. This is what it should be.
37254888Sjilles * Various code depends on the incorrect value.
38254888Sjilles */
39254888Sjilles#define CORRECT_O_ACCMODE (O_ACCMODE | O_EXEC)
40254888Sjilles
41254888Sjillesstatic int testnum;
42254888Sjilles
43254888Sjillesstatic void
44254888Sjillessubtests(const char *path, int omode, const char *omodetext)
45254888Sjilles{
46254888Sjilles	int fd, flags1, flags2, flags3;
47254888Sjilles
48254888Sjilles	fd = open(path, omode);
49254888Sjilles	if (fd == -1)
50254888Sjilles		printf("not ok %d - open(\"%s\", %s) failed\n",
51254888Sjilles		    testnum++, path, omodetext);
52254888Sjilles	else
53254888Sjilles		printf("ok %d - open(\"%s\", %s) succeeded\n",
54254888Sjilles		    testnum++, path, omodetext);
55254888Sjilles	flags1 = fcntl(fd, F_GETFL);
56254888Sjilles	if (flags1 == -1)
57254888Sjilles		printf("not ok %d - fcntl(F_GETFL) failed\n", testnum++);
58254888Sjilles	else if ((flags1 & CORRECT_O_ACCMODE) == omode)
59254888Sjilles		printf("ok %d - fcntl(F_GETFL) gave correct result\n",
60254888Sjilles		    testnum++);
61254888Sjilles	else
62254888Sjilles		printf("not ok %d - fcntl(F_GETFL) gave incorrect result "
63254888Sjilles		    "(%#x & %#x != %#x)\n",
64254888Sjilles		    testnum++, flags1, CORRECT_O_ACCMODE, omode);
65254888Sjilles	if (fcntl(fd, F_SETFL, flags1) == -1)
66254888Sjilles		printf("not ok %d - fcntl(F_SETFL) same flags failed\n",
67254888Sjilles		    testnum++);
68254888Sjilles	else
69254888Sjilles		printf("ok %d - fcntl(F_SETFL) same flags succeeded\n",
70254888Sjilles		    testnum++);
71254888Sjilles	flags2 = fcntl(fd, F_GETFL);
72254888Sjilles	if (flags2 == -1)
73254888Sjilles		printf("not ok %d - fcntl(F_GETFL) failed\n", testnum++);
74254888Sjilles	else if (flags2 == flags1)
75254888Sjilles		printf("ok %d - fcntl(F_GETFL) gave same result\n",
76254888Sjilles		    testnum++);
77254888Sjilles	else
78254888Sjilles		printf("not ok %d - fcntl(F_SETFL) caused fcntl(F_GETFL) to "
79254888Sjilles		    "change from %#x to %#x\n",
80254888Sjilles		    testnum++, flags1, flags2);
81254888Sjilles	if (fcntl(fd, F_SETFL, flags2 | O_NONBLOCK) == -1)
82254888Sjilles		printf("not ok %d - fcntl(F_SETFL) O_NONBLOCK failed\n",
83254888Sjilles		    testnum++);
84254888Sjilles	else
85254888Sjilles		printf("ok %d - fcntl(F_SETFL) O_NONBLOCK succeeded\n",
86254888Sjilles		    testnum++);
87254888Sjilles	flags3 = fcntl(fd, F_GETFL);
88254888Sjilles	if (flags3 == -1)
89254888Sjilles		printf("not ok %d - fcntl(F_GETFL) failed\n", testnum++);
90254888Sjilles	else if (flags3 == (flags2 | O_NONBLOCK))
91254888Sjilles		printf("ok %d - fcntl(F_GETFL) gave expected result\n",
92254888Sjilles		    testnum++);
93254888Sjilles	else
94254888Sjilles		printf("not ok %d - fcntl(F_SETFL) gave unexpected result "
95254888Sjilles		    "(%#x != %#x)\n",
96254888Sjilles		    testnum++, flags3, flags2 | O_NONBLOCK);
97254888Sjilles	(void)close(fd);
98254888Sjilles}
99254888Sjilles
100254888Sjillesint
101254888Sjillesmain(int argc __unused, char **argv __unused)
102254888Sjilles{
103254888Sjilles	printf("1..24\n");
104254888Sjilles	testnum = 1;
105254888Sjilles	subtests("/dev/null", O_RDONLY, "O_RDONLY");
106254888Sjilles	subtests("/dev/null", O_WRONLY, "O_WRONLY");
107254888Sjilles	subtests("/dev/null", O_RDWR, "O_RDWR");
108254888Sjilles	subtests("/bin/sh", O_EXEC, "O_EXEC");
109254888Sjilles	return (0);
110254888Sjilles}
111