X-Git-Url: https://pd.if.org/git/?a=blobdiff_plain;f=platform%2Fwin32%2Ffunctions%2Fstdio%2Ftmpfile.c;fp=platform%2Fwin32%2Ffunctions%2Fstdio%2Ftmpfile.c;h=f3292349f08a9cbb3eb29832c73c1bc892faabf9;hb=d8928b5f31bbdac23f9ec296ef28b4b10efa31d5;hp=0000000000000000000000000000000000000000;hpb=219271fd548949abce8bd75c34dd42e519418fc4;p=pdclib diff --git a/platform/win32/functions/stdio/tmpfile.c b/platform/win32/functions/stdio/tmpfile.c new file mode 100644 index 0000000..f329234 --- /dev/null +++ b/platform/win32/functions/stdio/tmpfile.c @@ -0,0 +1,89 @@ +/* $Id$ */ + +/* tmpfile( void ) + + This file is part of the Public Domain C Library (PDCLib). + Permission is granted to use, modify, and / or redistribute at will. +*/ + +#include + +#ifndef REGTEST +#include +#include <_PDCLIB_glue.h> +#include +#include + +static char tmpname_prefix[4] = {0, 0, 0, 0}; + +extern void _PDCLIB_w32errno( void ); +struct _PDCLIB_file_t * tmpfile( void ) +{ + if(!tmpname_prefix[0]) { + char namebuf[MAX_PATH+1]; + DWORD res = GetModuleFileNameA(NULL, namebuf, MAX_PATH+1); + if(res) { + char * basename = strrchr(namebuf, '\\'); + if(basename) { + basename += 1; + } else basename = namebuf; + + char* dot = strchr(basename, '.'); + if(dot) *dot = 0; + + strncpy(tmpname_prefix, basename, 3); + } else { + // Error getting file name + strcpy(tmpname_prefix, "PDU"); + } + } + + char tmpdir[MAX_PATH + 1]; + DWORD rv = GetTempPathA(MAX_PATH + 1, tmpdir); + if(rv == 0) { + _PDCLIB_w32errno(); + return NULL; + } + + char name[MAX_PATH + 1]; + rv = GetTempFileNameA(tmpdir, tmpname_prefix, 0, name); + if(rv == 0) { + _PDCLIB_w32errno(); + return NULL; + } + + /* OPEN_EXISTING as CreateTempFileName creates the file then closes the + handle to it (to avoid race conditions as associated with e.g. tmpnam) + */ + HANDLE fd = CreateFileA(name, GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_DELETE, NULL, OPEN_EXISTING, + FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_TEMPORARY, NULL); + + if(fd == INVALID_HANDLE_VALUE) { + _PDCLIB_w32errno(); + return NULL; + } + + /* Set the file to delete on close */ + DeleteFile(name); + + FILE* fs = _PDCLIB_fdopen(fd, _PDCLIB_FWRITE | _PDCLIB_FRW, name); + if(!fs) { + CloseHandle(fd); + } + return fs; +} + +#endif + +#ifdef TEST +#include <_PDCLIB_test.h> +#include + +int main( void ) +{ + return TEST_RESULTS; +} + +#endif +