From a0c6ae2c62bbf270a9f31c2596863b085c08df8c Mon Sep 17 00:00:00 2001 From: uz Date: Tue, 3 Apr 2012 13:01:56 +0000 Subject: [PATCH] Added a replacement for utime(), because it has the same DST bug as stat(). git-svn-id: svn://svn.cc65.org/cc65/trunk@5637 b7a2c559-68d2-44c3-8de9-860c34a00d81 --- src/common/filetime.c | 155 +++++++++++++++++++++++++++++++++++++ src/common/filetime.h | 73 +++++++++++++++++ src/common/make/gcc.mak | 3 +- src/common/make/watcom.mak | 1 + 4 files changed, 231 insertions(+), 1 deletion(-) create mode 100644 src/common/filetime.c create mode 100644 src/common/filetime.h diff --git a/src/common/filetime.c b/src/common/filetime.c new file mode 100644 index 000000000..e617534bd --- /dev/null +++ b/src/common/filetime.c @@ -0,0 +1,155 @@ +/*****************************************************************************/ +/* */ +/* filetime.c */ +/* */ +/* Replacement for buggy Microsoft code */ +/* */ +/* */ +/* */ +/* (C) 2012, Ullrich von Bassewitz */ +/* Roemerstrasse 52 */ +/* D-70794 Filderstadt */ +/* EMail: uz@cc65.org */ +/* */ +/* */ +/* This software is provided 'as-is', without any expressed or implied */ +/* warranty. In no event will the authors be held liable for any damages */ +/* arising from the use of this software. */ +/* */ +/* Permission is granted to anyone to use this software for any purpose, */ +/* including commercial applications, and to alter it and redistribute it */ +/* freely, subject to the following restrictions: */ +/* */ +/* 1. The origin of this software must not be misrepresented; you must not */ +/* claim that you wrote the original software. If you use this software */ +/* in a product, an acknowledgment in the product documentation would be */ +/* appreciated but is not required. */ +/* 2. Altered source versions must be plainly marked as such, and must not */ +/* be misrepresented as being the original software. */ +/* 3. This notice may not be removed or altered from any source */ +/* distribution. */ +/* */ +/*****************************************************************************/ + + + +/* This module works around bugs in the time conversion code supplied by + * Microsoft. The problem described here: + * http://www.codeproject.com/KB/datetime/dstbugs.aspx + * is also true when setting file times via utime(), so we need a + * replacement + */ + + + +#if defined(__WATCOMC__) && defined(__NT__) +#define BUGGY_OS 1 +#include +#include +#else +#if defined(__WATCOMC__) || defined(_MSC_VER) || defined(__MINGW32__) +/* The Windows compilers have the file in the wrong directory */ +# include +#else +# include /* FreeBSD needs this */ +# include +#endif +#endif + + +/* common */ +#include "filetime.h" + + + +/*****************************************************************************/ +/* Code */ +/*****************************************************************************/ + + + +#if defined(BUGGY_OS) + + + +static FILETIME* UnixTimeToFileTime (time_t T, FILETIME* FT) +/* Calculate a FILETIME value from a time_t. FILETIME contains a 64 bit + * value with point zero at 1600-01-01 00:00:00 and counting 100ns intervals. + * time_t is in seconds since 1970-01-01 00:00:00. + */ +{ + /* Offset between 1600-01-01 and the Epoch in seconds. Watcom C has no + * way to express a number > 32 bit (known to me) but is able to do + * calculations with 64 bit integers, so we need to do it this way. + */ + static const ULARGE_INTEGER Offs = { 0xB6109100UL, 0x00000020UL }; + ULARGE_INTEGER V; + V.QuadPart = (unsigned __int64) T * 10000000U + Offs.QuadPart; + FT->dwLowDateTime = V.LowPart; + FT->dwHighDateTime = V.HighPart; + return FT; +} + + + +int SetFileTimes (const char* Path, time_t T) +/* Set the time of last modification and the time of last access of a file to + * the given time T. This calls utime() for system where it works, and applies + * workarounds for all others (which in fact means "WINDOWS"). + */ +{ + HANDLE H; + FILETIME FileTime; + int Error = EACCES; /* Assume an error */ + + + /* Open the file */ + H = CreateFile (Path, + GENERIC_WRITE, + FILE_SHARE_READ, + 0, /* Security attributes */ + OPEN_EXISTING, + 0, /* File flags */ + 0); /* Template file */ + if (H != INVALID_HANDLE_VALUE) { + /* Set access and modification time */ + UnixTimeToFileTime (T, &FileTime); + if (SetFileTime (H, 0, &FileTime, &FileTime)) { + /* Done */ + Error = 0; + } + + /* Close the handle */ + (void) CloseHandle (H); + } + + /* Return the error code */ + return Error; +} + + + +#else + + + +int SetFileTimes (const char* Path, time_t T) +/* Set the time of last modification and the time of last access of a file to + * the given time T. This calls utime() for system where it works, and applies + * workarounds for all others (which in fact means "WINDOWS"). + */ +{ + struct utimbuf U; + + /* Set access and modification time */ + U.actime = T; + U.modtime = T; + return utime (Path, &U); +} + + + +#endif + + + diff --git a/src/common/filetime.h b/src/common/filetime.h new file mode 100644 index 000000000..3b525b734 --- /dev/null +++ b/src/common/filetime.h @@ -0,0 +1,73 @@ +/*****************************************************************************/ +/* */ +/* filetime.h */ +/* */ +/* Replacement for buggy Microsoft code */ +/* */ +/* */ +/* */ +/* (C) 2012, Ullrich von Bassewitz */ +/* Roemerstrasse 52 */ +/* D-70794 Filderstadt */ +/* EMail: uz@cc65.org */ +/* */ +/* */ +/* This software is provided 'as-is', without any expressed or implied */ +/* warranty. In no event will the authors be held liable for any damages */ +/* arising from the use of this software. */ +/* */ +/* Permission is granted to anyone to use this software for any purpose, */ +/* including commercial applications, and to alter it and redistribute it */ +/* freely, subject to the following restrictions: */ +/* */ +/* 1. The origin of this software must not be misrepresented; you must not */ +/* claim that you wrote the original software. If you use this software */ +/* in a product, an acknowledgment in the product documentation would be */ +/* appreciated but is not required. */ +/* 2. Altered source versions must be plainly marked as such, and must not */ +/* be misrepresented as being the original software. */ +/* 3. This notice may not be removed or altered from any source */ +/* distribution. */ +/* */ +/*****************************************************************************/ + + + +/* This module works around bugs in the time conversion code supplied by + * Microsoft. The problem described here: + * http://www.codeproject.com/KB/datetime/dstbugs.aspx + * is also true when setting file times via utime(), so we need a + * replacement + */ + + + +#ifndef FILETIME_H +#define FILETIME_H + + + +#include + + + +/*****************************************************************************/ +/* Code */ +/*****************************************************************************/ + + + +int SetFileTimes (const char* Path, time_t T); +/* Set the time of last modification and the time of last access of a file to + * the given time T. This calls utime() for system where it works, and applies + * workarounds for all others (which in fact means "WINDOWS"). + */ + + + +/* End of filestat.h */ + +#endif + + + diff --git a/src/common/make/gcc.mak b/src/common/make/gcc.mak index 1ed1f4fad..4a126b250 100644 --- a/src/common/make/gcc.mak +++ b/src/common/make/gcc.mak @@ -26,8 +26,9 @@ OBJS = abend.o \ debugflag.o \ exprdefs.o \ fileid.o \ - filepos.o \ + filepos.o \ filestat.o \ + filetime.o \ filetype.o \ fname.o \ fp.o \ diff --git a/src/common/make/watcom.mak b/src/common/make/watcom.mak index e041937fc..1da7340dd 100644 --- a/src/common/make/watcom.mak +++ b/src/common/make/watcom.mak @@ -70,6 +70,7 @@ OBJS = abend.obj \ fileid.obj \ filepos.obj \ filestat.obj \ + filetime.obj \ filetype.obj \ fname.obj \ fp.obj \ -- 2.39.5