3 This file is part of the Public Domain C Library (PDCLib).
4 Permission is granted to use, modify, and / or redistribute at will.
15 #include <_PDCLIB_glue.h>
17 #include <sys/types.h>
22 extern struct _PDCLIB_file_t * _PDCLIB_filelist;
24 /* This is an example implementation of tmpfile() fit for use with POSIX
27 struct _PDCLIB_file_t * tmpfile( void )
30 /* This is the chosen way to get high-quality randomness. Replace as
33 FILE * randomsource = fopen( "/proc/sys/kernel/random/uuid", "rb" );
34 char filename[ L_tmpnam ];
36 if ( randomsource == NULL )
42 /* Get a filename candidate. What constitutes a valid filename and
43 where temporary files are usually located is platform-dependent,
44 which is one reason why this function is located in the platform
45 overlay. The other reason is that a *good* implementation should
46 use high-quality randomness instead of a pseudo-random sequence to
47 generate the filename candidate, which is *also* platform-dependent.
50 fscanf( randomsource, "%u", &random );
51 sprintf( filename, "/tmp/%u.tmp", random );
52 /* Check if file of this name exists. Note that fopen() is a very weak
53 check, which does not take e.g. access permissions into account
54 (file might exist but not readable). Replace with something more
57 fd = open( filename, O_CREAT | O_EXCL | O_RDWR, S_IRUSR | S_IWUSR );
64 fclose( randomsource );
66 if ( ( rc = calloc( 1, sizeof( struct _PDCLIB_file_t ) + _PDCLIB_UNGETCBUFSIZE + L_tmpnam + BUFSIZ ) ) == NULL )
68 /* No memory to set up FILE structure */
72 rc->status = _PDCLIB_filemode( "wb+" ) | _IOLBF | _PDCLIB_DELONCLOSE;
74 rc->ungetbuf = (unsigned char *)rc + sizeof( struct _PDCLIB_file_t );
75 rc->filename = (char *)rc->ungetbuf + _PDCLIB_UNGETCBUFSIZE;
76 rc->buffer = rc->filename + L_tmpnam;
77 strcpy( rc->filename, filename );
81 rc->next = _PDCLIB_filelist;
82 _PDCLIB_filelist = rc;
89 #include <_PDCLIB_test.h>
96 char filename[ L_tmpnam ];
99 TESTCASE( ( fh = tmpfile() ) != NULL );
100 TESTCASE( fputc( 'x', fh ) == 'x' );
101 /* Checking that file is actually there */
102 TESTCASE_NOREG( strcpy( filename, fh->filename ) == filename );
103 TESTCASE_NOREG( ( fhtest = fopen( filename, "r" ) ) != NULL );
104 TESTCASE_NOREG( fclose( fhtest ) == 0 );
105 /* Closing tmpfile */
106 TESTCASE( fclose( fh ) == 0 );
107 /* Checking that file was deleted */
108 TESTCASE_NOREG( fopen( filename, "r" ) == NULL );