Discussion:
futimens() for WIN32/MinGW
(too old to reply)
Tim Rühsen
2017-04-04 11:03:12 UTC
Permalink
Raw Message
Hi,

gnulib has no support for WIN32 futimens resp. the gnulib implementation
returns a 'not implemented' error.

So today I wrote a surrogate for it, which works for me on MinGW.

Since I am not sure where to add it (futimens.c or utimens.c) and if
there are caveats, I ask you to add it where appropriate.

#ifdef _WIN32
#include <windows.h>

int futimens(int fd, const struct timespec times[2])
{
FILETIME mt, at;
LONGLONG ll;

// convert time_t to FILETIME
ll = Int32x32To64(times[0].tv_sec, 10000000) + 116444736000000000;
at.dwLowDateTime = (DWORD) ll;
at.dwHighDateTime = ll >> 32;

ll = Int32x32To64(times[1].tv_sec, 10000000) + 116444736000000000;
mt.dwLowDateTime = (DWORD) ll;
mt.dwHighDateTime = ll >> 32;

BOOL success = SetFileTime(
(HANDLE) _get_osfhandle (fd),
&mt, // creation
&at, // last access
&mt); // last modification

return success ? 0 : -1;
}
#endif


Regards, Tim
Bruno Haible
2017-04-05 01:48:32 UTC
Permalink
Raw Message
Hi Tim,
Post by Tim Rühsen
gnulib has no support for WIN32 futimens resp. the gnulib implementation
returns a 'not implemented' error.
So today I wrote a surrogate for it, which works for me on MinGW.
Since I am not sure where to add it (futimens.c or utimens.c) and if
there are caveats, I ask you to add it where appropriate.
#ifdef _WIN32
#include <windows.h>
int futimens(int fd, const struct timespec times[2])
{
FILETIME mt, at;
LONGLONG ll;
// convert time_t to FILETIME
ll = Int32x32To64(times[0].tv_sec, 10000000) + 116444736000000000;
at.dwLowDateTime = (DWORD) ll;
at.dwHighDateTime = ll >> 32;
ll = Int32x32To64(times[1].tv_sec, 10000000) + 116444736000000000;
mt.dwLowDateTime = (DWORD) ll;
mt.dwHighDateTime = ll >> 32;
BOOL success = SetFileTime(
(HANDLE) _get_osfhandle (fd),
&mt, // creation
&at, // last access
&mt); // last modification
return success ? 0 : -1;
}
#endif
This is a good start, indeed.

When integrating such a code in gnulib, one needs to check also
whether the existing tests (of this module and related modules)
or can be adapted. So the next practical step is to run
./gnulib-tool --create-testdir --with-tests --single-configure utimens futimens ...

You will then notice:
- There is a link error due to --single-configure and strerror_r.
- The logic in nap.h is buggy: it calls nanosleep with a negative
delay argument. And it expects Unix behaviour that is not met
by Windows.
- Not only utimens.c needs to be adjusted, but also utimecmp.c.
- st_mtime come out 2 hours higher than expected (for me). Obviously
some timezone issue.
- And probably more...

I'm trying to get these sorted out, one by one.

Bruno
Bruno Haible
2017-05-01 10:24:55 UTC
Permalink
Raw Message
Hi Tim,
Post by Bruno Haible
- There is a link error due to --single-configure and strerror_r.
- The logic in nap.h is buggy: it calls nanosleep with a negative
delay argument. And it expects Unix behaviour that is not met
by Windows.
- Not only utimens.c needs to be adjusted, but also utimecmp.c.
- st_mtime come out 2 hours higher than expected (for me). Obviously
some timezone issue.
- And probably more...
I'm trying to get these sorted out, one by one.
Done.

You should now be able to use utimens() and friends in GNU wget.

Btw, this utime() / futimens() call in wget is the reason why I prefer
to download files through wget instead of through a browser.

Bruno
Tim Rühsen
2017-05-01 15:03:07 UTC
Permalink
Raw Message
Hi Bruno,
Post by Bruno Haible
Hi Tim,
Post by Bruno Haible
- There is a link error due to --single-configure and strerror_r.
- The logic in nap.h is buggy: it calls nanosleep with a negative
delay argument. And it expects Unix behaviour that is not met
by Windows.
- Not only utimens.c needs to be adjusted, but also utimecmp.c.
- st_mtime come out 2 hours higher than expected (for me). Obviously
some timezone issue.
- And probably more...
I'm trying to get these sorted out, one by one.
Done.
You should now be able to use utimens() and friends in GNU wget.
That is awesome, thank you so much !

Removed my WIN32 futimens code from Wget2, updated gnulib, tested with MinGW
and pushed !

With Best Regards, Tim

Loading...