mkstemp() for WIN32

とある、ライブラリを使用中にmkstemp()のwin32版が無いことに気付いた。
まぁ、即席な形で名前生成とかちょっといい加減だけどこんな感じの実装はドウなのでしょう?水曜どうでしょう
もちライセンスはNYSLでんがな!

  • dkc_strcpyおよびdkc_strcpy2の実装はdkutil_cから引っこ抜いてきました。
  • もちろん
    http://www.linux.or.jp/JM/html/LDP_man-pages/man3/mkstemp.3.html
    のような仕様に準拠していません。(爆)
  • テンポラリファイルなのにcloseしてもファイルは残ります。
  • 6文字でテンポラリファイルを作りません。
  • その他、改変点などは調査中

/**
mkstemp() for win32
licence is NYSL
*/

#include <stdio.h>
#include <io.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <windows.h>


#if defined(WIN32) || defined(_MSC_VER)
# define MKSTEMP_OPEN_FLAGS (_O_RDWR | _O_CREAT | _O_EXCL | _O_BINARY)
#else
# define MKSTEMP_OPEN_FLAGS (O_RDWR | O_CREAT | O_EXCL | O_BINARY)
#endif

#define edk_FAILED -1
#define edk_SUCCEEDED 0
static int dkc_strcat(char *dest,size_t destsize,size_t destlen,
const char *src,size_t srclen)
{
//destlen + srclen + NULL文字
if(destsize < destlen + srclen + 1) return edk_FAILED;
strncat(dest,src,srclen);
return edk_SUCCEEDED;
}

static int dkc_strcat2(char *dest,size_t destsize,const char *src){
return dkc_strcat(dest,destsize,strlen(dest),src,strlen(src));
}

int mkstemp (const char *filename)
{
#ifdef HAVE_MKSTEMP
return mkstemp (tmpl);
#else
int fd = -1;
unsigned int ti = GetTickCount();
size_t count;
char time_filename[MAX_PATH + 1];
char count_str[4];

if(0 > _snprintf(time_filename,MAX_PATH,"%s_%08x",filename,ti))
{
return -1;
}
for (count = 0; count < 64;count++)
{

fd = open (time_filename,MKSTEMP_OPEN_FLAGS , 0600);

if (fd >= 0)
return fd;
else if (errno != EEXIST)
return -1;

if(0 > _snprintf(count_str,3,"_%d",count))
{
return -1;
}
if(0 != dkc_strcat2(time_filename,MAX_PATH,count_str))
{
return -1;
}

}
//これでエラーするのはどうなってしまっているんだ!
errno = EEXIST;
return -1;
#endif
}
int main(){
int h = mkstemp("temp");
if(h < 0) return -1;

char *data="test succeeded.";
char rd[64];
size_t dl = strlen(data);

write(h,data,dl);
lseek(h,SEEK_SET,0);
read(h,rd,dl);
rd[dl] = '\0';

printf("%s",rd);
close(h);

return 0;
}