1/*
2 *
3 *   Copyright (c) International Business Machines  Corp., 2001
4 *
5 *   This program is free software;  you can redistribute it and/or modify
6 *   it under the terms of the GNU General Public License as published by
7 *   the Free Software Foundation; either version 2 of the License, or
8 *   (at your option) any later version.
9 *
10 *   This program is distributed in the hope that it will be useful,
11 *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
12 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
13 *   the GNU General Public License for more details.
14 *
15 *   You should have received a copy of the GNU General Public License
16 *   along with this program;  if not, write to the Free Software
17 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20/*
21 * NAME
22 *	fchdir01.c
23 *
24 * DESCRIPTION
25 *	fchdir01 - create a directory and cd into it.
26 *
27 * ALGORITHM
28 *	create a new directory
29 *	open the directory and get a file descriptor
30 *	loop if that option was specified
31 *	fchdir() into the directory
32 *	check the return code
33 *	  if failure, issue a FAIL message.
34 *	otherwise,
35 *	  if doing functionality testing, call check_functionality()
36 *	  	if correct,
37 *			issue a PASS message
38 *		otherwise
39 *			issue a FAIL message
40 *	call cleanup
41 *
42 * USAGE:  <for command-line>
43 *  fchdir01 [-c n] [-f] [-i n] [-I x] [-P x] [-t]
44 *     where,  -c n : Run n copies concurrently.
45 *             -f   : Turn off functionality Testing.
46 *	       -i n : Execute test n times.
47 *	       -I x : Execute test for x seconds.
48 *	       -P x : Pause for x seconds between iterations.
49 *	       -t   : Turn on syscall timing.
50 *
51 * HISTORY
52 *	03/2001 - Written by Wayne Boyer
53 *
54 * RESTRICTIONS
55 *	none
56 */
57
58#include "test.h"
59
60#include <sys/stat.h>
61#include <errno.h>
62#include <fcntl.h>
63#include <libgen.h>
64#include <string.h>
65
66void cleanup(void);
67void setup(void);
68
69char *TCID = "fchdir01";
70int TST_TOTAL = 1;
71
72int fd;
73char *temp_dir;
74const char *TEST_DIR = "alpha";
75
76#define MODES	S_IRWXU
77
78int main(int ac, char **av)
79{
80	int lc;
81	void check_functionality(void);
82	int r_val;
83
84	tst_parse_opts(ac, av, NULL, NULL);
85
86	setup();		/* global setup */
87
88	for (lc = 0; TEST_LOOPING(lc); lc++) {
89		tst_count = 0;
90
91		/* get the name of the test dirctory */
92		if ((temp_dir = (getcwd(temp_dir, 0))) == NULL)
93			tst_brkm(TBROK, cleanup, "getcwd failed");
94
95		/*
96		 * create a new directory and open it
97		 */
98
99		if ((r_val = mkdir(TEST_DIR, MODES)) == -1)
100			tst_brkm(TBROK, cleanup, "mkdir failed");
101
102		if ((fd = open(TEST_DIR, O_RDONLY)) == -1)
103			tst_brkm(TBROK, cleanup, "open of directory failed");
104
105		TEST(fchdir(fd));
106
107		if (TEST_RETURN == -1) {
108			tst_brkm(TFAIL | TTERRNO, cleanup,
109				 "fchdir call failed");
110		} else {
111				check_functionality();
112		}
113
114		/*
115		 * clean up things in case we are looping
116		 */
117
118		/*
119		 * NOTE: in case of failure here, we need to use "tst_resm()"
120		 * and not "tst_brkm()".  This is because if we get to this
121		 * point, we have already set a PASS or FAIL for the test
122		 * and "tst_brkm()" won't report as we might expect.
123		 */
124
125		/* chdir back to our temporary work directory */
126		if ((r_val = chdir("..")) == -1)
127			tst_resm(TBROK | TERRNO, "chdir failed");
128
129		if ((r_val = rmdir(TEST_DIR)) == -1)
130			tst_resm(TBROK | TERRNO, "rmdir failed");
131
132		free(temp_dir);
133		temp_dir = NULL;
134	}
135
136	cleanup();
137	tst_exit();
138}
139
140void check_functionality(void)
141{
142	char *buf = NULL;
143	char *dir;
144
145	if ((buf = (getcwd(buf, 0))) == NULL) {
146		tst_brkm(TBROK, cleanup, "getcwd failed");
147	}
148
149	if ((dir = basename(buf)) == NULL)
150		tst_brkm(TBROK, cleanup, "basename failed");
151
152	if (strcmp(TEST_DIR, dir) == 0)
153		tst_resm(TPASS, "fchdir call succeeded");
154	else
155		tst_resm(TFAIL, "fchdir call failed");
156}
157
158void setup(void)
159{
160
161	tst_sig(NOFORK, DEF_HANDLER, cleanup);
162
163	TEST_PAUSE;
164
165	tst_tmpdir();
166}
167
168void cleanup(void)
169{
170	tst_rmdir();
171}
172