xref: /plan9/sys/src/libstdio/tmpfile.c (revision 3e12c5d1bb89fc02707907988834ef147769ddaf)
1*3e12c5d1SDavid du Colombier /*
2*3e12c5d1SDavid du Colombier  * pANS stdio -- tmpfile
3*3e12c5d1SDavid du Colombier  *
4*3e12c5d1SDavid du Colombier  * Bug: contains a critical section.  Two executions by the same
5*3e12c5d1SDavid du Colombier  * user could interleave as follows, both yielding the same file:
6*3e12c5d1SDavid du Colombier  *	access fails
7*3e12c5d1SDavid du Colombier  *			access fails
8*3e12c5d1SDavid du Colombier  *	fopen succeeds
9*3e12c5d1SDavid du Colombier  *			fopen succeeds
10*3e12c5d1SDavid du Colombier  *	unlink succeeds
11*3e12c5d1SDavid du Colombier  *			unlink fails
12*3e12c5d1SDavid du Colombier  * As I read the pANS, this can't reasonably use tmpnam to generate
13*3e12c5d1SDavid du Colombier  * the name, so that code is duplicated.
14*3e12c5d1SDavid du Colombier  */
15*3e12c5d1SDavid du Colombier #include "iolib.h"
16*3e12c5d1SDavid du Colombier 
17*3e12c5d1SDavid du Colombier static char tmpsmade[FOPEN_MAX][L_tmpnam+1];
18*3e12c5d1SDavid du Colombier static int ntmps = 0;
19*3e12c5d1SDavid du Colombier 
20*3e12c5d1SDavid du Colombier static void rmtmps(void);
21*3e12c5d1SDavid du Colombier 
tmpfile(void)22*3e12c5d1SDavid du Colombier FILE *tmpfile(void){
23*3e12c5d1SDavid du Colombier 	FILE *f;
24*3e12c5d1SDavid du Colombier 	static char name[]="/tmp/tf0000000000000";
25*3e12c5d1SDavid du Colombier 	char *p;
26*3e12c5d1SDavid du Colombier 	while(access(name, 0)==0){
27*3e12c5d1SDavid du Colombier 		p=name+7;
28*3e12c5d1SDavid du Colombier 		while(*p=='9') *p++='0';
29*3e12c5d1SDavid du Colombier 		if(*p=='\0') return NULL;
30*3e12c5d1SDavid du Colombier 		++*p;
31*3e12c5d1SDavid du Colombier 	}
32*3e12c5d1SDavid du Colombier 	f=fopen(name, "wb+");
33*3e12c5d1SDavid du Colombier 	if(f && ntmps<FOPEN_MAX){
34*3e12c5d1SDavid du Colombier 		if(ntmps==0)
35*3e12c5d1SDavid du Colombier 			atexit(rmtmps);
36*3e12c5d1SDavid du Colombier 		strcpy(tmpsmade[ntmps++], name);
37*3e12c5d1SDavid du Colombier 	}
38*3e12c5d1SDavid du Colombier 	return f;
39*3e12c5d1SDavid du Colombier }
40*3e12c5d1SDavid du Colombier 
41*3e12c5d1SDavid du Colombier static void
rmtmps(void)42*3e12c5d1SDavid du Colombier rmtmps(void)
43*3e12c5d1SDavid du Colombier {
44*3e12c5d1SDavid du Colombier 	int i;
45*3e12c5d1SDavid du Colombier 
46*3e12c5d1SDavid du Colombier 	for(i=0; i<ntmps; i++)
47*3e12c5d1SDavid du Colombier 		remove(tmpsmade[i]);
48*3e12c5d1SDavid du Colombier }
49