Feature #13726 » 02-file-utime.patch
file.c | ||
---|---|---|
#define chown(p, o, g) rb_w32_uchown((p), (o), (g))
|
||
#undef lchown
|
||
#define lchown(p, o, g) rb_w32_ulchown((p), (o), (g))
|
||
#undef utime
|
||
#define utime(p, t) rb_w32_uutime((p), (t))
|
||
#undef utimensat
|
||
#define utimensat(s, p, t, f) rb_w32_uutimensat((s), (p), (t), (f))
|
||
#undef link
|
||
#define link(f, t) rb_w32_ulink((f), (t))
|
||
#undef unlink
|
include/ruby/win32.h | ||
---|---|---|
#undef fstat
|
||
#ifdef RUBY_EXPORT
|
||
#define utime(_p, _t) rb_w32_utime(_p, _t)
|
||
#undef HAVE_UTIMES
|
||
#define HAVE_UTIMES 1
|
||
#define utimes(_p, _t) rb_w32_utimes(_p, _t)
|
||
#undef HAVE_UTIMENSAT
|
||
#define HAVE_UTIMENSAT 1
|
||
#define AT_FDCWD -100
|
||
#define utimensat(_d, _p, _t, _f) rb_w32_utimensat(_d, _p, _t, _f)
|
||
#define lseek(_f, _o, _w) _lseeki64(_f, _o, _w)
|
||
#define pipe(p) rb_w32_pipe(p)
|
||
... | ... | |
ssize_t rb_w32_write(int, const void *, size_t);
|
||
int rb_w32_utime(const char *, const struct utimbuf *);
|
||
int rb_w32_uutime(const char *, const struct utimbuf *);
|
||
int rb_w32_utimes(const char *, const struct timeval *);
|
||
int rb_w32_uutimes(const char *, const struct timeval *);
|
||
int rb_w32_utimensat(int /* must be AT_FDCWD */, const char *, const struct timespec *, int /* must be 0 */);
|
||
int rb_w32_uutimensat(int /* must be AT_FDCWD */, const char *, const struct timespec *, int /* must be 0 */);
|
||
long rb_w32_write_console(uintptr_t, int); /* use uintptr_t instead of VALUE because it's not defined yet here */
|
||
int WINAPI rb_w32_Sleep(unsigned long msec);
|
||
int rb_w32_wait_events_blocking(HANDLE *events, int num, DWORD timeout);
|
win32/win32.c | ||
---|---|---|
return (long)reslen;
|
||
}
|
||
#if RUBY_MSVCRT_VERSION < 80 && !defined(HAVE__GMTIME64_S)
|
||
/* License: Ruby's */
|
||
static int
|
||
unixtime_to_filetime(time_t time, FILETIME *ft)
|
||
... | ... | |
ft->dwHighDateTime = tmp.HighPart;
|
||
return 0;
|
||
}
|
||
#endif
|
||
/* License: Ruby's */
|
||
static int
|
||
timespec_to_filetime(const struct timespec *ts, FILETIME *ft)
|
||
{
|
||
ULARGE_INTEGER tmp;
|
||
tmp.QuadPart = ((LONG_LONG)ts->tv_sec + (LONG_LONG)((1970-1601)*365.2425) * 24 * 60 * 60) * 10 * 1000 * 1000;
|
||
tmp.QuadPart += ts->tv_nsec / 100;
|
||
ft->dwLowDateTime = tmp.LowPart;
|
||
ft->dwHighDateTime = tmp.HighPart;
|
||
return 0;
|
||
}
|
||
/* License: Ruby's */
|
||
static int
|
||
wutime(const WCHAR *path, const struct utimbuf *times)
|
||
wutimensat(int dirfd, const WCHAR *path, const struct timespec *times, int flags)
|
||
{
|
||
HANDLE hFile;
|
||
FILETIME atime, mtime;
|
||
struct stati64ns stat;
|
||
int ret = 0;
|
||
/* TODO: When path is absolute, dirfd should be ignored. */
|
||
if (dirfd != AT_FDCWD) {
|
||
errno = ENOSYS;
|
||
return -1;
|
||
}
|
||
if (flags != 0) {
|
||
errno = EINVAL; /* AT_SYMLINK_NOFOLLOW isn't supported. */
|
||
return -1;
|
||
}
|
||
if (wstati64ns(path, &stat)) {
|
||
return -1;
|
||
}
|
||
if (times) {
|
||
if (unixtime_to_filetime(times->actime, &atime)) {
|
||
if (timespec_to_filetime(×[0], &atime)) {
|
||
return -1;
|
||
}
|
||
if (unixtime_to_filetime(times->modtime, &mtime)) {
|
||
if (timespec_to_filetime(×[1], &mtime)) {
|
||
return -1;
|
||
}
|
||
}
|
||
... | ... | |
int
|
||
rb_w32_uutime(const char *path, const struct utimbuf *times)
|
||
{
|
||
struct timespec ts[2];
|
||
ts[0].tv_sec = times->actime;
|
||
ts[0].tv_nsec = 0;
|
||
ts[1].tv_sec = times->modtime;
|
||
ts[1].tv_nsec = 0;
|
||
return rb_w32_uutimensat(AT_FDCWD, path, ts, 0);
|
||
}
|
||
/* License: Ruby's */
|
||
int
|
||
rb_w32_utime(const char *path, const struct utimbuf *times)
|
||
{
|
||
struct timespec ts[2];
|
||
ts[0].tv_sec = times->actime;
|
||
ts[0].tv_nsec = 0;
|
||
ts[1].tv_sec = times->modtime;
|
||
ts[1].tv_nsec = 0;
|
||
return rb_w32_utimensat(AT_FDCWD, path, ts, 0);
|
||
}
|
||
/* License: Ruby's */
|
||
int
|
||
rb_w32_uutimes(const char *path, const struct timeval *times)
|
||
{
|
||
struct timespec ts[2];
|
||
ts[0].tv_sec = times[0].tv_sec;
|
||
ts[0].tv_nsec = times[0].tv_usec * 1000;
|
||
ts[1].tv_sec = times[1].tv_sec;
|
||
ts[1].tv_nsec = times[1].tv_usec * 1000;
|
||
return rb_w32_uutimensat(AT_FDCWD, path, ts, 0);
|
||
}
|
||
/* License: Ruby's */
|
||
int
|
||
rb_w32_utimes(const char *path, const struct timeval *times)
|
||
{
|
||
struct timespec ts[2];
|
||
ts[0].tv_sec = times[0].tv_sec;
|
||
ts[0].tv_nsec = times[0].tv_usec * 1000;
|
||
ts[1].tv_sec = times[1].tv_sec;
|
||
ts[1].tv_nsec = times[1].tv_usec * 1000;
|
||
return rb_w32_utimensat(AT_FDCWD, path, ts, 0);
|
||
}
|
||
/* License: Ruby's */
|
||
int
|
||
rb_w32_uutimensat(int dirfd, const char *path, const struct timespec *times, int flags)
|
||
{
|
||
WCHAR *wpath;
|
||
int ret;
|
||
if (!(wpath = utf8_to_wstr(path, NULL)))
|
||
return -1;
|
||
ret = wutime(wpath, times);
|
||
ret = wutimensat(dirfd, wpath, times, flags);
|
||
free(wpath);
|
||
return ret;
|
||
}
|
||
/* License: Ruby's */
|
||
int
|
||
rb_w32_utime(const char *path, const struct utimbuf *times)
|
||
rb_w32_utimensat(int dirfd, const char *path, const struct timespec *times, int flags)
|
||
{
|
||
WCHAR *wpath;
|
||
int ret;
|
||
if (!(wpath = filecp_to_wstr(path, NULL)))
|
||
return -1;
|
||
ret = wutime(wpath, times);
|
||
ret = wutimensat(dirfd, wpath, times, flags);
|
||
free(wpath);
|
||
return ret;
|
||
}
|