diff --git a/src/common/filestat.c b/src/common/filestat.c new file mode 100644 index 000000000..6a965af36 --- /dev/null +++ b/src/common/filestat.c @@ -0,0 +1,143 @@ +/*****************************************************************************/ +/* */ +/* filestat.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. See here for a description of the problem: + * http://www.codeproject.com/KB/datetime/dstbugs.aspx + * Please let me note that I find it absolutely unacceptable to just declare + * buggy behaviour like this "works as designed" as Microsoft does. The + * problems did even make it into .NET, where the DateTime builtin data type + * has exactly the same problems as described in the article above. + */ + + + +#include +#include +#if defined(__WATCOMC__) && defined(__NT__) +#define BUGGY_OS 1 +#include +#include +#endif + + + +/*****************************************************************************/ +/* Code */ +/*****************************************************************************/ + + + +#if defined(BUGGY_OS) + + + +static time_t FileTimeToUnixTime (const FILETIME* T) +/* Calculate a unix time_t value from a FILETIME. 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, 0x20000000UL }; + ULARGE_INTEGER V; + V.LowPart = T->dwLowDateTime; + V.HighPart = T->dwHighDateTime; + return (V.QuadPart / 10000000U) - Offs.QuadPart; +} + + + +int FileStat (const char* Path, struct stat* Buf) +/* Replacement function for stat() */ +{ + + HANDLE H; + BY_HANDLE_FILE_INFORMATION Info; + + /* First call stat() */ + int Error = stat (Path, Buf); + if (Error != 0) { + return Error; + } + + /* Open the file using backup semantics, so we won't change atime. Then + * retrieve the correct times in UTC and replace the ones in Buf. Return + * EACCES in case of errors to avoid the hassle of translating windows + * error codes to standard ones. + */ + H = CreateFile (Path, + GENERIC_READ, + FILE_SHARE_READ, + 0, /* Security attributes */ + OPEN_EXISTING, + FILE_FLAG_BACKUP_SEMANTICS, + 0); /* Template file */ + if (H != INVALID_HANDLE_VALUE) { + if (GetFileInformationByHandle (H, &Info)) { + Buf->st_ctime = FileTimeToUnixTime (&Info.ftCreationTime); + Buf->st_atime = FileTimeToUnixTime (&Info.ftLastAccessTime); + Buf->st_mtime = FileTimeToUnixTime (&Info.ftLastWriteTime); + } else { + Error = EACCES; + } + CloseHandle (H); + } else { + Error = EACCES; + } + + /* Done */ + return Error; +} + + + +#else + + + +int FileStat (const char* Path, struct stat* Buf) +/* Replacement function for stat() */ +{ + /* Just call the function which works without errors */ + return stat (Path, Buf); +} + + + +#endif diff --git a/src/common/filestat.h b/src/common/filestat.h new file mode 100644 index 000000000..9f19188f2 --- /dev/null +++ b/src/common/filestat.h @@ -0,0 +1,73 @@ +/*****************************************************************************/ +/* */ +/* filestat.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. See here for a description of the problem: + * http://www.codeproject.com/KB/datetime/dstbugs.aspx + * Please let me note that I find it absolutely unacceptable to just declare + * buggy behaviour like this "works as designed" as Microsoft does. The + * problems did even make it into .NET, where the DateTime builtin data type + * has exactly the same problems as described in the article above. + */ + + + +#ifndef FILESTAT_H +#define FILESTAT_H + + + +#include +#include + + + +/*****************************************************************************/ +/* Code */ +/*****************************************************************************/ + + + +int FileStat (const char* Path, struct stat* Buf); +/* Replacement function for stat() */ + + + +/* End of filestat.h */ + +#endif + + + diff --git a/src/common/make/gcc.mak b/src/common/make/gcc.mak index 499080ad3..1ed1f4fad 100644 --- a/src/common/make/gcc.mak +++ b/src/common/make/gcc.mak @@ -27,6 +27,7 @@ OBJS = abend.o \ exprdefs.o \ fileid.o \ filepos.o \ + filestat.o \ filetype.o \ fname.o \ fp.o \ diff --git a/src/common/make/watcom.mak b/src/common/make/watcom.mak index 07e39155e..e041937fc 100644 --- a/src/common/make/watcom.mak +++ b/src/common/make/watcom.mak @@ -69,6 +69,7 @@ OBJS = abend.obj \ exprdefs.obj \ fileid.obj \ filepos.obj \ + filestat.obj \ filetype.obj \ fname.obj \ fp.obj \