summaryrefslogtreecommitdiff
path: root/src/tet3/tcclib/mktmpdir.c
blob: 30bb6992b80e7e01675cb7987a82c8493a542722 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
/*
 *	SCCS: @(#)mktmpdir.c	1.3 (98/09/01)
 *
 *	UniSoft Ltd., London, England
 *
 * (C) Copyright 1996 X/Open Company Limited
 *
 * All rights reserved.  No part of this source code may be reproduced,
 * stored in a retrieval system, or transmitted, in any form or by any
 * means, electronic, mechanical, photocopying, recording or otherwise,
 * except as stated in the end-user licence agreement, without the prior
 * permission of the copyright owners.
 * A copy of the end-user licence agreement is contained in the file
 * Licence which accompanies this distribution.
 * 
 * X/Open and the 'X' symbol are trademarks of X/Open Company Limited in
 * the UK and other countries.
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

/************************************************************************

SCCS:   	@(#)mktmpdir.c	1.3 98/09/01 TETware release 3.3
NAME:		mktmpdir.c
PRODUCT:	TETware
AUTHOR:		Andrew Dingwall, UniSoft Ltd.
DATE CREATED:	October 1996

DESCRIPTION:
	tcc action function - make a unique temporary directory

	this function moved from tccd/stcc.c to here

MODIFICATIONS:
	Andrew Dingwall, UniSoft Ltd., March 1998
	Added an extra salt character to the unique directory name so as
	to enable more instances of a test case to execute in parallel.

	Andrew Dingwall, UniSoft Ltd., July 1998
	Added support for shared API libraries.

	Aaron Plattner, April 2010
	Fixed warnings when compiled with GCC's -Wall option.

************************************************************************/

#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "dtmac.h"
#include "dtmsg.h"
#include "error.h"
#include "globals.h"
#include "ltoa.h"
#include "dtetlib.h"
#include "tcclib.h"

/* mode for created directory */
#define MODEANY		((mode_t) (S_IRWXU | S_IRWXG | S_IRWXO))

/* static function declarations */
static int tcf_mktd2 PROTOLIST((char *));


/*
**	tcf_mktmpdir() - make a unique temporary directory
**
**	return ER_OK if successful or other ER_* code on error
**
**	if successful, the name of the temporary directory is returned
**	indirectly through *subdp
*/

int tcf_mktmpdir(dir, subdp)
char *dir, **subdp;
{
	register int needlen, rc;
	char salt1, salt2;
	char pidstr[LNUMSZ];
	static char *subdir;
	static int sdlen;
	extern int tet_mypid;

	/* do a sanity check on the input arguments */
	ASSERT(dir && *dir);

	/* format the pid string */
	sprintf(pidstr, "%05u", tet_mypid);

	/* get a buffer for the tmp dir name */
	needlen = strlen(dir) + strlen(pidstr) + 4;
	if (BUFCHK(&subdir, &sdlen, needlen) < 0)
		return(ER_ERR);

	/* try to make the directory a few times */
	for (salt1 = 'a'; salt1 <= 'z'; salt1++)
		for (salt2 = 'a'; salt2 <= 'z'; salt2++) {
			sprintf(subdir, "%s/%s%c%c",
				dir, pidstr, salt1, salt2);
			if ((rc = tcf_mktd2(subdir)) < 0)
				return(rc);
			else if (rc > 0) {
				*subdp = subdir;
				return(ER_OK);
			}
		}

	/* here if we are out of suffix letters */
	error(0, "out of tmp subdir names in", dir);
	return(ER_ERR);
}

/*
**	tcf_mktd2() - extend the tcf_mktmpdir() processing
**
**	try to make the specified directory
**
**	return	1 if successful
**		0 to try the next tmpdir name
**		-ve error code on error
*/

static int tcf_mktd2(subdir)
char *subdir;
{
	int errsave, rc;

	TRACE2(Ttcclib, 6, "tcf_mktmpdir(): try \"%s\"", subdir);

	/* attempt to make the directory */
	if (tet_mkdir(subdir, MODEANY) < 0) {
		if (errno == EEXIST)
			return(0);
		else {
			errsave = errno;
			if ((rc = tet_maperrno(errsave)) == ER_ERR)
				error(errsave, "can't make directory", subdir);
			errno = errsave;
			return(rc);
		}
	}

	/* here if the directory could be created successfully */
	TRACE2(Ttcclib, 4, "tcf_mktmpdir(): return \"%s\"", subdir);
	return(1);
}