/** * @file TmpFile.c * @brief テンポラリディレクトリにテンポラリファイルを作成. * @author tenk* * @note * Public Domain Software */ #include "TmpFile.h" #include <stdlib.h> #include <stdio.h> #include <string.h> #include <assert.h> // このファイル内限定で、基本的な名前も辻褄あわせ. #ifdef _WIN32 #include <windows.h> #include <tchar.h> #include <io.h> #include <tchar.h> #define DISK_MAX_PATH _MAX_PATH #define uint64_t unsigned __int64 #else // win以外ではcharのみ. #include <stddef.h> #include <unistd.h> #define _T(x) x #define TCHAR char #define _tcslen(s) strlen(s) #define _tcsncpy strncpy #define _tsnprintf snprintf #define DISK_MAX_PATH 4096 #endif //=========================================================================== // テンポラリ・ファイル. //=========================================================================== #if defined _WIN32 || defined MSDOS /** 環境変数tmp か temp があればその内容を、なければ"."を入れて返す. * @return 0:tmp,tempが無かった. 1:あった. */ int TmpFile_getTmpEnv(TCHAR tmpEnv[], size_t size) { int f = 1; const TCHAR* p = _tgetenv(_T("TMP")); assert(tmpEnv && size > 0); if (p == NULL) { p = _tgetenv(_T("TEMP")); if (p == NULL) { p = _T("."); f = 0; } } _tcsncpy(tmpEnv, p, size-1); tmpEnv[size-1] = 0; return f; } #else /** /tmp を返す. * @return 1 */ int TmpFile_getTmpEnv(TCHAR tmpEnv[], size_t size) { _tcsncpy(tmpEnv, "/tmp", size-1); tmpEnv[size-1] = 0; return 1; } #endif /** テンポラリファイル作成. 成功するとhandleを返す. */ #ifdef _WIN32 //static HANDLE TmpFile_open(TCHAR name[], size_t size, const TCHAR* prefix) //{ // if (TmpFile_openName(name, size, prefix)) { // return CreateFile(name, GENERIC_WRITE, 0, CREATE_ALWAYS,FILE_ATTRIBUTE_TEMPORARY, 0); // } //} #else static int TmpFile_open(TCHAR name[], size_t size, const TCHAR* prefix) { TCHAR nm[ DISK_MAX_PATH + 2 ]; int hdl; assert(name != 0 && size > 0 && prefix != 0); _tsnprintf( nm, DISK_MAX_PATH, _T("/tmp/%s.XXXXXX"), prefix ); hdl = mkstemp( nm ); if (hdl >= 0) { if (_tcslen(nm) < size) { _tcsncpy(name, nm, size-1); name[size-1] = 0; } else { // ファイル名をちゃんと返せないなら失敗扱い. close(hdl); remove(nm); hdl = -1; } } return hdl; } #endif /** テンポラリファイル名作成. 成功するとnameを返し、失敗だとNULL. * prefix はwindowsだと3バイト. * 成功すると、テンポラリディレクトリにその名前のファイルができているので注意.(close済) * (つまり自分で削除しないと駄目) */ TCHAR* TmpFile_make(TCHAR name[], size_t size, const TCHAR* prefix) { #ifdef _WIN32 TCHAR tmpd[ DISK_MAX_PATH + 2]; TCHAR nm[ DISK_MAX_PATH + 2 ]; int val; assert(name != 0 && size > 0 && prefix != 0); TmpFile_getTmpEnv(tmpd, DISK_MAX_PATH); val = GetTempFileName( tmpd, prefix, 0, nm ); if (val > 0) { _tcsncpy(name, nm, size-1); name[size-1] = 0; return name; } return 0; #else int hdl = TmpFile_open(name, size, prefix); if (hdl >= 0) { // ハンドルが取得できていたら、win側に似せるため、ファイルはcloseして帰る. close(hdl); return name; } else { return 0; } #endif } #ifdef FNAME_INCLUDED // fname を使う場合. /** 環境変数tmp か temp からテンポラリディレクトリ名を取得. なければカレント"./"を返す. * @return 0:tmp,tempが無かった. 1:あった. */ int TmpFile_getTmpDir(TCHAR *dirName, size_t dirNameLen) { #if defined _WIN32 // winNT/2kのGetTempPathだとTMP,TEMPがなかったときwindowsディレクトリらしいのでやめて自前. TCHAR nm[DISK_MAX_PATH+2]; int f = TmpFile_getTmpEnv(nm, DISK_MAX_PATH); fname_addSep(nm, DISK_MAX_PATH); fname_cat(nm, DISK_MAX_PATH, _T("*.*")); fname_fullpath(dirName, dirNameLen, nm, "/"); fname_getDir(dirName, dirNameLen, dirName); #else fname_cpy(dirName, dirNameLen, "/tmp"); #endif return f; } #endif