/** * @file disk.h * @brief ディレクトリ・エントリやファイル属性関係. * @author tenk* * @note * - win/linuxのディレクトリ・エントリやファイル属性関係の薄めのラッパー. * - 関数の返り値がintなら、特に別記なければ、0がok. 負がエラー. * - 大半がヘッダのみのinlineだが、一部、別の .c に実体を定義. * - Public Domain Software */ #ifndef DISK_H #define DISK_H #include <stddef.h> #include <assert.h> #include <stdio.h> #include <stdlib.h> #include <time.h> // ファイル名のサイズ. 利用側のバッファ準備用. #if defined _MAX_PATH #define DISK_MAX_PATH _MAX_PATH ///< 通常のパス名の長さ. #else #define DISK_MAX_PATH 1024 ///< 通常のパス名の長さ. (仮) #endif #if defined _WIN32 // ======================================================= #include <windows.h> #include <tchar.h> #include <io.h> #include <sys/stat.h> #include <sys/utime.h> #ifndef __cplusplus #define inline __inline #endif typedef struct __stat64 disk_file_stat_t; typedef struct __utimbuf64 disk_utimbuf_t; typedef unsigned __int64 disk_time_t; inline int disk_rename(const TCHAR* oldp, const TCHAR* newp) { assert(oldp&&newp); return MoveFile( oldp, newp ) ? 0 : -1; } inline int disk_remove(const TCHAR* fname) { assert(fname); return DeleteFile( fname ) ? 0 : -1; } inline int disk_mkdir (const TCHAR* fname) { assert(fname); return CreateDirectory(fname,NULL) ? 0 : -1; } inline int disk_rmdir (const TCHAR* fname) { assert(fname); return RemoveDirectory( fname ) ? 0 : -1; } inline int disk_chdir (const TCHAR* fname) { assert(fname); return SetCurrentDirectory(fname) ? 0 : -1; } inline TCHAR* disk_getcwd(TCHAR d[], size_t l) { assert(d&&l); return GetCurrentDirectory(l, d) ? d : 0 ; } inline int disk_chmod (const TCHAR* fnm, unsigned m) { assert(fnm&&m); return _tchmod(fnm, m); } inline int disk_fileStat(const char* fnm, disk_file_stat_t* s) { assert(fnm&&s); return _stat64(fnm, s); } inline int disk_utime(const char* fnm, disk_utimbuf_t* u) { assert(fnm&&u); return _utime64(fnm, u); } /// ファイルがあるか? inline int disk_fileExist(const TCHAR* f) { assert(f); return 0xFFFFFFFF != GetFileAttributes(f); } /// ファイル名のフルパス化. (実際のカレントディレクトリを反映) inline TCHAR* disk_fullpath(TCHAR f[], size_t l, const TCHAR* s) { assert(f&&l&&s); return _fullpath(f, s, l); } /// ファイルサイズ取得. inline unsigned __int64 disk_fileSize(const TCHAR* f) { WIN32_FIND_DATA d; HANDLE h; return f && ((h=FindFirstFile(f,&d)) != INVALID_HANDLE_VALUE) && FindClose(h) ? (((unsigned __int64)d.nFileSizeHigh<<32)|d.nFileSizeLow) : 0; } /// 時間の取得. 値はシステムに依存. inline int disk_getTime(const TCHAR* name, disk_time_t* pCr, disk_time_t* pAcs, disk_time_t* pWrt) { HANDLE hdl; if (name && (hdl = CreateFile(name, GENERIC_READ , FILE_SHARE_READ, 0 , OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0)) != INVALID_HANDLE_VALUE) { int r = (GetFileTime(hdl, (FILETIME*)pCr, (FILETIME*)pAcs, (FILETIME*)pWrt) ); CloseHandle(hdl); return r ? 0 : -1; } return 0; } /// 時間の設定. 値はシステム依存. inline int disk_setTime(const TCHAR* name, disk_time_t crt, disk_time_t acs, disk_time_t wrt) { int rc = 0; HANDLE hdl = CreateFile(name, GENERIC_WRITE, FILE_SHARE_READ, 0, CREATE_ALWAYS, 0, 0); if (hdl != INVALID_HANDLE_VALUE) { rc = SetFileTime(hdl, (FILETIME*)&crt, (FILETIME*)&acs, (FILETIME*)&wrt); CloseHandle(hdl); } return rc ? 0 : -1; } #if 1 // windows のみの専用. /// exeのパス名取得. 返値0:ok 負:エラー. 詳細はdisk_lastError()から取得. inline TCHAR* disk_getExePath(TCHAR nameBuf[], size_t nameBufSize) { return GetModuleFileName(0, nameBuf, nameBufSize) ? nameBuf : 0; } /// システムディレクトリの取得. 返値0:ok 負:エラー. 詳細はdisk_lastError()から取得. inline TCHAR* disk_getSystemDir(TCHAR nameBuf[], size_t nameBufSize) { return GetSystemDirectory(nameBuf, nameBufSize) ? nameBuf: 0; } /// windowsディレクトリの取得. 返値0:ok 負:エラー. 詳細はdisk_lastError()から取得. inline TCHAR* disk_getWindowsDir(TCHAR nameBuf[], size_t nameBufSize) { return GetWindowsDirectory(nameBuf, nameBufSize) ? nameBuf: 0; } #endif #else // linux ============================================================== //#define _LARGEFILE64_SOURCE //きっとここで定義するんじゃなくてコンパイラ引数で. #include <stdint.h> #include <string.h> #include <unistd.h> #include <fcntl.h> #include <sys/stat.h> #include <dirent.h> #include <time.h> #include <utime.h> #ifndef _T #define TCHAR char #define _T(x) x #endif typedef struct stat disk_file_stat_t; typedef struct utimbuf disk_utimbuf_t; typedef time_t disk_time_t; inline int disk_rename(const TCHAR* oldp, const TCHAR* newp) { assert(oldp&&newp); return rename( oldp, newp ); } inline int disk_remove(const TCHAR* fname) { assert(fname); return remove(fname); } inline int disk_mkdir (const TCHAR* fname) { assert(fname); return mkdir(fname, 0777); } inline int disk_rmdir (const TCHAR* fname) { assert(fname); return rmdir(fname); } inline int disk_chdir (const TCHAR* fname) { assert(fname); return chdir(fname); } inline TCHAR* disk_getcwd(TCHAR d[], size_t l) { assert(d&&l); return getcwd(d, l); } inline int disk_chmod (const TCHAR* fnm, unsigned m) { assert(fnm&&m); return chmod(fnm, m); } inline int disk_fileStat(const char* f, disk_file_stat_t* s) { assert(f&&s); return stat(f, s); } inline int disk_utime (const char* f, disk_utimbuf_t* u) { assert(f&&u); return utime(f, u); } /// ファイルがあるか? inline int disk_fileExist(const TCHAR* f) {int h;assert(f);return ((h=open(f,O_RDONLY/*|O_BINARY*/,0766)) >= 0) ? (close(h),1) : 0;} /// ファイル名のフルパス化. (実際のカレントディレクトリを反映. gnuライブラリ拡張機能を使用.) inline TCHAR* disk_fullpath(TCHAR f[], size_t l, const TCHAR* p) { assert(f&&l&&p); return (p=realpath(p,0)) ? (f[--l]=0, strncpy(f,p,l),free((void*)p), (TCHAR*)p) : 0; } /// ファイルサイズ取得. inline uint64_t disk_fileSize(const TCHAR* fnm) {struct stat s; assert(fnm); return (!stat(fnm, &s)) ? s.st_size : 0; } /// 時間の取得. 値はシステムに依存. inline int disk_getTime(const TCHAR* name, disk_time_t* pCr, disk_time_t* pAcs, disk_time_t* pWrt) { struct stat st; if (name && stat(name, &st) == 0) { if (pWrt) *pWrt = st.st_mtime; if (pAcs) *pAcs = st.st_atime; if (pCr ) *pCr = st.st_ctime; return 0; } else { return -1; } } /// 時間の設定. createTimeは無視する. inline int disk_setTime(const TCHAR* name, disk_time_t createTime, disk_time_t acs, disk_time_t wrt) { struct utimbuf u = { 0 }; createTime; u.actime = acs; u.modtime = wrt; return utime(name, &u); } #endif // ================================================================== #endif // DISK_H