xref: /aosp_15_r20/external/ltp/lib/tst_tmpdir.c (revision 49cdfc7efb34551c7342be41a7384b9c40d7cab7)
1*49cdfc7eSAndroid Build Coastguard Worker /**********************************************************
2*49cdfc7eSAndroid Build Coastguard Worker  * Copyright (c) 2000 Silicon Graphics, Inc.  All Rights Reserved.
3*49cdfc7eSAndroid Build Coastguard Worker  *
4*49cdfc7eSAndroid Build Coastguard Worker  * This program is free software; you can redistribute it and/or modify it
5*49cdfc7eSAndroid Build Coastguard Worker  * under the terms of version 2 of the GNU General Public License as
6*49cdfc7eSAndroid Build Coastguard Worker  * published by the Free Software Foundation.
7*49cdfc7eSAndroid Build Coastguard Worker  *
8*49cdfc7eSAndroid Build Coastguard Worker  * This program is distributed in the hope that it would be useful, but
9*49cdfc7eSAndroid Build Coastguard Worker  * WITHOUT ANY WARRANTY; without even the implied warranty of
10*49cdfc7eSAndroid Build Coastguard Worker  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11*49cdfc7eSAndroid Build Coastguard Worker  *
12*49cdfc7eSAndroid Build Coastguard Worker  * Further, this software is distributed without any warranty that it is
13*49cdfc7eSAndroid Build Coastguard Worker  * free of the rightful claim of any third person regarding infringement
14*49cdfc7eSAndroid Build Coastguard Worker  * or the like.  Any license provided herein, whether implied or
15*49cdfc7eSAndroid Build Coastguard Worker  * otherwise, applies only to this software file.  Patent licenses, if
16*49cdfc7eSAndroid Build Coastguard Worker  * any, provided herein do not apply to combinations of this program with
17*49cdfc7eSAndroid Build Coastguard Worker  * other software, or any other product whatsoever.
18*49cdfc7eSAndroid Build Coastguard Worker  *
19*49cdfc7eSAndroid Build Coastguard Worker  * You should have received a copy of the GNU General Public License along
20*49cdfc7eSAndroid Build Coastguard Worker  * with this program; if not, write the Free Software Foundation, Inc.,
21*49cdfc7eSAndroid Build Coastguard Worker  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22*49cdfc7eSAndroid Build Coastguard Worker  *
23*49cdfc7eSAndroid Build Coastguard Worker  * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
24*49cdfc7eSAndroid Build Coastguard Worker  * Mountain View, CA  94043, or:
25*49cdfc7eSAndroid Build Coastguard Worker  *
26*49cdfc7eSAndroid Build Coastguard Worker  * http://www.sgi.com
27*49cdfc7eSAndroid Build Coastguard Worker  *
28*49cdfc7eSAndroid Build Coastguard Worker  * For further information regarding this notice, see:
29*49cdfc7eSAndroid Build Coastguard Worker  *
30*49cdfc7eSAndroid Build Coastguard Worker  * http://oss.sgi.com/projects/GenInfo/NoticeExplan/
31*49cdfc7eSAndroid Build Coastguard Worker  *********************************************************/
32*49cdfc7eSAndroid Build Coastguard Worker 
33*49cdfc7eSAndroid Build Coastguard Worker /**********************************************************
34*49cdfc7eSAndroid Build Coastguard Worker  *
35*49cdfc7eSAndroid Build Coastguard Worker  *	 OS Testing - Silicon Graphics, Inc.
36*49cdfc7eSAndroid Build Coastguard Worker  *
37*49cdfc7eSAndroid Build Coastguard Worker  *	 FUNCTION NAME	  : tst_tmpdir, tst_rmdir
38*49cdfc7eSAndroid Build Coastguard Worker  *
39*49cdfc7eSAndroid Build Coastguard Worker  *	 FUNCTION TITLE	 : Create/remove a testing temp dir
40*49cdfc7eSAndroid Build Coastguard Worker  *
41*49cdfc7eSAndroid Build Coastguard Worker  *	 SYNOPSIS:
42*49cdfc7eSAndroid Build Coastguard Worker  *		void tst_tmpdir();
43*49cdfc7eSAndroid Build Coastguard Worker  *		void tst_rmdir();
44*49cdfc7eSAndroid Build Coastguard Worker  *
45*49cdfc7eSAndroid Build Coastguard Worker  *	 AUTHOR		 : Dave Fenner
46*49cdfc7eSAndroid Build Coastguard Worker  *
47*49cdfc7eSAndroid Build Coastguard Worker  *	 INITIAL RELEASE	: UNICOS 8.0
48*49cdfc7eSAndroid Build Coastguard Worker  *
49*49cdfc7eSAndroid Build Coastguard Worker  *	 DESCRIPTION
50*49cdfc7eSAndroid Build Coastguard Worker  *		tst_tmpdir() is used to create a unique, temporary testing
51*49cdfc7eSAndroid Build Coastguard Worker  *		directory, and make it the current working directory.
52*49cdfc7eSAndroid Build Coastguard Worker  *		tst_rmdir() is used to remove the directory created by
53*49cdfc7eSAndroid Build Coastguard Worker  *		tst_tmpdir().
54*49cdfc7eSAndroid Build Coastguard Worker  *
55*49cdfc7eSAndroid Build Coastguard Worker  *	 RETURN VALUE
56*49cdfc7eSAndroid Build Coastguard Worker  *		Neither tst_tmpdir() or tst_rmdir() has a return value.
57*49cdfc7eSAndroid Build Coastguard Worker  *
58*49cdfc7eSAndroid Build Coastguard Worker  *********************************************************/
59*49cdfc7eSAndroid Build Coastguard Worker #define _GNU_SOURCE
60*49cdfc7eSAndroid Build Coastguard Worker #include <sys/mman.h>
61*49cdfc7eSAndroid Build Coastguard Worker #include <sys/types.h>
62*49cdfc7eSAndroid Build Coastguard Worker #include <sys/stat.h>
63*49cdfc7eSAndroid Build Coastguard Worker #include <assert.h>
64*49cdfc7eSAndroid Build Coastguard Worker #include <errno.h>
65*49cdfc7eSAndroid Build Coastguard Worker #include <libgen.h>
66*49cdfc7eSAndroid Build Coastguard Worker #include <stdio.h>
67*49cdfc7eSAndroid Build Coastguard Worker #include <stdlib.h>
68*49cdfc7eSAndroid Build Coastguard Worker #include <string.h>
69*49cdfc7eSAndroid Build Coastguard Worker #include <unistd.h>
70*49cdfc7eSAndroid Build Coastguard Worker #include <dirent.h>
71*49cdfc7eSAndroid Build Coastguard Worker #include <fcntl.h>
72*49cdfc7eSAndroid Build Coastguard Worker 
73*49cdfc7eSAndroid Build Coastguard Worker #include "test.h"
74*49cdfc7eSAndroid Build Coastguard Worker #include "safe_macros.h"
75*49cdfc7eSAndroid Build Coastguard Worker #include "ltp_priv.h"
76*49cdfc7eSAndroid Build Coastguard Worker #include "lapi/futex.h"
77*49cdfc7eSAndroid Build Coastguard Worker 
78*49cdfc7eSAndroid Build Coastguard Worker /*
79*49cdfc7eSAndroid Build Coastguard Worker  * Define some useful macros.
80*49cdfc7eSAndroid Build Coastguard Worker  */
81*49cdfc7eSAndroid Build Coastguard Worker #define DIR_MODE	(S_IRWXU|S_IRWXG|S_IRWXO)
82*49cdfc7eSAndroid Build Coastguard Worker 
83*49cdfc7eSAndroid Build Coastguard Worker #ifndef PATH_MAX
84*49cdfc7eSAndroid Build Coastguard Worker #ifdef MAXPATHLEN
85*49cdfc7eSAndroid Build Coastguard Worker #define PATH_MAX	MAXPATHLEN
86*49cdfc7eSAndroid Build Coastguard Worker #else
87*49cdfc7eSAndroid Build Coastguard Worker #define PATH_MAX	1024
88*49cdfc7eSAndroid Build Coastguard Worker #endif
89*49cdfc7eSAndroid Build Coastguard Worker #endif
90*49cdfc7eSAndroid Build Coastguard Worker 
91*49cdfc7eSAndroid Build Coastguard Worker /*
92*49cdfc7eSAndroid Build Coastguard Worker  * Define global variables.
93*49cdfc7eSAndroid Build Coastguard Worker  */
94*49cdfc7eSAndroid Build Coastguard Worker extern char *TCID;		/* defined/initialized in main() */
95*49cdfc7eSAndroid Build Coastguard Worker static char *TESTDIR = NULL;	/* the directory created */
96*49cdfc7eSAndroid Build Coastguard Worker 
97*49cdfc7eSAndroid Build Coastguard Worker static char test_start_work_dir[PATH_MAX];
98*49cdfc7eSAndroid Build Coastguard Worker 
99*49cdfc7eSAndroid Build Coastguard Worker /* lib/tst_checkpoint.c */
100*49cdfc7eSAndroid Build Coastguard Worker extern futex_t *tst_futexes;
101*49cdfc7eSAndroid Build Coastguard Worker 
102*49cdfc7eSAndroid Build Coastguard Worker static int rmobj(const char *obj, char **errmsg);
103*49cdfc7eSAndroid Build Coastguard Worker 
tst_tmpdir_created(void)104*49cdfc7eSAndroid Build Coastguard Worker int tst_tmpdir_created(void)
105*49cdfc7eSAndroid Build Coastguard Worker {
106*49cdfc7eSAndroid Build Coastguard Worker 	return TESTDIR != NULL;
107*49cdfc7eSAndroid Build Coastguard Worker }
108*49cdfc7eSAndroid Build Coastguard Worker 
tst_get_tmpdir(void)109*49cdfc7eSAndroid Build Coastguard Worker char *tst_get_tmpdir(void)
110*49cdfc7eSAndroid Build Coastguard Worker {
111*49cdfc7eSAndroid Build Coastguard Worker 	char *ret = NULL;
112*49cdfc7eSAndroid Build Coastguard Worker 
113*49cdfc7eSAndroid Build Coastguard Worker 	if (TESTDIR == NULL) {
114*49cdfc7eSAndroid Build Coastguard Worker 		tst_brkm(TBROK, NULL, "you must call tst_tmpdir() first");
115*49cdfc7eSAndroid Build Coastguard Worker 		return NULL;
116*49cdfc7eSAndroid Build Coastguard Worker 	}
117*49cdfc7eSAndroid Build Coastguard Worker 
118*49cdfc7eSAndroid Build Coastguard Worker 	ret = strdup(TESTDIR);
119*49cdfc7eSAndroid Build Coastguard Worker 	if (!ret)
120*49cdfc7eSAndroid Build Coastguard Worker 		tst_brkm(TBROK, NULL, "strdup() failed");
121*49cdfc7eSAndroid Build Coastguard Worker 
122*49cdfc7eSAndroid Build Coastguard Worker 	return ret;
123*49cdfc7eSAndroid Build Coastguard Worker }
124*49cdfc7eSAndroid Build Coastguard Worker 
tst_get_tmpdir_root(void)125*49cdfc7eSAndroid Build Coastguard Worker const char *tst_get_tmpdir_root(void)
126*49cdfc7eSAndroid Build Coastguard Worker {
127*49cdfc7eSAndroid Build Coastguard Worker 	const char *env_tmpdir = getenv("TMPDIR");
128*49cdfc7eSAndroid Build Coastguard Worker 
129*49cdfc7eSAndroid Build Coastguard Worker 	if (!env_tmpdir)
130*49cdfc7eSAndroid Build Coastguard Worker 		env_tmpdir = TEMPDIR;
131*49cdfc7eSAndroid Build Coastguard Worker 
132*49cdfc7eSAndroid Build Coastguard Worker 	if (env_tmpdir[0] != '/') {
133*49cdfc7eSAndroid Build Coastguard Worker 		tst_brkm(TBROK, NULL, "You must specify an absolute "
134*49cdfc7eSAndroid Build Coastguard Worker 				"pathname for environment variable TMPDIR");
135*49cdfc7eSAndroid Build Coastguard Worker 		return NULL;
136*49cdfc7eSAndroid Build Coastguard Worker 	}
137*49cdfc7eSAndroid Build Coastguard Worker 	return env_tmpdir;
138*49cdfc7eSAndroid Build Coastguard Worker }
139*49cdfc7eSAndroid Build Coastguard Worker 
tst_get_startwd(void)140*49cdfc7eSAndroid Build Coastguard Worker const char *tst_get_startwd(void)
141*49cdfc7eSAndroid Build Coastguard Worker {
142*49cdfc7eSAndroid Build Coastguard Worker 	return test_start_work_dir;
143*49cdfc7eSAndroid Build Coastguard Worker }
144*49cdfc7eSAndroid Build Coastguard Worker 
purge_dir(const char * path,char ** errptr)145*49cdfc7eSAndroid Build Coastguard Worker static int purge_dir(const char *path, char **errptr)
146*49cdfc7eSAndroid Build Coastguard Worker {
147*49cdfc7eSAndroid Build Coastguard Worker 	int ret_val = 0;
148*49cdfc7eSAndroid Build Coastguard Worker 	DIR *dir;
149*49cdfc7eSAndroid Build Coastguard Worker 	struct dirent *dir_ent;
150*49cdfc7eSAndroid Build Coastguard Worker 	char dirobj[PATH_MAX];
151*49cdfc7eSAndroid Build Coastguard Worker 	static char err_msg[PATH_MAX + 1280];
152*49cdfc7eSAndroid Build Coastguard Worker 
153*49cdfc7eSAndroid Build Coastguard Worker 	/* Do NOT perform the request if the directory is "/" */
154*49cdfc7eSAndroid Build Coastguard Worker 	if (!strcmp(path, "/")) {
155*49cdfc7eSAndroid Build Coastguard Worker 		if (errptr) {
156*49cdfc7eSAndroid Build Coastguard Worker 			strcpy(err_msg, "Cannot purge system root directory");
157*49cdfc7eSAndroid Build Coastguard Worker 			*errptr = err_msg;
158*49cdfc7eSAndroid Build Coastguard Worker 		}
159*49cdfc7eSAndroid Build Coastguard Worker 
160*49cdfc7eSAndroid Build Coastguard Worker 		return -1;
161*49cdfc7eSAndroid Build Coastguard Worker 	}
162*49cdfc7eSAndroid Build Coastguard Worker 
163*49cdfc7eSAndroid Build Coastguard Worker 	errno = 0;
164*49cdfc7eSAndroid Build Coastguard Worker 
165*49cdfc7eSAndroid Build Coastguard Worker 	/* Open the directory to get access to what is in it */
166*49cdfc7eSAndroid Build Coastguard Worker 	if (!(dir = opendir(path))) {
167*49cdfc7eSAndroid Build Coastguard Worker 		if (errptr) {
168*49cdfc7eSAndroid Build Coastguard Worker 			sprintf(err_msg,
169*49cdfc7eSAndroid Build Coastguard Worker 				"Cannot open directory %s; errno=%d: %s",
170*49cdfc7eSAndroid Build Coastguard Worker 				path, errno, tst_strerrno(errno));
171*49cdfc7eSAndroid Build Coastguard Worker 			*errptr = err_msg;
172*49cdfc7eSAndroid Build Coastguard Worker 		}
173*49cdfc7eSAndroid Build Coastguard Worker 		return -1;
174*49cdfc7eSAndroid Build Coastguard Worker 	}
175*49cdfc7eSAndroid Build Coastguard Worker 
176*49cdfc7eSAndroid Build Coastguard Worker 	/* Loop through the entries in the directory, removing each one */
177*49cdfc7eSAndroid Build Coastguard Worker 	for (dir_ent = readdir(dir); dir_ent; dir_ent = readdir(dir)) {
178*49cdfc7eSAndroid Build Coastguard Worker 		/* Don't remove "." or ".." */
179*49cdfc7eSAndroid Build Coastguard Worker 		if (!strcmp(dir_ent->d_name, ".")
180*49cdfc7eSAndroid Build Coastguard Worker 		    || !strcmp(dir_ent->d_name, ".."))
181*49cdfc7eSAndroid Build Coastguard Worker 			continue;
182*49cdfc7eSAndroid Build Coastguard Worker 
183*49cdfc7eSAndroid Build Coastguard Worker 		/* Recursively remove the current entry */
184*49cdfc7eSAndroid Build Coastguard Worker 		sprintf(dirobj, "%s/%s", path, dir_ent->d_name);
185*49cdfc7eSAndroid Build Coastguard Worker 		if (rmobj(dirobj, errptr) != 0)
186*49cdfc7eSAndroid Build Coastguard Worker 			ret_val = -1;
187*49cdfc7eSAndroid Build Coastguard Worker 	}
188*49cdfc7eSAndroid Build Coastguard Worker 
189*49cdfc7eSAndroid Build Coastguard Worker 	closedir(dir);
190*49cdfc7eSAndroid Build Coastguard Worker 	return ret_val;
191*49cdfc7eSAndroid Build Coastguard Worker }
192*49cdfc7eSAndroid Build Coastguard Worker 
rmobj(const char * obj,char ** errmsg)193*49cdfc7eSAndroid Build Coastguard Worker static int rmobj(const char *obj, char **errmsg)
194*49cdfc7eSAndroid Build Coastguard Worker {
195*49cdfc7eSAndroid Build Coastguard Worker 	int ret_val = 0;
196*49cdfc7eSAndroid Build Coastguard Worker 	struct stat statbuf;
197*49cdfc7eSAndroid Build Coastguard Worker 	static char err_msg[PATH_MAX + 1280];
198*49cdfc7eSAndroid Build Coastguard Worker 	int fd;
199*49cdfc7eSAndroid Build Coastguard Worker 
200*49cdfc7eSAndroid Build Coastguard Worker 	fd = open(obj, O_DIRECTORY | O_NOFOLLOW);
201*49cdfc7eSAndroid Build Coastguard Worker 	if (fd >= 0) {
202*49cdfc7eSAndroid Build Coastguard Worker 		close(fd);
203*49cdfc7eSAndroid Build Coastguard Worker 		ret_val = purge_dir(obj, errmsg);
204*49cdfc7eSAndroid Build Coastguard Worker 
205*49cdfc7eSAndroid Build Coastguard Worker 		/* If there were problems removing an entry, don't attempt to
206*49cdfc7eSAndroid Build Coastguard Worker 		   remove the directory itself */
207*49cdfc7eSAndroid Build Coastguard Worker 		if (ret_val == -1)
208*49cdfc7eSAndroid Build Coastguard Worker 			return -1;
209*49cdfc7eSAndroid Build Coastguard Worker 
210*49cdfc7eSAndroid Build Coastguard Worker 		/* Get the link count, now that all the entries have been removed */
211*49cdfc7eSAndroid Build Coastguard Worker 		if (lstat(obj, &statbuf) < 0) {
212*49cdfc7eSAndroid Build Coastguard Worker 			if (errmsg != NULL) {
213*49cdfc7eSAndroid Build Coastguard Worker 				sprintf(err_msg,
214*49cdfc7eSAndroid Build Coastguard Worker 					"lstat(%s) failed; errno=%d: %s", obj,
215*49cdfc7eSAndroid Build Coastguard Worker 					errno, tst_strerrno(errno));
216*49cdfc7eSAndroid Build Coastguard Worker 				*errmsg = err_msg;
217*49cdfc7eSAndroid Build Coastguard Worker 			}
218*49cdfc7eSAndroid Build Coastguard Worker 			return -1;
219*49cdfc7eSAndroid Build Coastguard Worker 		}
220*49cdfc7eSAndroid Build Coastguard Worker 
221*49cdfc7eSAndroid Build Coastguard Worker 		/* Remove the directory itself */
222*49cdfc7eSAndroid Build Coastguard Worker 		if (statbuf.st_nlink >= 3) {
223*49cdfc7eSAndroid Build Coastguard Worker 			/* The directory is linked; unlink() must be used */
224*49cdfc7eSAndroid Build Coastguard Worker 			if (unlink(obj) < 0) {
225*49cdfc7eSAndroid Build Coastguard Worker 				if (errmsg != NULL) {
226*49cdfc7eSAndroid Build Coastguard Worker 					sprintf(err_msg,
227*49cdfc7eSAndroid Build Coastguard Worker 						"unlink(%s) failed; errno=%d: %s",
228*49cdfc7eSAndroid Build Coastguard Worker 						obj, errno, tst_strerrno(errno));
229*49cdfc7eSAndroid Build Coastguard Worker 					*errmsg = err_msg;
230*49cdfc7eSAndroid Build Coastguard Worker 				}
231*49cdfc7eSAndroid Build Coastguard Worker 				return -1;
232*49cdfc7eSAndroid Build Coastguard Worker 			}
233*49cdfc7eSAndroid Build Coastguard Worker 		} else {
234*49cdfc7eSAndroid Build Coastguard Worker 			/* The directory is not linked; remove() can be used */
235*49cdfc7eSAndroid Build Coastguard Worker 			if (remove(obj) < 0) {
236*49cdfc7eSAndroid Build Coastguard Worker 				if (errmsg != NULL) {
237*49cdfc7eSAndroid Build Coastguard Worker 					sprintf(err_msg,
238*49cdfc7eSAndroid Build Coastguard Worker 						"remove(%s) failed; errno=%d: %s",
239*49cdfc7eSAndroid Build Coastguard Worker 						obj, errno, tst_strerrno(errno));
240*49cdfc7eSAndroid Build Coastguard Worker 					*errmsg = err_msg;
241*49cdfc7eSAndroid Build Coastguard Worker 				}
242*49cdfc7eSAndroid Build Coastguard Worker 				return -1;
243*49cdfc7eSAndroid Build Coastguard Worker 			}
244*49cdfc7eSAndroid Build Coastguard Worker 		}
245*49cdfc7eSAndroid Build Coastguard Worker 	} else {
246*49cdfc7eSAndroid Build Coastguard Worker 		if (unlink(obj) < 0) {
247*49cdfc7eSAndroid Build Coastguard Worker 			if (errmsg != NULL) {
248*49cdfc7eSAndroid Build Coastguard Worker 				sprintf(err_msg,
249*49cdfc7eSAndroid Build Coastguard Worker 					"unlink(%s) failed; errno=%d: %s", obj,
250*49cdfc7eSAndroid Build Coastguard Worker 					errno, tst_strerrno(errno));
251*49cdfc7eSAndroid Build Coastguard Worker 				*errmsg = err_msg;
252*49cdfc7eSAndroid Build Coastguard Worker 			}
253*49cdfc7eSAndroid Build Coastguard Worker 			return -1;
254*49cdfc7eSAndroid Build Coastguard Worker 		}
255*49cdfc7eSAndroid Build Coastguard Worker 	}
256*49cdfc7eSAndroid Build Coastguard Worker 
257*49cdfc7eSAndroid Build Coastguard Worker 	return 0;
258*49cdfc7eSAndroid Build Coastguard Worker }
259*49cdfc7eSAndroid Build Coastguard Worker 
tst_tmpdir(void)260*49cdfc7eSAndroid Build Coastguard Worker void tst_tmpdir(void)
261*49cdfc7eSAndroid Build Coastguard Worker {
262*49cdfc7eSAndroid Build Coastguard Worker 	char template[PATH_MAX];
263*49cdfc7eSAndroid Build Coastguard Worker 	const char *env_tmpdir;
264*49cdfc7eSAndroid Build Coastguard Worker 	char *errmsg;
265*49cdfc7eSAndroid Build Coastguard Worker 
266*49cdfc7eSAndroid Build Coastguard Worker 	/*
267*49cdfc7eSAndroid Build Coastguard Worker 	 * Create a template for the temporary directory.  Use the
268*49cdfc7eSAndroid Build Coastguard Worker 	 * environment variable TMPDIR if it is available, otherwise
269*49cdfc7eSAndroid Build Coastguard Worker 	 * use our default TEMPDIR.
270*49cdfc7eSAndroid Build Coastguard Worker 	 */
271*49cdfc7eSAndroid Build Coastguard Worker 	env_tmpdir = tst_get_tmpdir_root();
272*49cdfc7eSAndroid Build Coastguard Worker 	snprintf(template, PATH_MAX, "%s/LTP_%.3sXXXXXX", env_tmpdir, TCID);
273*49cdfc7eSAndroid Build Coastguard Worker 
274*49cdfc7eSAndroid Build Coastguard Worker 	/* Make the temporary directory in one shot using mkdtemp. */
275*49cdfc7eSAndroid Build Coastguard Worker 	if (mkdtemp(template) == NULL) {
276*49cdfc7eSAndroid Build Coastguard Worker 		tst_brkm(TBROK | TERRNO, NULL,
277*49cdfc7eSAndroid Build Coastguard Worker 			 "%s: mkdtemp(%s) failed", __func__, template);
278*49cdfc7eSAndroid Build Coastguard Worker 		return;
279*49cdfc7eSAndroid Build Coastguard Worker 	}
280*49cdfc7eSAndroid Build Coastguard Worker 
281*49cdfc7eSAndroid Build Coastguard Worker 	if ((TESTDIR = strdup(template)) == NULL) {
282*49cdfc7eSAndroid Build Coastguard Worker 		tst_brkm(TBROK | TERRNO, NULL,
283*49cdfc7eSAndroid Build Coastguard Worker 			 "%s: strdup(%s) failed", __func__, template);
284*49cdfc7eSAndroid Build Coastguard Worker 		return;
285*49cdfc7eSAndroid Build Coastguard Worker 	}
286*49cdfc7eSAndroid Build Coastguard Worker 
287*49cdfc7eSAndroid Build Coastguard Worker 	SAFE_CHOWN(NULL, TESTDIR, -1, getgid());
288*49cdfc7eSAndroid Build Coastguard Worker 
289*49cdfc7eSAndroid Build Coastguard Worker 	SAFE_CHMOD(NULL, TESTDIR, DIR_MODE);
290*49cdfc7eSAndroid Build Coastguard Worker 
291*49cdfc7eSAndroid Build Coastguard Worker 	if (getcwd(test_start_work_dir, sizeof(test_start_work_dir)) == NULL) {
292*49cdfc7eSAndroid Build Coastguard Worker 		tst_resm(TINFO, "Failed to record test working dir");
293*49cdfc7eSAndroid Build Coastguard Worker 		test_start_work_dir[0] = '\0';
294*49cdfc7eSAndroid Build Coastguard Worker 	}
295*49cdfc7eSAndroid Build Coastguard Worker 
296*49cdfc7eSAndroid Build Coastguard Worker 	/*
297*49cdfc7eSAndroid Build Coastguard Worker 	 * Change to the temporary directory.  If the chdir() fails, issue
298*49cdfc7eSAndroid Build Coastguard Worker 	 * TBROK messages for all test cases, attempt to remove the
299*49cdfc7eSAndroid Build Coastguard Worker 	 * directory (if it was created), and exit.  If the removal also
300*49cdfc7eSAndroid Build Coastguard Worker 	 * fails, also issue a TWARN message.
301*49cdfc7eSAndroid Build Coastguard Worker 	 */
302*49cdfc7eSAndroid Build Coastguard Worker 	if (chdir(TESTDIR) == -1) {
303*49cdfc7eSAndroid Build Coastguard Worker 		tst_resm(TERRNO, "%s: chdir(%s) failed", __func__, TESTDIR);
304*49cdfc7eSAndroid Build Coastguard Worker 
305*49cdfc7eSAndroid Build Coastguard Worker 		/* Try to remove the directory */
306*49cdfc7eSAndroid Build Coastguard Worker 		if (rmobj(TESTDIR, &errmsg) == -1) {
307*49cdfc7eSAndroid Build Coastguard Worker 			tst_resm(TWARN, "%s: rmobj(%s) failed: %s",
308*49cdfc7eSAndroid Build Coastguard Worker 				 __func__, TESTDIR, errmsg);
309*49cdfc7eSAndroid Build Coastguard Worker 		}
310*49cdfc7eSAndroid Build Coastguard Worker 
311*49cdfc7eSAndroid Build Coastguard Worker 		tst_exit();
312*49cdfc7eSAndroid Build Coastguard Worker 	}
313*49cdfc7eSAndroid Build Coastguard Worker }
314*49cdfc7eSAndroid Build Coastguard Worker 
tst_rmdir(void)315*49cdfc7eSAndroid Build Coastguard Worker void tst_rmdir(void)
316*49cdfc7eSAndroid Build Coastguard Worker {
317*49cdfc7eSAndroid Build Coastguard Worker 	char *errmsg;
318*49cdfc7eSAndroid Build Coastguard Worker 
319*49cdfc7eSAndroid Build Coastguard Worker 	/*
320*49cdfc7eSAndroid Build Coastguard Worker 	 * Check that TESTDIR is not NULL.
321*49cdfc7eSAndroid Build Coastguard Worker 	 */
322*49cdfc7eSAndroid Build Coastguard Worker 	if (TESTDIR == NULL) {
323*49cdfc7eSAndroid Build Coastguard Worker 		tst_resm(TWARN,
324*49cdfc7eSAndroid Build Coastguard Worker 			 "%s: TESTDIR was NULL; no removal attempted",
325*49cdfc7eSAndroid Build Coastguard Worker 			 __func__);
326*49cdfc7eSAndroid Build Coastguard Worker 		return;
327*49cdfc7eSAndroid Build Coastguard Worker 	}
328*49cdfc7eSAndroid Build Coastguard Worker 
329*49cdfc7eSAndroid Build Coastguard Worker 	/*
330*49cdfc7eSAndroid Build Coastguard Worker 	 * Unmap the backend file.
331*49cdfc7eSAndroid Build Coastguard Worker 	 * This is needed to overcome the NFS "silly rename" feature.
332*49cdfc7eSAndroid Build Coastguard Worker 	 */
333*49cdfc7eSAndroid Build Coastguard Worker 	if (tst_futexes) {
334*49cdfc7eSAndroid Build Coastguard Worker 		msync((void *)tst_futexes, getpagesize(), MS_SYNC);
335*49cdfc7eSAndroid Build Coastguard Worker 		munmap((void *)tst_futexes, getpagesize());
336*49cdfc7eSAndroid Build Coastguard Worker 	}
337*49cdfc7eSAndroid Build Coastguard Worker 
338*49cdfc7eSAndroid Build Coastguard Worker 	/*
339*49cdfc7eSAndroid Build Coastguard Worker 	 * Attempt to remove the "TESTDIR" directory, using rmobj().
340*49cdfc7eSAndroid Build Coastguard Worker 	 */
341*49cdfc7eSAndroid Build Coastguard Worker 	if (rmobj(TESTDIR, &errmsg) == -1) {
342*49cdfc7eSAndroid Build Coastguard Worker 		tst_resm(TWARN, "%s: rmobj(%s) failed: %s",
343*49cdfc7eSAndroid Build Coastguard Worker 			 __func__, TESTDIR, errmsg);
344*49cdfc7eSAndroid Build Coastguard Worker 	}
345*49cdfc7eSAndroid Build Coastguard Worker }
346*49cdfc7eSAndroid Build Coastguard Worker 
tst_purge_dir(const char * path)347*49cdfc7eSAndroid Build Coastguard Worker void tst_purge_dir(const char *path)
348*49cdfc7eSAndroid Build Coastguard Worker {
349*49cdfc7eSAndroid Build Coastguard Worker 	char *err;
350*49cdfc7eSAndroid Build Coastguard Worker 
351*49cdfc7eSAndroid Build Coastguard Worker 	if (purge_dir(path, &err))
352*49cdfc7eSAndroid Build Coastguard Worker 		tst_brkm(TBROK, NULL, "%s: %s", __func__, err);
353*49cdfc7eSAndroid Build Coastguard Worker }
354