• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
Aucun tag

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

The MinGW.org Installation Manager Tool


Commit MetaInfo

Révision8e848b8b65f5a1f5c6dec8892e3fffa9228d31f0 (tree)
l'heure2013-06-15 04:58:21
AuteurKeith Marshall <keithmarshall@user...>
CommiterKeith Marshall

Message de Log

Handle Microsoft's 32-bit vs. 64-bit time_t ambiguity.

Change Summary

Modification

--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,19 @@
1+2013-06-14 Keith Marshall <keithmarshall@users.sourceforge.net>
2+
3+ Handle Microsoft's 32-bit vs. 64-bit time_t ambiguity.
4+
5+ * src/apihook.c: New file; it provides...
6+ (have_api): ...this helper; it checks for availability of any specific
7+ API function, within a specific system DLL, (MSVCRT.DLL by default).
8+
9+ * src/tarproc.cpp (have_utime64_api): New inline function; it wraps...
10+ (have_api): ...this, to check whether MSVCRT.DLL provides...
11+ (commit_saved_entity) [_utime64]: ...this; use if available, else...
12+ (commit_saved_entity) [!_utime64]: ...fall back to using...
13+ (utime): ...this.
14+
15+ * Makefile.in (CORE_DLL_OBJECTS): Add apihook.$OBJEXT
16+
117 2013-06-13 Keith Marshall <keithmarshall@users.sourceforge.net>
218
319 Facilitate package extraction and registration at setup time.
--- a/Makefile.in
+++ b/Makefile.in
@@ -165,7 +165,7 @@ CORE_DLL_OBJECTS = climain.$(OBJEXT) pkgshow.$(OBJEXT) dmhcore.$(OBJEXT) \
165165 pkgdeps.$(OBJEXT) pkgreqs.$(OBJEXT) pkginst.$(OBJEXT) pkgunst.$(OBJEXT) \
166166 tarproc.$(OBJEXT) xmlfile.$(OBJEXT) keyword.$(OBJEXT) vercmp.$(OBJEXT) \
167167 tinyxml.$(OBJEXT) tinystr.$(OBJEXT) tinyxmlparser.$(OBJEXT) \
168- mkpath.$(OBJEXT) tinyxmlerror.$(OBJEXT)
168+ apihook.$(OBJEXT) mkpath.$(OBJEXT) tinyxmlerror.$(OBJEXT)
169169
170170 CLI_EXE_OBJECTS = \
171171 clistub.$(OBJEXT) version.$(OBJEXT) approot.$(OBJEXT) getopt.$(OBJEXT)
--- /dev/null
+++ b/src/apihook.c
@@ -0,0 +1,61 @@
1+/*
2+ * apihook.c
3+ *
4+ * $Id$
5+ *
6+ * Written by Keith Marshall <keithmarshall@users.sourceforge.net>
7+ * Copyright (C) 2013, MinGW.org Project
8+ *
9+ *
10+ * Implementation of a utility function to check for availabiliity of
11+ * a specified API function within a specified DLL.
12+ *
13+ *
14+ * This is free software. Permission is granted to copy, modify and
15+ * redistribute this software, under the provisions of the GNU General
16+ * Public License, Version 3, (or, at your option, any later version),
17+ * as published by the Free Software Foundation; see the file COPYING
18+ * for licensing details.
19+ *
20+ * Note, in particular, that this software is provided "as is", in the
21+ * hope that it may prove useful, but WITHOUT WARRANTY OF ANY KIND; not
22+ * even an implied WARRANTY OF MERCHANTABILITY, nor of FITNESS FOR ANY
23+ * PARTICULAR PURPOSE. Under no circumstances will the author, or the
24+ * MinGW Project, accept liability for any damages, however caused,
25+ * arising from the use of this software.
26+ *
27+ */
28+#define WIN32_LEAN_AND_MEAN
29+
30+#include <windows.h>
31+
32+int have_api( const char *entry, const char *dll )
33+{
34+ /* Initially assuming that the specified API is "unsupported",
35+ * attempt to get a handle for the nominated provider DLL.
36+ */
37+ HMODULE provider;
38+ enum { API_UNSUPPORTED = 0, API_SUPPORTED } status = API_UNSUPPORTED;
39+ if( (provider = LoadLibrary( dll == NULL ? "msvcrt.dll" : dll )) != NULL )
40+ {
41+ /* When we have a valid DLL handle, look up the entry point
42+ * address, within it, for the specified API function...
43+ */
44+ if( GetProcAddress( provider, entry ) != NULL )
45+ /*
46+ * ...and, provided this returns a valid entry address,
47+ * mark the API as "supported".
48+ */
49+ status = API_SUPPORTED;
50+
51+ /* Release the handle we acquired above, for the provider DLL,
52+ * so that we maintain a balanced reference count.
53+ */
54+ FreeLibrary( provider );
55+ }
56+ /* Finally, return the support state for the API, as determined.
57+ */
58+ return (int)(status);
59+}
60+
61+/* $RCSfile$: end of file */
--- a/src/tarproc.cpp
+++ b/src/tarproc.cpp
@@ -532,16 +532,62 @@ char *pkgTarArchiveProcessor::EntityDataAsString()
532532 */
533533 #include <utime.h>
534534
535-static int commit_saved_entity( const char *pathname, time_t mtime )
535+EXTERN_C int have_api( const char *, const char * = NULL );
536+
537+static inline int have_utime64_api( void )
538+{
539+ /* Local helper function to check and record the availability of
540+ * the _utime64() API function, within the particular version of
541+ * MSVCRT.DLL which is installed on the host platform.
542+ */
543+ enum { API_UNSUPPORTED = 0, API_SUPPORTED, API_UNTESTED };
544+
545+ /* On first call, we don't know; initialise accordingly.
546+ */
547+ static int status = (int)(API_UNTESTED);
548+
549+ return (status == (int)(API_UNTESTED))
550+ /*
551+ * Must be first time of calling; check, record, and return
552+ * the appropriate availability status.
553+ */
554+ ? status = have_api( "_utime64" )
555+ /*
556+ * On second and subsequent calls, we've already checked, so
557+ * we know the availability status; simply return it.
558+ */
559+ : status;
560+}
561+
562+static int commit_saved_entity( const char *pathname, __time64_t mtime )
536563 {
537564 /* Helper to set the access and modification times for a file,
538565 * after extraction from an archive, to match the specified "mtime";
539566 * (typically "mtime" is as recorded within the archive).
540567 */
541- struct utimbuf timestamp;
568+ if( have_utime64_api() )
569+ {
570+ /* When the _utime64() API function is available...
571+ */
572+ struct __utimbuf64 timestamp;
542573
543- timestamp.actime = timestamp.modtime = mtime;
544- return utime( pathname, &timestamp );
574+ /* ...we prefer to use it...
575+ */
576+ timestamp.actime = timestamp.modtime = mtime;
577+ return _utime64( pathname, &timestamp );
578+ }
579+ else
580+ {
581+ /* ...otherwise, we assume that this is a legacy system,
582+ * and the utime() function is based on 32-bit time_t...
583+ */
584+ struct __utimbuf32 timestamp;
585+
586+ /* ...so fall back to using that.
587+ */
588+ timestamp.actime = timestamp.modtime = mtime;
589+ return utime( pathname, (utimbuf *)(&timestamp) );
590+ }
545591 }
546592
547593 pkgTarArchiveExtractor::pkgTarArchiveExtractor( const char *fn, const char *dir )