The MinGW.org Installation Manager Tool
Révision | 8e848b8b65f5a1f5c6dec8892e3fffa9228d31f0 (tree) |
---|---|
l'heure | 2013-06-15 04:58:21 |
Auteur | Keith Marshall <keithmarshall@user...> |
Commiter | Keith Marshall |
Handle Microsoft's 32-bit vs. 64-bit time_t ambiguity.
@@ -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 | + | |
1 | 17 | 2013-06-13 Keith Marshall <keithmarshall@users.sourceforge.net> |
2 | 18 | |
3 | 19 | Facilitate package extraction and registration at setup time. |
@@ -165,7 +165,7 @@ CORE_DLL_OBJECTS = climain.$(OBJEXT) pkgshow.$(OBJEXT) dmhcore.$(OBJEXT) \ | ||
165 | 165 | pkgdeps.$(OBJEXT) pkgreqs.$(OBJEXT) pkginst.$(OBJEXT) pkgunst.$(OBJEXT) \ |
166 | 166 | tarproc.$(OBJEXT) xmlfile.$(OBJEXT) keyword.$(OBJEXT) vercmp.$(OBJEXT) \ |
167 | 167 | tinyxml.$(OBJEXT) tinystr.$(OBJEXT) tinyxmlparser.$(OBJEXT) \ |
168 | - mkpath.$(OBJEXT) tinyxmlerror.$(OBJEXT) | |
168 | + apihook.$(OBJEXT) mkpath.$(OBJEXT) tinyxmlerror.$(OBJEXT) | |
169 | 169 | |
170 | 170 | CLI_EXE_OBJECTS = \ |
171 | 171 | clistub.$(OBJEXT) version.$(OBJEXT) approot.$(OBJEXT) getopt.$(OBJEXT) |
@@ -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 */ |
@@ -532,16 +532,62 @@ char *pkgTarArchiveProcessor::EntityDataAsString() | ||
532 | 532 | */ |
533 | 533 | #include <utime.h> |
534 | 534 | |
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 ) | |
536 | 563 | { |
537 | 564 | /* Helper to set the access and modification times for a file, |
538 | 565 | * after extraction from an archive, to match the specified "mtime"; |
539 | 566 | * (typically "mtime" is as recorded within the archive). |
540 | 567 | */ |
541 | - struct utimbuf timestamp; | |
568 | + if( have_utime64_api() ) | |
569 | + { | |
570 | + /* When the _utime64() API function is available... | |
571 | + */ | |
572 | + struct __utimbuf64 timestamp; | |
542 | 573 | |
543 | - timestamp.actime = timestamp.modtime = mtime; | |
544 | - return utime( pathname, ×tamp ); | |
574 | + /* ...we prefer to use it... | |
575 | + */ | |
576 | + timestamp.actime = timestamp.modtime = mtime; | |
577 | + return _utime64( pathname, ×tamp ); | |
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 *)(×tamp) ); | |
590 | + } | |
545 | 591 | } |
546 | 592 | |
547 | 593 | pkgTarArchiveExtractor::pkgTarArchiveExtractor( const char *fn, const char *dir ) |