From 396f32c98eeef66f67c87336deab94774db00650 Mon Sep 17 00:00:00 2001 From: usa Date: Mon, 17 Feb 2003 05:17:46 +0000 Subject: * win32/win32.c (link): implement with CreateHardLink(). * win32/win32.c, win32/win32.h (rb_w32_utime): enable utime() to directory if on NT. [new] (ruby-bugs-ja:PR#393) git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@3501 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- win32/win32.c | 93 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ win32/win32.h | 4 ++- 2 files changed, 96 insertions(+), 1 deletion(-) (limited to 'win32') diff --git a/win32/win32.c b/win32/win32.c index 37aa0d0cf4..f19976934e 100644 --- a/win32/win32.c +++ b/win32/win32.c @@ -2499,7 +2499,35 @@ kill(int pid, int sig) int link(char *from, char *to) { + static BOOL (WINAPI *pCreateHardLink)(LPCTSTR, LPCTSTR, LPSECURITY_ATTRIBUTES) = NULL; + static int myerrno = 0; + + if (!pCreateHardLink && !myerrno) { + HANDLE hKernel; + + hKernel = GetModuleHandle("kernel32.dll"); + if (hKernel) { + pCreateHardLink = (BOOL (WINAPI *)(LPCTSTR, LPCTSTR, LPSECURITY_ATTRIBUTES))GetProcAddress(hKernel, "CreateHardLinkA"); + if (!pCreateHardLink) { + myerrno = GetLastError(); + } + CloseHandle(hKernel); + } + else { + myerrno = GetLastError(); + } + } + if (!pCreateHardLink) { + errno = myerrno; return -1; + } + + if (!pCreateHardLink(to, from, NULL)) { + errno = GetLastError(); + return -1; + } + + return 0; } int @@ -3083,3 +3111,68 @@ rb_w32_close(int fd) } return 0; } + +static int +unixtime_to_filetime(time_t time, FILETIME *ft) +{ + struct tm *tm; + SYSTEMTIME st; + + tm = gmtime(&time); + st.wYear = tm->tm_year + 1900; + st.wMonth = tm->tm_mon + 1; + st.wDayOfWeek = tm->tm_wday; + st.wDay = tm->tm_mday; + st.wHour = tm->tm_hour; + st.wMinute = tm->tm_min; + st.wSecond = tm->tm_sec; + st.wMilliseconds = 0; + if (!SystemTimeToFileTime(&st, ft)) { + errno = GetLastError(); + return -1; + } + return 0; +} + +#undef utime +#ifdef __BORLANDC__ +#define utime _utime +#endif +int +rb_w32_utime(const char *path, struct utimbuf *times) +{ + HANDLE hDir; + SYSTEMTIME st; + FILETIME atime, mtime; + struct tm *tm; + struct stat stat; + int ret = 0; + + if (rb_w32_stat(path, &stat)) { + return -1; + } + if (stat.st_mode & S_IFDIR == 0 || IsWin95()) { + return utime(path, times); + } + + if (unixtime_to_filetime(times->actime, &atime)) { + return -1; + } + if (unixtime_to_filetime(times->modtime, &mtime)) { + return -1; + } + + hDir = CreateFile(path, GENERIC_WRITE, 0, 0, OPEN_EXISTING, + FILE_FLAG_BACKUP_SEMANTICS, 0); + if (hDir == INVALID_HANDLE_VALUE) { + errno = GetLastError(); + return -1; + } + if (!SetFileTime(hDir, NULL, &atime, &mtime)) { + errno = GetLastError(); + ret = -1; + } + CloseHandle(hDir); + + return ret; +} diff --git a/win32/win32.h b/win32/win32.h index 6880b65a2d..59e0dd694b 100644 --- a/win32/win32.h +++ b/win32/win32.h @@ -89,6 +89,7 @@ extern "C++" { #undef putchar #undef fgetchar #undef fputchar +#undef utime #define getc(_stream) rb_w32_getc(_stream) #define putc(_c, _stream) rb_w32_putc(_c, _stream) #define fgetc(_stream) getc(_stream) @@ -97,6 +98,7 @@ extern "C++" { #define putchar(_c) rb_w32_putc(_c, stdout) #define fgetchar() getchar() #define fputchar(_c) putchar(_c) +#define utime(_p, _t) rb_w32_utime(_p, _t) #define strcasecmp stricmp #define strncasecmp strnicmp @@ -121,7 +123,6 @@ extern "C++" { #define umask _umask #define unlink _unlink #define write _write -#define utime _utime #endif #define vsnprintf _vsnprintf #define snprintf _snprintf @@ -459,6 +460,7 @@ int rb_w32_putc(int, FILE*); int rb_w32_getc(FILE*); int rb_w32_close(int); int rb_w32_fclose(FILE*); +int rb_w32_utime(const char *, struct utimbuf *); #define Sleep(msec) (void)rb_w32_sleep(msec) /* -- cgit v1.2.3