summaryrefslogtreecommitdiff
path: root/win32
diff options
context:
space:
mode:
authorusa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2003-02-17 05:17:46 +0000
committerusa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2003-02-17 05:17:46 +0000
commit396f32c98eeef66f67c87336deab94774db00650 (patch)
tree4d6371d8807b59369c3c7b4509b2bee62544f705 /win32
parentc510198c3bda2e4c1554a2926c3803c84c9f6b94 (diff)
* 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
Diffstat (limited to 'win32')
-rw-r--r--win32/win32.c93
-rw-r--r--win32/win32.h4
2 files changed, 96 insertions, 1 deletions
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)
/*