]> git.sur5r.net Git - cc65/commitdiff
Add a new module that works around a bug in the Microsoft version of stat. The
authoruz <uz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Sun, 1 Apr 2012 16:56:42 +0000 (16:56 +0000)
committeruz <uz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Sun, 1 Apr 2012 16:56:42 +0000 (16:56 +0000)
function is buggy since the first version of windows that supports something
else than FAT, and instead of fixing the problem, Microsoft has declared it
"works as designed". The problem has made it into .NET and is also visible in
the standard windows file explorer (modification times of untouched files will
change when entering or leaving DST).
Please note that the new FileStat function returns incorrect times for files
on FAT file systems. This is because I have currently no idea on how to
identify the file system for a given file. However, it should be correct in
quite some more cases than stat().

git-svn-id: svn://svn.cc65.org/cc65/trunk@5632 b7a2c559-68d2-44c3-8de9-860c34a00d81

src/common/filestat.c [new file with mode: 0644]
src/common/filestat.h [new file with mode: 0644]
src/common/make/gcc.mak
src/common/make/watcom.mak

diff --git a/src/common/filestat.c b/src/common/filestat.c
new file mode 100644 (file)
index 0000000..6a965af
--- /dev/null
@@ -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 <sys/types.h>
+#include <sys/stat.h>
+#if defined(__WATCOMC__) && defined(__NT__)
+#define BUGGY_OS 1
+#include <errno.h>
+#include <windows.h>
+#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 (file)
index 0000000..9f19188
--- /dev/null
@@ -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 <sys/types.h>
+#include <sys/stat.h>
+
+
+
+/*****************************************************************************/
+/*                                          Code                                    */
+/*****************************************************************************/
+
+
+
+int FileStat (const char* Path, struct stat* Buf);
+/* Replacement function for stat() */
+
+
+
+/* End of filestat.h */
+
+#endif
+
+
+
index 499080ad3e9296e7ec82f40ff7e36f1574af9342..1ed1f4fad7ab8739d720d77026022a0ac0abe3e2 100644 (file)
@@ -27,6 +27,7 @@ OBJS =        abend.o         \
        exprdefs.o      \
         fileid.o        \
        filepos.o       \
+        filestat.o      \
        filetype.o      \
        fname.o         \
        fp.o            \
index 07e39155e598c0b26e1071aa72b97116f880aceb..e041937fce0c357aa9d392b0bd173054438cb48a 100644 (file)
@@ -69,6 +69,7 @@ OBJS =        abend.obj       \
        exprdefs.obj    \
         fileid.obj      \
        filepos.obj     \
+        filestat.obj    \
         filetype.obj    \
        fname.obj       \
         fp.obj          \