Project

General

Profile

Feature #13726 ยป 02-file-utime.patch

MSP-Greg (Greg L), 07/07/2017 02:25 AM

View differences:

file.c
113 113
#define chown(p, o, g)	rb_w32_uchown((p), (o), (g))
114 114
#undef lchown
115 115
#define lchown(p, o, g)	rb_w32_ulchown((p), (o), (g))
116
#undef utime
117
#define utime(p, t)	rb_w32_uutime((p), (t))
116
#undef utimensat
117
#define utimensat(s, p, t, f)	rb_w32_uutimensat((s), (p), (t), (f))
118 118
#undef link
119 119
#define link(f, t)	rb_w32_ulink((f), (t))
120 120
#undef unlink
include/ruby/win32.h
139 139
#undef fstat
140 140
#ifdef RUBY_EXPORT
141 141
#define utime(_p, _t)		rb_w32_utime(_p, _t)
142
#undef HAVE_UTIMES
143
#define HAVE_UTIMES 1
144
#define utimes(_p, _t)		rb_w32_utimes(_p, _t)
145
#undef HAVE_UTIMENSAT
146
#define HAVE_UTIMENSAT 1
147
#define AT_FDCWD		-100
148
#define utimensat(_d, _p, _t, _f)	rb_w32_utimensat(_d, _p, _t, _f)
142 149
#define lseek(_f, _o, _w)	_lseeki64(_f, _o, _w)
143 150

  
144 151
#define pipe(p)			rb_w32_pipe(p)
......
742 749
ssize_t rb_w32_write(int, const void *, size_t);
743 750
int  rb_w32_utime(const char *, const struct utimbuf *);
744 751
int  rb_w32_uutime(const char *, const struct utimbuf *);
752
int  rb_w32_utimes(const char *, const struct timeval *);
753
int  rb_w32_uutimes(const char *, const struct timeval *);
754
int  rb_w32_utimensat(int /* must be AT_FDCWD */, const char *, const struct timespec *, int /* must be 0 */);
755
int  rb_w32_uutimensat(int /* must be AT_FDCWD */, const char *, const struct timespec *, int /* must be 0 */);
745 756
long rb_w32_write_console(uintptr_t, int);	/* use uintptr_t instead of VALUE because it's not defined yet here */
746 757
int  WINAPI rb_w32_Sleep(unsigned long msec);
747 758
int  rb_w32_wait_events_blocking(HANDLE *events, int num, DWORD timeout);
win32/win32.c
7248 7248
    return (long)reslen;
7249 7249
}
7250 7250

  
7251
#if RUBY_MSVCRT_VERSION < 80 && !defined(HAVE__GMTIME64_S)
7251 7252
/* License: Ruby's */
7252 7253
static int
7253 7254
unixtime_to_filetime(time_t time, FILETIME *ft)
......
7259 7260
    ft->dwHighDateTime = tmp.HighPart;
7260 7261
    return 0;
