• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /***************************************************************************
2  *                                  _   _ ____  _
3  *  Project                     ___| | | |  _ \| |
4  *                             / __| | | | |_) | |
5  *                            | (__| |_| |  _ <| |___
6  *                             \___|\___/|_| \_\_____|
7  *
8  * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
9  *
10  * This software is licensed as described in the file COPYING, which
11  * you should have received as part of this distribution. The terms
12  * are also available at https://curl.se/docs/copyright.html.
13  *
14  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15  * copies of the Software, and permit persons to whom the Software is
16  * furnished to do so, under the terms of the COPYING file.
17  *
18  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19  * KIND, either express or implied.
20  *
21  * SPDX-License-Identifier: curl
22  *
23  ***************************************************************************/
24 #include "tool_setup.h"
25 
26 #if defined(HAVE_STRCASECMP) && defined(HAVE_STRINGS_H)
27 #include <strings.h>
28 #endif
29 
30 #include "tool_util.h"
31 
32 #include "memdebug.h" /* keep this as LAST include */
33 
34 #if defined(WIN32) && !defined(MSDOS)
35 
36 /* set in win32_init() */
37 extern LARGE_INTEGER tool_freq;
38 extern bool tool_isVistaOrGreater;
39 
40 /* In case of bug fix this function has a counterpart in timeval.c */
tvnow(void)41 struct timeval tvnow(void)
42 {
43   struct timeval now;
44   if(tool_isVistaOrGreater) { /* QPC timer might have issues pre-Vista */
45     LARGE_INTEGER count;
46     QueryPerformanceCounter(&count);
47     now.tv_sec = (long)(count.QuadPart / tool_freq.QuadPart);
48     now.tv_usec = (long)((count.QuadPart % tool_freq.QuadPart) * 1000000 /
49                          tool_freq.QuadPart);
50   }
51   else {
52     /* Disable /analyze warning that GetTickCount64 is preferred  */
53 #if defined(_MSC_VER)
54 #pragma warning(push)
55 #pragma warning(disable:28159)
56 #endif
57     DWORD milliseconds = GetTickCount();
58 #if defined(_MSC_VER)
59 #pragma warning(pop)
60 #endif
61 
62     now.tv_sec = (long)(milliseconds / 1000);
63     now.tv_usec = (long)((milliseconds % 1000) * 1000);
64   }
65   return now;
66 }
67 
68 #elif defined(HAVE_CLOCK_GETTIME_MONOTONIC)
69 
tvnow(void)70 struct timeval tvnow(void)
71 {
72   /*
73   ** clock_gettime() is granted to be increased monotonically when the
74   ** monotonic clock is queried. Time starting point is unspecified, it
75   ** could be the system start-up time, the Epoch, or something else,
76   ** in any case the time starting point does not change once that the
77   ** system has started up.
78   */
79   struct timeval now;
80   struct timespec tsnow;
81   if(0 == clock_gettime(CLOCK_MONOTONIC, &tsnow)) {
82     now.tv_sec = tsnow.tv_sec;
83     now.tv_usec = (int)(tsnow.tv_nsec / 1000);
84   }
85   /*
86   ** Even when the configure process has truly detected monotonic clock
87   ** availability, it might happen that it is not actually available at
88   ** run-time. When this occurs simply fallback to other time source.
89   */
90 #ifdef HAVE_GETTIMEOFDAY
91   else
92     (void)gettimeofday(&now, NULL);
93 #else
94   else {
95     now.tv_sec = time(NULL);
96     now.tv_usec = 0;
97   }
98 #endif
99   return now;
100 }
101 
102 #elif defined(HAVE_GETTIMEOFDAY)
103 
tvnow(void)104 struct timeval tvnow(void)
105 {
106   /*
107   ** gettimeofday() is not granted to be increased monotonically, due to
108   ** clock drifting and external source time synchronization it can jump
109   ** forward or backward in time.
110   */
111   struct timeval now;
112   (void)gettimeofday(&now, NULL);
113   return now;
114 }
115 
116 #else
117 
tvnow(void)118 struct timeval tvnow(void)
119 {
120   /*
121   ** time() returns the value of time in seconds since the Epoch.
122   */
123   struct timeval now;
124   now.tv_sec = time(NULL);
125   now.tv_usec = 0;
126   return now;
127 }
128 
129 #endif
130 
131 /*
132  * Make sure that the first argument is the more recent time, as otherwise
133  * we'll get a weird negative time-diff back...
134  *
135  * Returns: the time difference in number of milliseconds.
136  */
tvdiff(struct timeval newer,struct timeval older)137 long tvdiff(struct timeval newer, struct timeval older)
138 {
139   return (long)(newer.tv_sec-older.tv_sec)*1000+
140     (long)(newer.tv_usec-older.tv_usec)/1000;
141 }
142 
143 /* Case insensitive compare. Accept NULL pointers. */
struplocompare(const char * p1,const char * p2)144 int struplocompare(const char *p1, const char *p2)
145 {
146   if(!p1)
147     return p2? -1: 0;
148   if(!p2)
149     return 1;
150 #ifdef HAVE_STRCASECMP
151   return strcasecmp(p1, p2);
152 #elif defined(HAVE_STRCMPI)
153   return strcmpi(p1, p2);
154 #elif defined(HAVE_STRICMP)
155   return stricmp(p1, p2);
156 #else
157   return strcmp(p1, p2);
158 #endif
159 }
160 
161 /* Indirect version to use as qsort callback. */
struplocompare4sort(const void * p1,const void * p2)162 int struplocompare4sort(const void *p1, const void *p2)
163 {
164   return struplocompare(* (char * const *) p1, * (char * const *) p2);
165 }
166