... to cater for systems with unsigned time_t variables.
- Renamed the functions to curlx_timediff and Curl_timediff_us.
- Added overflow protection for both of them in either direction for
both 32 bit and 64 bit time_ts
- Reprefixed the curlx_time functions to use Curl_*
Reported-by: Peter Piekarski
Fixes #2004
Closes #2005
result = CURLE_ABORTED_BY_CALLBACK;
else {
struct curltime now2 = Curl_tvnow();
- time_t timediff = Curl_tvdiff(now2, now); /* spent time */
+ timediff_t timediff = Curl_timediff(now2, now); /* spent time */
if(timediff <= 0)
timeout -= 1; /* always deduct at least 1 */
else if(timediff > timeout)
}
else {
/* poll for name lookup done with exponential backoff up to 250ms */
- time_t elapsed = Curl_tvdiff(Curl_tvnow(), data->progress.t_startsingle);
+ timediff_t elapsed = Curl_timediff(Curl_tvnow(),
+ data->progress.t_startsingle);
if(elapsed < 0)
elapsed = 0;
/* subtract elapsed time */
if(duringconnect)
/* since this most recent connect started */
- timeout_ms -= Curl_tvdiff(*nowp, data->progress.t_startsingle);
+ timeout_ms -= Curl_timediff(*nowp, data->progress.t_startsingle);
else
/* since the entire operation started */
- timeout_ms -= Curl_tvdiff(*nowp, data->progress.t_startop);
+ timeout_ms -= Curl_timediff(*nowp, data->progress.t_startop);
if(!timeout_ms)
/* avoid returning 0 as that means no timeout! */
return -1;
if(rc == 0) { /* no connection yet */
error = 0;
- if(curlx_tvdiff(now, conn->connecttime) >= conn->timeoutms_per_addr) {
+ if(Curl_timediff(now, conn->connecttime) >= conn->timeoutms_per_addr) {
infof(data, "After %ldms connect time, move on!\n",
conn->timeoutms_per_addr);
error = ETIMEDOUT;
/* should we try another protocol family? */
if(i == 0 && conn->tempaddr[1] == NULL &&
- curlx_tvdiff(now, conn->connecttime) >= HAPPY_EYEBALLS_TIMEOUT) {
+ Curl_timediff(now, conn->connecttime) >= HAPPY_EYEBALLS_TIMEOUT) {
trynextip(conn, sockindex, 1);
}
}
}
/* get the time stamp to use to figure out how long poll takes */
- before = curlx_tvnow();
+ before = Curl_tvnow();
/* wait for activity or timeout */
pollrc = Curl_poll(fds, numfds, (int)ev->ms);
- after = curlx_tvnow();
+ after = Curl_tvnow();
ev->msbump = FALSE; /* reset here */
/* If nothing updated the timeout, we decrease it by the spent time.
* If it was updated, it has the new timeout time stored already.
*/
- time_t timediff = curlx_tvdiff(after, before);
+ timediff_t timediff = Curl_timediff(after, before);
if(timediff > 0) {
if(timediff > ev->ms)
ev->ms = 0;
int still_running = 0;
int rc;
- before = curlx_tvnow();
+ before = Curl_tvnow();
mcode = curl_multi_wait(multi, NULL, 0, 1000, &rc);
if(!mcode) {
if(!rc) {
- struct curltime after = curlx_tvnow();
+ struct curltime after = Curl_tvnow();
/* If it returns without any filedescriptor instantly, we need to
avoid busy-looping during periods where it has nothing particular
to wait for */
- if(curlx_tvdiff(after, before) <= 10) {
+ if(Curl_timediff(after, before) <= 10) {
without_fds++;
if(without_fds > 2) {
int sleep_ms = without_fds < 10 ? (1 << (without_fds - 1)) : 1000;
timeout_ms = other;
else {
/* subtract elapsed time */
- timeout_ms -= Curl_tvdiff(now, data->progress.t_acceptdata);
+ timeout_ms -= Curl_timediff(now, data->progress.t_acceptdata);
if(!timeout_ms)
/* avoid returning 0 as that means no timeout! */
return -1;
the time we spent until now! */
if(prev_alarm) {
/* there was an alarm() set before us, now put it back */
- unsigned long elapsed_secs = (unsigned long) (Curl_tvdiff(Curl_tvnow(),
- conn->created) / 1000);
+ timediff_t elapsed_secs = Curl_timediff(Curl_tvnow(),
+ conn->created) / 1000;
/* the alarm period is counted in even number of seconds */
unsigned long alarm_set = prev_alarm - elapsed_secs;
/* Handle timed out */
if(data->mstate == CURLM_STATE_WAITRESOLVE)
failf(data, "Resolving timed out after %ld milliseconds",
- Curl_tvdiff(now, data->progress.t_startsingle));
+ Curl_timediff(now, data->progress.t_startsingle));
else if(data->mstate == CURLM_STATE_WAITCONNECT)
failf(data, "Connection timed out after %ld milliseconds",
- Curl_tvdiff(now, data->progress.t_startsingle));
+ Curl_timediff(now, data->progress.t_startsingle));
else {
k = &data->req;
if(k->size != -1) {
failf(data, "Operation timed out after %ld milliseconds with %"
CURL_FORMAT_CURL_OFF_T " out of %"
CURL_FORMAT_CURL_OFF_T " bytes received",
- Curl_tvdiff(now, data->progress.t_startsingle),
+ Curl_timediff(now, data->progress.t_startsingle),
k->bytecount, k->size);
}
else {
failf(data, "Operation timed out after %ld milliseconds with %"
CURL_FORMAT_CURL_OFF_T " bytes received",
- Curl_tvdiff(now, data->progress.t_startsingle),
+ Curl_timediff(now, data->progress.t_startsingle),
k->bytecount);
}
}
timeout in *tv */
for(e = list->head; e;) {
struct curl_llist_element *n = e->next;
- time_t diff;
+ timediff_t diff;
node = (struct time_node *)e->ptr;
- diff = curlx_tvdiff(node->time, now);
+ diff = Curl_timediff(node->time, now);
if(diff <= 0)
/* remove outdated entry */
Curl_llist_remove(list, e, NULL);
if(Curl_splaycomparekeys(multi->timetree->key, now) > 0) {
/* some time left before expiration */
- *timeout_ms = (long)curlx_tvdiff(multi->timetree->key, now);
- if(!*timeout_ms)
+ timediff_t diff = Curl_timediff(multi->timetree->key, now);
+ if(diff <= 0)
/*
* Since we only provide millisecond resolution on the returned value
* and the diff might be less than one millisecond here, we don't
* millisecond! instead we return 1 until the time is ripe.
*/
*timeout_ms = 1;
+ else
+ /* this should be safe even on 64 bit archs, as we don't use that
+ overly long timeouts */
+ *timeout_ms = (long)diff;
}
else
/* 0 means immediately */
/* find the correct spot in the list */
for(e = timeoutlist->head; e; e = e->next) {
struct time_node *check = (struct time_node *)e->ptr;
- time_t diff = curlx_tvdiff(check->time, node->time);
+ timediff_t diff = Curl_timediff(check->time, node->time);
if(diff > 0)
break;
prev = e;
/* This means that the struct is added as a node in the splay tree.
Compare if the new time is earlier, and only remove-old/add-new if it
is. */
- time_t diff = curlx_tvdiff(set, *nowp);
+ timediff_t diff = Curl_timediff(set, *nowp);
if(diff > 0) {
/* The current splay tree entry is sooner than this new expiry time.
/* Without a requested timeout, we only wait 'response_time' seconds for the
full response to arrive before we bail out */
timeout_ms = response_time -
- Curl_tvdiff(Curl_tvnow(), pp->response); /* spent time */
+ Curl_timediff(Curl_tvnow(), pp->response); /* spent time */
if(data->set.timeout) {
/* if timeout is requested, find out how much remaining time we have */
timeout2_ms = data->set.timeout - /* timeout time */
- Curl_tvdiff(Curl_tvnow(), conn->now); /* spent time */
+ Curl_timediff(Curl_tvnow(), conn->now); /* spent time */
/* pick the lowest number */
timeout_ms = CURLMIN(timeout_ms, timeout2_ms);
/* this is the normal end-of-transfer thing */
break;
case TIMER_REDIRECT:
- data->progress.t_redirect = Curl_tvdiff_us(now, data->progress.start);
+ data->progress.t_redirect = Curl_timediff_us(now, data->progress.start);
break;
}
if(delta) {
- time_t us = Curl_tvdiff_us(now, data->progress.t_startsingle);
- if(!us)
- us++; /* make sure at least one microsecond passed */
+ timediff_t us = Curl_timediff_us(now, data->progress.t_startsingle);
+ if(us < 1)
+ us = 1; /* make sure at least one microsecond passed */
*delta += us;
}
}
return -1;
minimum = (time_t) (CURL_OFF_T_C(1000) * size / limit);
- actual = Curl_tvdiff(now, start);
+ actual = Curl_timediff(now, start);
if(actual < minimum)
/* this is a conversion on some systems (64bit time_t => 32bit long) */
now = Curl_tvnow(); /* what time is it */
/* The time spent so far (from the start) */
- data->progress.timespent = Curl_tvdiff_us(now, data->progress.start);
+ data->progress.timespent = Curl_timediff_us(now, data->progress.start);
timespent = (curl_off_t)data->progress.timespent/1000000; /* seconds */
/* The average download speed this far */
/* first of all, we don't do this if there's no counted seconds yet */
if(countindex) {
- time_t span_ms;
+ timediff_t span_ms;
/* Get the index position to compare with the 'nowindex' position.
Get the oldest entry possible. While we have less than CURR_TIME
data->progress.speeder_c%CURR_TIME:0;
/* Figure out the exact time for the time span */
- span_ms = Curl_tvdiff(now,
- data->progress.speeder_time[checkindex]);
+ span_ms = Curl_timediff(now,
+ data->progress.speeder_time[checkindex]);
if(0 == span_ms)
span_ms = 1; /* at least one millisecond MUST have passed */
#endif
if(!seeded) {
- struct curltime now = curlx_tvnow();
+ struct curltime now = Curl_tvnow();
infof(data, "WARNING: Using weak random seed\n");
randseed += (unsigned int)now.tv_usec + (unsigned int)now.tv_sec;
randseed = randseed * 1103515245 + 12345;
#include "warnless.h"
/* Convenience local macros */
-#define ELAPSED_MS() (int)curlx_tvdiff(curlx_tvnow(), initial_tv)
+#define ELAPSED_MS() (int)Curl_timediff(Curl_tvnow(), initial_tv)
int Curl_ack_eintr = 0;
#define ERROR_NOT_EINTR(error) (Curl_ack_eintr || error != EINTR)
Sleep(timeout_ms);
#else
pending_ms = timeout_ms;
- initial_tv = curlx_tvnow();
+ initial_tv = Curl_tvnow();
do {
#if defined(HAVE_POLL_FINE)
r = poll(NULL, 0, pending_ms);
if(timeout_ms > 0) {
pending_ms = (int)timeout_ms;
- initial_tv = curlx_tvnow();
+ initial_tv = Curl_tvnow();
}
#ifdef HAVE_POLL_FINE
if(timeout_ms > 0) {
pending_ms = timeout_ms;
- initial_tv = curlx_tvnow();
+ initial_tv = Curl_tvnow();
}
#ifdef HAVE_POLL_FINE
data->state.keeps_speed = now;
else {
/* how long has it been under the limit */
- time_t howlong = Curl_tvdiff(now, data->state.keeps_speed);
+ timediff_t howlong = Curl_timediff(now, data->state.keeps_speed);
if(howlong >= data->set.low_speed_time * 1000) {
/* too long */
if(data->set.timeout) {
now = Curl_tvnow();
- if(Curl_tvdiff(now, conn->created) >= data->set.timeout) {
+ if(Curl_timediff(now, conn->created) >= data->set.timeout) {
failf(data, "Time-out");
result = CURLE_OPERATION_TIMEDOUT;
keepon = FALSE;
if(data->set.timeout) {
now = Curl_tvnow();
- if(Curl_tvdiff(now, conn->created) >= data->set.timeout) {
+ if(Curl_timediff(now, conn->created) >= data->set.timeout) {
failf(data, "Time-out");
result = CURLE_OPERATION_TIMEDOUT;
keepon = FALSE;
#if defined(WIN32) && !defined(MSDOS)
-struct curltime curlx_tvnow(void)
+struct curltime Curl_tvnow(void)
{
/*
** GetTickCount() is available on _all_ Windows versions from W95 up
#elif defined(HAVE_CLOCK_GETTIME_MONOTONIC)
-struct curltime curlx_tvnow(void)
+struct curltime Curl_tvnow(void)
{
/*
** clock_gettime() is granted to be increased monotonically when the
#elif defined(HAVE_GETTIMEOFDAY)
-struct curltime curlx_tvnow(void)
+struct curltime Curl_tvnow(void)
{
/*
** gettimeofday() is not granted to be increased monotonically, due to
#else
-struct curltime curlx_tvnow(void)
+struct curltime Curl_tvnow(void)
{
/*
** time() returns the value of time in seconds since the Epoch.
#endif
+#if SIZEOF_TIME_T < 8
+#define TIME_MAX INT_MAX
+#define TIME_MIN INT_MIN
+#else
+#define TIME_MAX 9223372036854775807LL
+#define TIME_MIN -9223372036854775807LL
+#endif
+
/*
* Make sure that the first argument is the more recent time, as otherwise
* we'll get a weird negative time-diff back...
*
* @unittest: 1323
*/
-time_t curlx_tvdiff(struct curltime newer, struct curltime older)
+timediff_t Curl_timediff(struct curltime newer, struct curltime older)
{
-#if SIZEOF_TIME_T < 8
- /* for 32bit time_t systems, add a precaution to avoid overflow for really
- big time differences */
- time_t diff = newer.tv_sec-older.tv_sec;
- if(diff >= (0x7fffffff/1000))
- return 0x7fffffff;
-#endif
- return (newer.tv_sec-older.tv_sec)*1000+
- (int)(newer.tv_usec-older.tv_usec)/1000;
+ timediff_t diff = newer.tv_sec-older.tv_sec;
+ if(diff >= (TIME_MAX/1000))
+ return TIME_MAX;
+ else if(diff <= (TIME_MIN/1000))
+ return TIME_MIN;
+ return (timediff_t)(newer.tv_sec-older.tv_sec)*1000+
+ (timediff_t)(newer.tv_usec-older.tv_usec)/1000;
}
/*
* Returns: the time difference in number of microseconds. For too large diffs
* it returns max value.
*/
-time_t Curl_tvdiff_us(struct curltime newer, struct curltime older)
+timediff_t Curl_timediff_us(struct curltime newer, struct curltime older)
{
- time_t diff = newer.tv_sec-older.tv_sec;
-#if SIZEOF_TIME_T < 8
- /* for 32bit time_t systems */
- if(diff >= (0x7fffffff/1000000))
- return 0x7fffffff;
-#else
- /* for 64bit time_t systems */
- if(diff >= (0x7fffffffffffffffLL/1000000))
- return 0x7fffffffffffffffLL;
-#endif
- return (newer.tv_sec-older.tv_sec)*1000000+
- (int)(newer.tv_usec-older.tv_usec);
+ timediff_t diff = newer.tv_sec-older.tv_sec;
+ if(diff >= (TIME_MAX/1000000))
+ return TIME_MAX;
+ else if(diff <= (TIME_MIN/1000000))
+ return TIME_MIN;
+ return (timediff_t)(newer.tv_sec-older.tv_sec)*1000000+
+ (timediff_t)(newer.tv_usec-older.tv_usec);
}
*
***************************************************************************/
-/*
- * CAUTION: this header is designed to work when included by the app-side
- * as well as the library. Do not mix with library internals!
- */
-
#include "curl_setup.h"
+#if SIZEOF_TIME_T < 8
+typedef int timediff_t;
+#else
+typedef ssize_t timediff_t;
+#endif
+
+
struct curltime {
- time_t tv_sec; /* seconds */
- unsigned int tv_usec; /* microseconds */
+ time_t tv_sec; /* seconds */
+ int tv_usec; /* microseconds */
};
-struct curltime curlx_tvnow(void);
+struct curltime Curl_tvnow(void);
/*
* Make sure that the first argument (t1) is the more recent time and t2 is
*
* Returns: the time difference in number of milliseconds.
*/
-time_t curlx_tvdiff(struct curltime t1, struct curltime t2);
+timediff_t Curl_timediff(struct curltime t1, struct curltime t2);
/*
* Make sure that the first argument (t1) is the more recent time and t2 is
*
* Returns: the time difference in number of microseconds.
*/
-time_t Curl_tvdiff_us(struct curltime newer, struct curltime older);
-
-/* These two defines below exist to provide the older API for library
- internals only. */
-#define Curl_tvnow() curlx_tvnow()
-#define Curl_tvdiff(x,y) curlx_tvdiff(x,y)
+timediff_t Curl_timediff_us(struct curltime newer, struct curltime older);
#endif /* HEADER_CURL_TIMEVAL_H */
*/
- time_t ms = Curl_tvdiff(k->now, k->start100);
+ timediff_t ms = Curl_timediff(k->now, k->start100);
if(ms >= data->set.expect_100_timeout) {
/* we've waited long enough, continue anyway */
k->exp100 = EXP100_SEND_DATA;
failf(data, "Operation timed out after %ld milliseconds with %"
CURL_FORMAT_CURL_OFF_T " out of %"
CURL_FORMAT_CURL_OFF_T " bytes received",
- Curl_tvdiff(k->now, data->progress.t_startsingle), k->bytecount,
- k->size);
+ Curl_timediff(k->now, data->progress.t_startsingle),
+ k->bytecount, k->size);
}
else {
failf(data, "Operation timed out after %ld milliseconds with %"
CURL_FORMAT_CURL_OFF_T " bytes received",
- Curl_tvdiff(k->now, data->progress.t_startsingle), k->bytecount);
+ Curl_timediff(k->now, data->progress.t_startsingle),
+ k->bytecount);
}
return CURLE_OPERATION_TIMEDOUT;
}
struct curl_hash_iterator iter;
struct curl_llist_element *curr;
struct curl_hash_element *he;
- time_t highscore =- 1;
- time_t score;
+ timediff_t highscore =- 1;
+ timediff_t score;
struct curltime now;
struct connectdata *conn_candidate = NULL;
struct connectbundle *bundle;
if(!conn->inuse) {
/* Set higher score for the age passed since the connection was used */
- score = Curl_tvdiff(now, conn->now);
+ score = Curl_timediff(now, conn->now);
if(score > highscore) {
highscore = score;
struct connectbundle *bundle)
{
struct curl_llist_element *curr;
- time_t highscore = -1;
- time_t score;
+ timediff_t highscore = -1;
+ timediff_t score;
struct curltime now;
struct connectdata *conn_candidate = NULL;
struct connectdata *conn;
if(!conn->inuse) {
/* Set higher score for the age passed since the connection was used */
- score = Curl_tvdiff(now, conn->now);
+ score = Curl_timediff(now, conn->now);
if(score > highscore) {
highscore = score;
static void prune_dead_connections(struct Curl_easy *data)
{
struct curltime now = Curl_tvnow();
- time_t elapsed = Curl_tvdiff(now, data->state.conn_cache->last_cleanup);
+ time_t elapsed = Curl_timediff(now, data->state.conn_cache->last_cleanup);
if(elapsed >= 1000L) {
Curl_conncache_foreach(data->state.conn_cache, data,
size_t len = sizeof(randb);
size_t i, i_max;
for(i = 0, i_max = len / sizeof(struct curltime); i < i_max; ++i) {
- struct curltime tv = curlx_tvnow();
+ struct curltime tv = Curl_tvnow();
Curl_wait_ms(1);
tv.tv_sec *= i + 1;
tv.tv_usec *= (unsigned int)i + 2;
- tv.tv_sec ^= ((curlx_tvnow().tv_sec + curlx_tvnow().tv_usec) *
+ tv.tv_sec ^= ((Curl_tvnow().tv_sec + Curl_tvnow().tv_usec) *
(i + 3)) << 8;
- tv.tv_usec ^= (unsigned int) ((curlx_tvnow().tv_sec +
- curlx_tvnow().tv_usec) *
+ tv.tv_usec ^= (unsigned int) ((Curl_tvnow().tv_sec +
+ Curl_tvnow().tv_usec) *
(i + 4)) << 16;
memcpy(&randb[i * sizeof(struct curltime)], &tv,
sizeof(struct curltime));
../../lib/mprintf.c \
../../lib/nonblock.c \
../../lib/strtoofft.c \
- ../../lib/timeval.c \
../../lib/warnless.c
CURLX_HDRS = \
../../lib/curlx.h \
../../lib/nonblock.h \
../../lib/strtoofft.h \
- ../../lib/timeval.h \
../../lib/warnless.h
USEFUL = \
#endif /* w32api < 3.6 */
#endif /* ENABLE_IPV6 && __MINGW32__*/
+static struct timeval tvnow(void);
+
/* This function returns a pointer to STATIC memory. It converts the given
* binary lump to a hex formatted string usable for output in logs or
* whatever.
char buffer[2048 + 1];
FILE *logfp;
int error;
- struct curltime tv;
+ struct timeval tv;
time_t sec;
struct tm *now;
char timebuf[20];
return;
}
- tv = curlx_tvnow();
+ tv = tvnow();
if(!known_offset) {
epoch_offset = time(NULL) - tv.tv_sec;
known_offset = 1;
#ifndef HAVE_POLL_FINE
struct timeval pending_tv;
#endif
- struct curltime initial_tv;
+ struct timeval initial_tv;
int pending_ms;
int error;
#endif
Sleep(timeout_ms);
#else
pending_ms = timeout_ms;
- initial_tv = curlx_tvnow();
+ initial_tv = tvnow();
do {
#if defined(HAVE_POLL_FINE)
r = poll(NULL, 0, pending_ms);
error = errno;
if(error && (error != EINTR))
break;
- pending_ms = timeout_ms - (int)curlx_tvdiff(curlx_tvnow(), initial_tv);
+ pending_ms = timeout_ms - (int)timediff(tvnow(), initial_tv);
if(pending_ms <= 0)
break;
} while(r == -1);
return raw_toupper(*first) == raw_toupper(*second);
}
+
+#if defined(WIN32) && !defined(MSDOS)
+
+static struct timeval tvnow(void)
+{
+ /*
+ ** GetTickCount() is available on _all_ Windows versions from W95 up
+ ** to nowadays. Returns milliseconds elapsed since last system boot,
+ ** increases monotonically and wraps once 49.7 days have elapsed.
+ **
+ ** GetTickCount64() is available on Windows version from Windows Vista
+ ** and Windows Server 2008 up to nowadays. The resolution of the
+ ** function is limited to the resolution of the system timer, which
+ ** is typically in the range of 10 milliseconds to 16 milliseconds.
+ */
+ struct timeval now;
+#if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0600)
+ ULONGLONG milliseconds = GetTickCount64();
+#else
+ DWORD milliseconds = GetTickCount();
+#endif
+ now.tv_sec = (long)(milliseconds / 1000);
+ now.tv_usec = (milliseconds % 1000) * 1000;
+ return now;
+}
+
+#elif defined(HAVE_CLOCK_GETTIME_MONOTONIC)
+
+static struct timeval tvnow(void)
+{
+ /*
+ ** clock_gettime() is granted to be increased monotonically when the
+ ** monotonic clock is queried. Time starting point is unspecified, it
+ ** could be the system start-up time, the Epoch, or something else,
+ ** in any case the time starting point does not change once that the
+ ** system has started up.
+ */
+ struct timeval now;
+ struct timespec tsnow;
+ if(0 == clock_gettime(CLOCK_MONOTONIC, &tsnow)) {
+ now.tv_sec = tsnow.tv_sec;
+ now.tv_usec = tsnow.tv_nsec / 1000;
+ }
+ /*
+ ** Even when the configure process has truly detected monotonic clock
+ ** availability, it might happen that it is not actually available at
+ ** run-time. When this occurs simply fallback to other time source.
+ */
+#ifdef HAVE_GETTIMEOFDAY
+ else
+ (void)gettimeofday(&now, NULL);
+#else
+ else {
+ now.tv_sec = (long)time(NULL);
+ now.tv_usec = 0;
+ }
+#endif
+ return now;
+}
+
+#elif defined(HAVE_GETTIMEOFDAY)
+
+static struct timeval tvnow(void)
+{
+ /*
+ ** gettimeofday() is not granted to be increased monotonically, due to
+ ** clock drifting and external source time synchronization it can jump
+ ** forward or backward in time.
+ */
+ struct timeval now;
+ (void)gettimeofday(&now, NULL);
+ return now;
+}
+
+#else
+
+static struct timeval tvnow(void)
+{
+ /*
+ ** time() returns the value of time in seconds since the Epoch.
+ */
+ struct timeval now;
+ now.tv_sec = (long)time(NULL);
+ now.tv_usec = 0;
+ return now;
+}
+
+#endif
+
+long timediff(struct timeval newer, struct timeval older)
+{
+ timediff_t diff = newer.tv_sec-older.tv_sec;
+ if(diff >= (LONG_MAX/1000))
+ return LONG_MAX;
+ else if(diff <= (LONG_MIN/1000))
+ return LONG_MIN;
+ return (long)(newer.tv_sec-older.tv_sec)*1000+
+ (long)(newer.tv_usec-older.tv_usec)/1000;
+}
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
char *data_to_hex(char *data, size_t len);
void logmsg(const char *msg, ...);
+long timediff(struct timeval newer, struct timeval older);
#define TEST_DATA_PATH "%s/data/test%ld"
size_t i;
for(i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) {
- time_t result = curlx_tvdiff(tests[i].first, tests[i].second);
+ timediff_t result = Curl_timediff(tests[i].first, tests[i].second);
if(result != tests[i].result) {
printf("%d.%06u to %d.%06u got %d, but expected %d\n",
tests[i].first.tv_sec,