7261 7262
}
7263
#endif
7264

  
7265
/* License: Ruby's */
7266
static int
7267
timespec_to_filetime(const struct timespec *ts, FILETIME *ft)
7268
{
7269
    ULARGE_INTEGER tmp;
7270

  
7271
    tmp.QuadPart = ((LONG_LONG)ts->tv_sec + (LONG_LONG)((1970-1601)*365.2425) * 24 * 60 * 60) * 10 * 1000 * 1000;
7272
    tmp.QuadPart += ts->tv_nsec / 100;
7273
    ft->dwLowDateTime = tmp.LowPart;
7274
    ft->dwHighDateTime = tmp.HighPart;
7275
    return 0;
7276
}
7262 7277

  
7263 7278
/* License: Ruby's */
7264 7279
static int
7265
wutime(const WCHAR *path, const struct utimbuf *times)
7280
wutimensat(int dirfd, const WCHAR *path, const struct timespec *times, int flags)
7266 7281
{
7267 7282
    HANDLE hFile;
7268 7283
    FILETIME atime, mtime;
7269 7284
    struct stati64ns stat;
7270 7285
    int ret = 0;
7271 7286

  
7287
    /* TODO: When path is absolute, dirfd should be ignored. */
7288
    if (dirfd != AT_FDCWD) {
7289
	errno = ENOSYS;
7290
	return -1;
7291
    }
7292

  
7293
    if (flags != 0) {
7294
	errno = EINVAL; /* AT_SYMLINK_NOFOLLOW isn't supported. */
7295
	return -1;
7296
    }
7297

  
7272 7298
    if (wstati64ns(path, &stat)) {
7273 7299
	return -1;
7274 7300
    }
7275 7301

  
7276 7302
    if (times) {
7277
	if (unixtime_to_filetime(times->actime, &atime)) {
7303
	if (timespec_to_filetime(&times[0], &atime)) {
7278 7304
	    return -1;
7279 7305
	}
7280
	if (unixtime_to_filetime(times->modtime, &mtime)) {
7306
	if (timespec_to_filetime(&times[1], &mtime)) {
7281 7307
	    return -1;
7282 7308
	}
7283 7309
    }
......
7313 7339
int
7314 7340
rb_w32_uutime(const char *path, const struct utimbuf *times)
7315 7341
{
7342
    struct timespec ts[2];
7343

  
7344
    ts[0].tv_sec = times->actime;
7345
    ts[0].tv_nsec = 0;
7346
    ts[1].tv_sec = times->modtime;
7347
    ts[1].tv_nsec = 0;
7348
    return rb_w32_uutimensat(AT_FDCWD, path, ts, 0);
7349
}
7350

  
7351
/* License: Ruby's */
7352
int
7353
rb_w32_utime(const char *path, const struct utimbuf *times)
7354
{
7355
    struct timespec ts[2];
7356

  
7357
    ts[0].tv_sec = times->actime;
7358
    ts[0].tv_nsec = 0;
7359
    ts[1].tv_sec = times->modtime;
7360
    ts[1].tv_nsec = 0;
7361
    return rb_w32_utimensat(AT_FDCWD, path, ts, 0);
7362
}
7363

  
7364
/* License: Ruby's */
7365
int
7366
rb_w32_uutimes(const char *path, const struct timeval *times)
7367
{
7368
    struct timespec ts[2];
7369

  
7370
    ts[0].tv_sec = times[0].tv_sec;
7371
    ts[0].tv_nsec = times[0].tv_usec * 1000;
7372
    ts[1].tv_sec = times[1].tv_sec;
7373
    ts[1].tv_nsec = times[1].tv_usec * 1000;
7374
    return rb_w32_uutimensat(AT_FDCWD, path, ts, 0);
7375
}
7376

  
7377
/* License: Ruby's */
7378
int
7379
rb_w32_utimes(const char *path, const struct timeval *times)
7380
{
7381
    struct timespec ts[2];
7382

  
7383
    ts[0].tv_sec = times[0].tv_sec;
7384
    ts[0].tv_nsec = times[0].tv_usec * 1000;
7385
    ts[1].tv_sec = times[1].tv_sec;
7386
    ts[1].tv_nsec = times[1].tv_usec * 1000;
7387
    return rb_w32_utimensat(AT_FDCWD, path, ts, 0);
7388
}
7389

  
7390
/* License: Ruby's */
7391
int
7392
rb_w32_uutimensat(int dirfd, const char *path, const struct timespec *times, int flags)
7393
{
7316 7394
    WCHAR *wpath;
7317 7395
    int ret;
7318 7396

  
7319 7397
    if (!(wpath = utf8_to_wstr(path, NULL)))
7320 7398
	return -1;
7321
    ret = wutime(wpath, times);
7399
    ret = wutimensat(dirfd, wpath, times, flags);
7322 7400
    free(wpath);
7323 7401
    return ret;
7324 7402
}
7325 7403

  
7326 7404
/* License: Ruby's */
7327 7405
int
7328
rb_w32_utime(const char *path, const struct utimbuf *times)
7406
rb_w32_utimensat(int dirfd, const char *path, const struct timespec *times, int flags)
7329 7407
{
7330 7408
    WCHAR *wpath;
7331 7409
    int ret;
7332 7410

  
7333 7411
    if (!(wpath = filecp_to_wstr(path, NULL)))
7334 7412
	return -1;
7335
    ret = wutime(wpath, times);
7413
    ret = wutimensat(dirfd, wpath, times, flags);
7336 7414
    free(wpath);
7337 7415
    return ret;
7338 7416
}