1/* MIT License 2 * 3 * Copyright (c) 2008 Daniel Stenberg 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a copy 6 * of this software and associated documentation files (the "Software"), to deal 7 * in the Software without restriction, including without limitation the rights 8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 * copies of the Software, and to permit persons to whom the Software is 10 * furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice (including the next 13 * paragraph) shall be included in all copies or substantial portions of the 14 * Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 * SOFTWARE. 23 * 24 * SPDX-License-Identifier: MIT 25 */ 26 27#include "ares_setup.h" 28#include "ares.h" 29#include "ares_private.h" 30 31#if defined(WIN32) && !defined(MSDOS) 32 33struct timeval ares__tvnow(void) 34{ 35 /* 36 ** GetTickCount() is available on _all_ Windows versions from W95 up 37 ** to nowadays. Returns milliseconds elapsed since last system boot, 38 ** increases monotonically and wraps once 49.7 days have elapsed. 39 */ 40 struct timeval now; 41 DWORD milliseconds = GetTickCount(); 42 now.tv_sec = (long)milliseconds / 1000; 43 now.tv_usec = (long)(milliseconds % 1000) * 1000; 44 return now; 45} 46 47#elif defined(HAVE_CLOCK_GETTIME_MONOTONIC) 48 49struct timeval ares__tvnow(void) 50{ 51 /* 52 ** clock_gettime() is granted to be increased monotonically when the 53 ** monotonic clock is queried. Time starting point is unspecified, it 54 ** could be the system start-up time, the Epoch, or something else, 55 ** in any case the time starting point does not change once that the 56 ** system has started up. 57 */ 58 struct timeval now; 59 struct timespec tsnow; 60 if (0 == clock_gettime(CLOCK_MONOTONIC, &tsnow)) { 61 now.tv_sec = tsnow.tv_sec; 62 now.tv_usec = (int)(tsnow.tv_nsec / 1000); 63 } 64 /* 65 ** Even when the configure process has truly detected monotonic clock 66 ** availability, it might happen that it is not actually available at 67 ** run-time. When this occurs simply fallback to other time source. 68 */ 69# ifdef HAVE_GETTIMEOFDAY 70 else 71 (void)gettimeofday(&now, NULL); /* LCOV_EXCL_LINE */ 72# else 73 else { 74 now.tv_sec = (long)time(NULL); 75 now.tv_usec = 0; 76 } 77# endif 78 return now; 79} 80 81#elif defined(HAVE_GETTIMEOFDAY) 82 83struct timeval ares__tvnow(void) 84{ 85 /* 86 ** gettimeofday() is not granted to be increased monotonically, due to 87 ** clock drifting and external source time synchronization it can jump 88 ** forward or backward in time. 89 */ 90 struct timeval now; 91 (void)gettimeofday(&now, NULL); 92 return now; 93} 94 95#else 96 97struct timeval ares__tvnow(void) 98{ 99 /* 100 ** time() returns the value of time in seconds since the Epoch. 101 */ 102 struct timeval now; 103 now.tv_sec = (long)time(NULL); 104 now.tv_usec = 0; 105 return now; 106} 107 108#endif 109