1f08c3bdfSopenharmony_ci/*
2f08c3bdfSopenharmony_ci * NAME
3f08c3bdfSopenharmony_ci *	fcntl01.c
4f08c3bdfSopenharmony_ci *
5f08c3bdfSopenharmony_ci * DESCRIPTION
6f08c3bdfSopenharmony_ci *	Test F_DUPFD, F_SETFL cmds of fcntl
7f08c3bdfSopenharmony_ci *
8f08c3bdfSopenharmony_ci * CALLS
9f08c3bdfSopenharmony_ci *	fcntl
10f08c3bdfSopenharmony_ci *
11f08c3bdfSopenharmony_ci * ALGORITHM
12f08c3bdfSopenharmony_ci *
13f08c3bdfSopenharmony_ci *	1. Testing F_DUPFD cmd with arg less than, equal to, and greater
14f08c3bdfSopenharmony_ci *	   than the next available file descriptor.
15f08c3bdfSopenharmony_ci *
16f08c3bdfSopenharmony_ci *	2. Checking F_SETFL cmd with each valid flag (O_NDELAY, O_APPEND).
17f08c3bdfSopenharmony_ci *
18f08c3bdfSopenharmony_ci *	3. Checking, setting and reading `close on exec' flag.
19f08c3bdfSopenharmony_ci *
20f08c3bdfSopenharmony_ci * USAGE
21f08c3bdfSopenharmony_ci *	fcntl01
22f08c3bdfSopenharmony_ci *
23f08c3bdfSopenharmony_ci * HISTORY
24f08c3bdfSopenharmony_ci *	07/2001 Ported by Wayne Boyer
25f08c3bdfSopenharmony_ci *	09/2002 added fd2 array to remove statid fds
26f08c3bdfSopenharmony_ci *
27f08c3bdfSopenharmony_ci * RESTRICTIONS
28f08c3bdfSopenharmony_ci *	None
29f08c3bdfSopenharmony_ci *
30f08c3bdfSopenharmony_ci */
31f08c3bdfSopenharmony_ci
32f08c3bdfSopenharmony_ci#include <fcntl.h>
33f08c3bdfSopenharmony_ci#include <errno.h>
34f08c3bdfSopenharmony_ci#include <sys/types.h>
35f08c3bdfSopenharmony_ci#include <sys/stat.h>
36f08c3bdfSopenharmony_ci#include "test.h"
37f08c3bdfSopenharmony_ci
38f08c3bdfSopenharmony_civoid setup(void);
39f08c3bdfSopenharmony_civoid cleanup(void);
40f08c3bdfSopenharmony_ci
41f08c3bdfSopenharmony_cichar *TCID = "fcntl01";
42f08c3bdfSopenharmony_ciint TST_TOTAL = 1;
43f08c3bdfSopenharmony_ci
44f08c3bdfSopenharmony_ciint main(int ac, char **av)
45f08c3bdfSopenharmony_ci{
46f08c3bdfSopenharmony_ci	int flags;
47f08c3bdfSopenharmony_ci	char fname[40];
48f08c3bdfSopenharmony_ci	int fd[10], fd2[10];
49f08c3bdfSopenharmony_ci	int mypid;
50f08c3bdfSopenharmony_ci	unsigned int i;
51f08c3bdfSopenharmony_ci	int lc;
52f08c3bdfSopenharmony_ci
53f08c3bdfSopenharmony_ci	tst_parse_opts(ac, av, NULL, NULL);
54f08c3bdfSopenharmony_ci
55f08c3bdfSopenharmony_ci	setup();
56f08c3bdfSopenharmony_ci
57f08c3bdfSopenharmony_ci	/* check for looping state if -i option is given */
58f08c3bdfSopenharmony_ci	for (lc = 0; TEST_LOOPING(lc); lc++) {
59f08c3bdfSopenharmony_ci
60f08c3bdfSopenharmony_ci		tst_count = 0;
61f08c3bdfSopenharmony_ci
62f08c3bdfSopenharmony_ci		mypid = getpid();
63f08c3bdfSopenharmony_ci		for (i = 0; i < 8; i++) {
64f08c3bdfSopenharmony_ci			sprintf(fname, "./fcntl%d.%d", i, mypid);
65f08c3bdfSopenharmony_ci			if ((fd[i] =
66f08c3bdfSopenharmony_ci			     open(fname, O_WRONLY | O_CREAT, 0666)) == -1)
67f08c3bdfSopenharmony_ci				tst_resm(TBROK | TERRNO, "open failed");
68f08c3bdfSopenharmony_ci			fd2[i] = fd[i];
69f08c3bdfSopenharmony_ci		}
70f08c3bdfSopenharmony_ci
71f08c3bdfSopenharmony_ci		close(fd[2]);
72f08c3bdfSopenharmony_ci		close(fd[3]);
73f08c3bdfSopenharmony_ci		close(fd[4]);
74f08c3bdfSopenharmony_ci		close(fd[5]);
75f08c3bdfSopenharmony_ci
76f08c3bdfSopenharmony_ci		if ((fd[2] = fcntl(fd[1], F_DUPFD, 1)) == -1)
77f08c3bdfSopenharmony_ci			tst_resm(TFAIL | TERRNO, "fcntl(.., 1) failed");
78f08c3bdfSopenharmony_ci
79f08c3bdfSopenharmony_ci		if (fd[2] < fd2[2])
80f08c3bdfSopenharmony_ci			tst_resm(TFAIL, "new fd has unexpected value: "
81f08c3bdfSopenharmony_ci				 "got %d, expected greater than %d", fd[2], 5);
82f08c3bdfSopenharmony_ci
83f08c3bdfSopenharmony_ci		if ((fd[4] = fcntl(fd[1], F_DUPFD, fd2[3])) < 0)
84f08c3bdfSopenharmony_ci			tst_resm(TFAIL | TERRNO, "fcntl(.., fd2[3]) failed");
85f08c3bdfSopenharmony_ci
86f08c3bdfSopenharmony_ci		if (fd[4] < fd2[3])
87f08c3bdfSopenharmony_ci			tst_resm(TFAIL, "new fd has unexpected value, got %d, "
88f08c3bdfSopenharmony_ci				 "expect greater than %d", fd[4], fd2[3]);
89f08c3bdfSopenharmony_ci
90f08c3bdfSopenharmony_ci		if ((fd[8] = fcntl(fd[1], F_DUPFD, fd2[5])) < 0)
91f08c3bdfSopenharmony_ci			tst_resm(TFAIL | TERRNO, "fcntl(.., fd2[5]) failed");
92f08c3bdfSopenharmony_ci
93f08c3bdfSopenharmony_ci		if (fd[8] != fd2[5])
94f08c3bdfSopenharmony_ci			tst_resm(TFAIL, "new fd has unexpected value: "
95f08c3bdfSopenharmony_ci				 "got %d, expected %d", fd[8], fd2[5]);
96f08c3bdfSopenharmony_ci/* //block1: */
97f08c3bdfSopenharmony_ci		flags = fcntl(fd[2], F_GETFL, 0);
98f08c3bdfSopenharmony_ci		if ((flags & O_WRONLY) == 0)
99f08c3bdfSopenharmony_ci			tst_resm(TFAIL, "unexpected flag 0x%x, expected 0x%x",
100f08c3bdfSopenharmony_ci				 flags, O_WRONLY);
101f08c3bdfSopenharmony_ci
102f08c3bdfSopenharmony_ci		/* Check setting of no_delay flag */
103f08c3bdfSopenharmony_ci		if (fcntl(fd[2], F_SETFL, O_NDELAY) == -1)
104f08c3bdfSopenharmony_ci			tst_resm(TBROK | TERRNO, "fcntl(.., O_NDELAY) failed");
105f08c3bdfSopenharmony_ci
106f08c3bdfSopenharmony_ci		flags = fcntl(fd[2], F_GETFL, 0);
107f08c3bdfSopenharmony_ci		if ((flags & (O_NDELAY | O_WRONLY)) == 0)
108f08c3bdfSopenharmony_ci			tst_resm(TFAIL, "unexpected flag 0x%x, expected 0x%x",
109f08c3bdfSopenharmony_ci				 flags, O_NDELAY | O_WRONLY);
110f08c3bdfSopenharmony_ci
111f08c3bdfSopenharmony_ci		/* Check of setting append flag */
112f08c3bdfSopenharmony_ci		if (fcntl(fd[2], F_SETFL, O_APPEND) == -1)
113f08c3bdfSopenharmony_ci			tst_resm(TFAIL | TERRNO, "fcntl(.., O_APPEND) failed");
114f08c3bdfSopenharmony_ci
115f08c3bdfSopenharmony_ci		flags = fcntl(fd[2], F_GETFL, 0);
116f08c3bdfSopenharmony_ci		if ((flags & (O_APPEND | O_WRONLY)) == 0)
117f08c3bdfSopenharmony_ci			tst_resm(TFAIL, "unexpected flag ox%x, expected 0x%x",
118f08c3bdfSopenharmony_ci				 flags, O_APPEND | O_WRONLY);
119f08c3bdfSopenharmony_ci
120f08c3bdfSopenharmony_ci		/* Check setting flags together */
121f08c3bdfSopenharmony_ci		if (fcntl(fd[2], F_SETFL, O_NDELAY | O_APPEND) < 0)
122f08c3bdfSopenharmony_ci			tst_resm(TFAIL, "fcntl(.., O_NDELAY|O_APPEND) failed");
123f08c3bdfSopenharmony_ci
124f08c3bdfSopenharmony_ci		flags = fcntl(fd[2], F_GETFL, 0);
125f08c3bdfSopenharmony_ci		if ((flags & (O_NDELAY | O_APPEND | O_WRONLY)) == 0)
126f08c3bdfSopenharmony_ci			tst_resm(TFAIL, "unexpected flag 0x%x, expected 0x%x",
127f08c3bdfSopenharmony_ci				 flags,
128f08c3bdfSopenharmony_ci				 O_NDELAY | O_APPEND | O_SYNC | O_WRONLY);
129f08c3bdfSopenharmony_ci
130f08c3bdfSopenharmony_ci		/* Check that flags are not cummulative */
131f08c3bdfSopenharmony_ci		if (fcntl(fd[2], F_SETFL, 0) == -1)
132f08c3bdfSopenharmony_ci			tst_resm(TFAIL, "fcntl(.., 0) failed");
133f08c3bdfSopenharmony_ci
134f08c3bdfSopenharmony_ci		flags = fcntl(fd[2], F_GETFL, 0);
135f08c3bdfSopenharmony_ci		if ((flags & O_WRONLY) == 0)
136f08c3bdfSopenharmony_ci			tst_resm(TFAIL, "unexpected flag 0x%x, expected 0x%x",
137f08c3bdfSopenharmony_ci				 flags, O_WRONLY);
138f08c3bdfSopenharmony_ci
139f08c3bdfSopenharmony_ci/* //block2: */
140f08c3bdfSopenharmony_ci		/*
141f08c3bdfSopenharmony_ci		 * Check ability to set (F_SETFD) the close on exec flag
142f08c3bdfSopenharmony_ci		 */
143f08c3bdfSopenharmony_ci		if ((flags = fcntl(fd[2], F_GETFD, 0)) < 0)
144f08c3bdfSopenharmony_ci			tst_resm(TFAIL | TERRNO,
145f08c3bdfSopenharmony_ci				 "fcntl(.., F_GETFD, ..) #1 failed");
146f08c3bdfSopenharmony_ci		if (flags != 0)
147f08c3bdfSopenharmony_ci			tst_resm(TFAIL, "unexpected flags got 0x%x expected "
148f08c3bdfSopenharmony_ci				 "0x%x", flags, 0);
149f08c3bdfSopenharmony_ci		if ((flags = fcntl(fd[2], F_SETFD, 1)) == -1)
150f08c3bdfSopenharmony_ci			tst_resm(TFAIL, "fcntl(.., F_SETFD, ..) failed");
151f08c3bdfSopenharmony_ci		if ((flags = fcntl(fd[2], F_GETFD, 0)) == -1)
152f08c3bdfSopenharmony_ci			tst_resm(TFAIL | TERRNO,
153f08c3bdfSopenharmony_ci				 "fcntl(.., F_GETFD, ..) #2 failed");
154f08c3bdfSopenharmony_ci		if (flags != 1)
155f08c3bdfSopenharmony_ci			tst_resm(TFAIL, "unexpected flags, got 0x%x, "
156f08c3bdfSopenharmony_ci				 "expected 0x%x", flags, 1);
157f08c3bdfSopenharmony_ci
158f08c3bdfSopenharmony_ci		for (i = 0; i < ARRAY_SIZE(fd); i++)
159f08c3bdfSopenharmony_ci			close(fd[i]);
160f08c3bdfSopenharmony_ci		for (i = 0; i < 8; i++) {
161f08c3bdfSopenharmony_ci			sprintf(fname, "./fcntl%u.%d", i, mypid);
162f08c3bdfSopenharmony_ci			if ((unlink(fname)) == -1)
163f08c3bdfSopenharmony_ci				tst_resm(TFAIL | TERRNO,
164f08c3bdfSopenharmony_ci					 "unlinking %s failed", fname);
165f08c3bdfSopenharmony_ci		}
166f08c3bdfSopenharmony_ci	}
167f08c3bdfSopenharmony_ci	cleanup();
168f08c3bdfSopenharmony_ci	tst_exit();
169f08c3bdfSopenharmony_ci}
170f08c3bdfSopenharmony_ci
171f08c3bdfSopenharmony_ci/*
172f08c3bdfSopenharmony_ci * setup
173f08c3bdfSopenharmony_ci *	performs all ONE TIME setup for this test
174f08c3bdfSopenharmony_ci */
175f08c3bdfSopenharmony_civoid setup(void)
176f08c3bdfSopenharmony_ci{
177f08c3bdfSopenharmony_ci	tst_sig(FORK, DEF_HANDLER, cleanup);
178f08c3bdfSopenharmony_ci	umask(0);
179f08c3bdfSopenharmony_ci	TEST_PAUSE;
180f08c3bdfSopenharmony_ci	tst_tmpdir();
181f08c3bdfSopenharmony_ci}
182f08c3bdfSopenharmony_ci
183f08c3bdfSopenharmony_civoid cleanup(void)
184f08c3bdfSopenharmony_ci{
185f08c3bdfSopenharmony_ci	tst_rmdir();
186f08c3bdfSopenharmony_ci
187f08c3bdfSopenharmony_ci}
188