/* tmpfile.c: create a temporary file that will be deleted when exit()
   is called.
   Written by Eric R. Smith and placed in the public domain.
*/

#include <stdio.h>
#include <stdlib.h>

extern int __mint;

static void delete_tmpfiles __PROTO((void));

typedef struct {
	char	*name;
	FILE	*fp;
} FILE_RECORD;

static FILE_RECORD	*file_to_delete;
static int		numtmps = -1;

static void
delete_tmpfiles()
{
	int i;

	for (i = 0; i <= numtmps; i++)
	{
		fclose(file_to_delete[i].fp);
		remove(file_to_delete[i].name);
	}
}

FILE *tmpfile()
{
	char *junknam;
	FILE *junkfil;

	if ( ((junknam = tmpnam(NULL)) == NULL) || 
		((junkfil = fopen(junknam, "w+b")) == NULL ))
	{
		if(junknam)
			free(junknam);
		return NULL;
	}

/* in MiNT 0.9 and above, we can often unlink a file and continue to use
 * it; some file systems may return EACCDN for unlinking an open file,
 * in which case we use the old method of unlinking the file at exit
 */
	if (__mint >= 9) {
		if (remove(junknam) == 0)
			return junkfil;
	}

	if((++numtmps) == 0)
		file_to_delete = (FILE_RECORD *)malloc((size_t)sizeof(FILE_RECORD));
	else
		file_to_delete = (FILE_RECORD *)realloc(file_to_delete,
					(size_t)((numtmps+1) * sizeof(FILE_RECORD)));
	if(file_to_delete == (FILE_RECORD *)NULL)
	{
		fclose(junkfil);
		remove(junknam);
		free(junknam);
		numtmps -= 1;
		return NULL;	/* outa mem */
	}
/* install this in the list of temporary files to be deleted at exit */
	file_to_delete[numtmps].name = junknam;
	file_to_delete[numtmps].fp   = junkfil;

/* if this is the first, install the delete routine */
	if (numtmps == 0)
		if(atexit(delete_tmpfiles) != 0)
		{	/* atexit failed -- cleanup */
			delete_tmpfiles();
			numtmps = -1;
			free(file_to_delete[0].name);
			free(file_to_delete);
			return NULL;
		}
	return junkfil;
}
