1/*
2 *
3 *   Copyright (c) International Business Machines  Corp., 2002
4 *    ported from SPIE, section2/iosuite/dup3.c, by Airong Zhang
5 *   Copyright (c) 2013 Cyril Hrubis <chrubis@suse.cz>
6 *
7 *   This program is free software;  you can redistribute it and/or modify
8 *   it under the terms of the GNU General Public License as published by
9 *   the Free Software Foundation; either version 2 of the License, or
10 *   (at your option) any later version.
11 *
12 *   This program is distributed in the hope that it will be useful,
13 *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
14 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
15 *   the GNU General Public License for more details.
16 *
17 *   You should have received a copy of the GNU General Public License
18 *   along with this program;  if not, write to the Free Software
19 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22/*
23  WHAT:  Is the access mode the same for both file descriptors?
24          0: read only?
25          1: write only?
26          2: read/write?
27  HOW:   Creat a file with each access mode; dup each file descriptor;
28         stat each file descriptor and compare mode of each pair
29*/
30
31#include <stdio.h>
32#include <fcntl.h>
33#include <sys/types.h>
34#include <sys/stat.h>
35#include <sys/types.h>
36#include <sys/stat.h>
37#include "test.h"
38
39char *TCID = "dup07";
40int TST_TOTAL = 3;
41
42static const char *testfile = "dup07";
43
44static void setup(void);
45static void cleanup(void);
46
47int main(int ac, char **av)
48{
49	struct stat retbuf;
50	struct stat dupbuf;
51	int rdoret, wroret, rdwret;
52	int duprdo, dupwro, duprdwr;
53
54	int lc;
55
56	tst_parse_opts(ac, av, NULL, NULL);
57
58	setup();
59
60	for (lc = 0; TEST_LOOPING(lc); lc++) {
61
62		if ((rdoret = creat(testfile, 0444)) == -1) {
63			tst_resm(TFAIL, "Unable to creat file '%s'", testfile);
64		} else {
65			if ((duprdo = dup(rdoret)) == -1) {
66				tst_resm(TFAIL, "Unable to dup '%s'", testfile);
67			} else {
68				fstat(rdoret, &retbuf);
69				fstat(duprdo, &dupbuf);
70				if (retbuf.st_mode != dupbuf.st_mode) {
71					tst_resm(TFAIL,
72						 "rdonly and dup do not match");
73				} else {
74					tst_resm(TPASS,
75					         "Passed in read mode.");
76				}
77				close(duprdo);
78			}
79			close(rdoret);
80		}
81
82		unlink(testfile);
83
84		if ((wroret = creat(testfile, 0222)) == -1) {
85			tst_resm(TFAIL, "Unable to creat file '%s'", testfile);
86		} else {
87			if ((dupwro = dup(wroret)) == -1) {
88				tst_resm(TFAIL, "Unable to dup '%s'", testfile);
89			} else {
90				fstat(wroret, &retbuf);
91				fstat(dupwro, &dupbuf);
92				if (retbuf.st_mode != dupbuf.st_mode) {
93					tst_resm(TFAIL,
94						 "wronly and dup do not match");
95				} else {
96					tst_resm(TPASS,
97					         "Passed in write mode.");
98				}
99				close(dupwro);
100			}
101			close(wroret);
102
103		}
104
105		unlink(testfile);
106
107		if ((rdwret = creat(testfile, 0666)) == -1) {
108			tst_resm(TFAIL, "Unable to creat file '%s'", testfile);
109		} else {
110			if ((duprdwr = dup(rdwret)) == -1) {
111				tst_resm(TFAIL, "Unable to dup '%s'", testfile);
112			} else {
113				fstat(rdwret, &retbuf);
114				fstat(duprdwr, &dupbuf);
115				if (retbuf.st_mode != dupbuf.st_mode) {
116					tst_resm(TFAIL,
117						 "rdwr and dup do not match");
118				} else {
119					tst_resm(TPASS,
120					         "Passed in read/write mode.");
121				}
122				close(duprdwr);
123			}
124			close(rdwret);
125		}
126
127		unlink(testfile);
128	}
129
130	cleanup();
131	tst_exit();
132}
133
134static void setup(void)
135{
136	tst_tmpdir();
137}
138
139static void cleanup(void)
140{
141	tst_rmdir();
142}
143