smtp: use the upload buffer size for scratch buffer malloc
[platform/upstream/curl.git] / lib / timeval.c
index 664f6a9..66f923a 100644 (file)
-/*****************************************************************************
- *                                  _   _ ____  _     
- *  Project                     ___| | | |  _ \| |    
- *                             / __| | | | |_) | |    
- *                            | (__| |_| |  _ <| |___ 
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2002, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
- * In order to be useful for every potential user, curl and libcurl are
- * dual-licensed under the MPL and the MIT/X-derivate licenses.
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the MPL or the MIT/X-derivate
- * licenses. You may pick one of these licenses.
+ * furnished to do so, under the terms of the COPYING file.
  *
  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
  * KIND, either express or implied.
  *
- * $Id$
- *****************************************************************************/
+ ***************************************************************************/
 
-#ifdef WIN32
-#include <windows.h>
-#endif
 #include "timeval.h"
 
-#ifndef HAVE_GETTIMEOFDAY
+#if defined(WIN32) && !defined(MSDOS)
 
-#ifdef WIN32
-int
-gettimeofday (struct timeval *tp, void *nothing)
+struct curltime Curl_now(void)
 {
-#ifdef WITHOUT_MM_LIB
-  SYSTEMTIME st;
-  time_t tt;
-  struct tm tmtm;
-  /* mktime converts local to UTC */
-  GetLocalTime (&st);
-  tmtm.tm_sec = st.wSecond;
-  tmtm.tm_min = st.wMinute;
-  tmtm.tm_hour = st.wHour;
-  tmtm.tm_mday = st.wDay;
-  tmtm.tm_mon = st.wMonth - 1;
-  tmtm.tm_year = st.wYear - 1900;
-  tmtm.tm_isdst = -1;
-  tt = mktime (&tmtm);
-  tp->tv_sec = tt;
-  tp->tv_usec = st.wMilliseconds * 1000;
+  /*
+  ** 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.
+  */
+  struct curltime now;
+#if !defined(_WIN32_WINNT) || !defined(_WIN32_WINNT_VISTA) || \
+    (_WIN32_WINNT < _WIN32_WINNT_VISTA)
+  DWORD milliseconds = GetTickCount();
+  now.tv_sec = milliseconds / 1000;
+  now.tv_usec = (milliseconds % 1000) * 1000;
 #else
-  /**
-   ** The earlier time calculations using GetLocalTime
-   ** had a time resolution of 10ms.The timeGetTime, part
-   ** of multimedia apis offer a better time resolution
-   ** of 1ms.Need to link against winmm.lib for this
-   **/
-  unsigned long Ticks = 0;
-  unsigned long Sec =0;
-  unsigned long Usec = 0;
-  Ticks = timeGetTime();
-
-  Sec = Ticks/1000;
-  Usec = (Ticks - (Sec*1000))*1000;
-  tp->tv_sec = Sec;
-  tp->tv_usec = Usec;
+  ULONGLONG milliseconds = GetTickCount64();
+  now.tv_sec = (time_t) (milliseconds / 1000);
+  now.tv_usec = (unsigned int) (milliseconds % 1000) * 1000;
 #endif
-  return 1;
+
+  return now;
 }
-#define HAVE_GETTIMEOFDAY
-#endif
-#endif
 
-struct timeval Curl_tvnow (void)
+#elif defined(HAVE_CLOCK_GETTIME_MONOTONIC)
+
+struct curltime Curl_now(void)
 {
- struct timeval now;
+  /*
+  ** 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 curltime cnow;
+  struct timespec tsnow;
+  if(0 == clock_gettime(CLOCK_MONOTONIC, &tsnow)) {
+    cnow.tv_sec = tsnow.tv_sec;
+    cnow.tv_usec = (unsigned int)(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
- gettimeofday (&now, NULL);
+  else {
+    (void)gettimeofday(&now, NULL);
+    cnow.tv_sec = now.tv_sec;
+    cnow.tv_usec = (unsigned int)now.tv_usec;
+  }
 #else
- now.tv_sec = (long) time(NULL);
- now.tv_usec = 0;
+  else {
+    cnow.tv_sec = time(NULL);
+    cnow.tv_usec = 0;
+  }
 #endif
return now;
 return cnow;
 }
 
-/*
- * Make sure that the first argument is the more recent time, as otherwise
- * we'll get a weird negative time-diff back...
- */
-long Curl_tvdiff (struct timeval newer, struct timeval older)
+#elif defined(HAVE_MACH_ABSOLUTE_TIME)
+
+#include <stdint.h>
+#include <mach/mach_time.h>
+
+struct curltime Curl_now(void)
+{
+  /*
+  ** Monotonic timer on Mac OS is provided by mach_absolute_time(), which
+  ** returns time in Mach "absolute time units," which are platform-dependent.
+  ** To convert to nanoseconds, one must use conversion factors specified by
+  ** mach_timebase_info().
+  */
+  static mach_timebase_info_data_t timebase;
+  struct curltime cnow;
+  uint64_t usecs;
+
+  if(0 == timebase.denom)
+    (void) mach_timebase_info(&timebase);
+
+  usecs = mach_absolute_time();
+  usecs *= timebase.numer;
+  usecs /= timebase.denom;
+  usecs /= 1000;
+
+  cnow.tv_sec = usecs / 1000000;
+  cnow.tv_usec = usecs % 1000000;
+
+  return cnow;
+}
+
+#elif defined(HAVE_GETTIMEOFDAY)
+
+struct curltime Curl_now(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;
+  struct curltime ret;
+  (void)gettimeofday(&now, NULL);
+  ret.tv_sec = now.tv_sec;
+  ret.tv_usec = now.tv_usec;
+  return ret;
+}
+
+#else
+
+struct curltime Curl_now(void)
 {
-  return (newer.tv_sec-older.tv_sec)*1000+
-    (499+newer.tv_usec-older.tv_usec)/1000;
+  /*
+  ** time() returns the value of time in seconds since the Epoch.
+  */
+  struct curltime now;
+  now.tv_sec = time(NULL);
+  now.tv_usec = 0;
+  return now;
 }
 
-long Curl_tvlong (struct timeval t1)
+#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
+
+/*
+ * Returns: time difference in number of milliseconds. For too large diffs it
+ * returns max value.
+ *
+ * @unittest: 1323
+ */
+timediff_t Curl_timediff(struct curltime newer, struct curltime older)
 {
- return t1.tv_sec;
+  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 diff * 1000 + (newer.tv_usec-older.tv_usec)/1000;
 }
 
 /*
- * local variables:
- * eval: (load-file "../curl-mode.el")
- * end:
- * vim600: fdm=marker
- * vim: et sw=2 ts=2 sts=2 tw=78
+ * Returns: time difference in number of microseconds. For too large diffs it
+ * returns max value.
  */
+timediff_t Curl_timediff_us(struct curltime newer, struct curltime older)
+{
+  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 diff * 1000000 + newer.tv_usec-older.tv_usec;
+}