aboutsummaryrefslogtreecommitdiffstats
path: root/extension/time.c
diff options
context:
space:
mode:
Diffstat (limited to 'extension/time.c')
-rw-r--r--extension/time.c167
1 files changed, 167 insertions, 0 deletions
diff --git a/extension/time.c b/extension/time.c
new file mode 100644
index 00000000..4f590c88
--- /dev/null
+++ b/extension/time.c
@@ -0,0 +1,167 @@
+/*
+ * time.c - Builtin functions that provide time-related functions.
+ *
+ */
+
+/*
+ * Copyright (C) 2012
+ * the Free Software Foundation, Inc.
+ *
+ * This file is part of GAWK, the GNU implementation of the
+ * AWK Programming Language.
+ *
+ * GAWK is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GAWK is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include "config.h"
+#include "gawkapi.h"
+
+static const gawk_api_t *api; /* for convenience macros to work */
+static awk_ext_id_t *ext_id;
+
+int plugin_is_GPL_compatible;
+
+#if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H)
+#include <sys/time.h>
+#endif
+#if defined(HAVE_SELECT) && defined(HAVE_SYS_SELECT_H)
+#include <sys/select.h>
+#endif
+#if defined(HAVE_NANOSLEEP) && defined(HAVE_TIME_H)
+#include <time.h>
+#endif
+
+#define RETURN return tmp_number((AWKNUM) 0)
+
+/*
+ * Returns time since 1/1/1970 UTC as a floating point value; should
+ * have sub-second precision, but the actual precision will vary based
+ * on the platform
+ */
+static awk_value_t *
+do_gettimeofday(int nargs, awk_value_t *result)
+{
+ double curtime;
+
+ if (do_lint && nargs > 0)
+ lintwarn(ext_id, "gettimeofday: ignoring arguments");
+
+#if defined(HAVE_GETTIMEOFDAY)
+ {
+ struct timeval tv;
+ gettimeofday(&tv,NULL);
+ curtime = tv.tv_sec+(tv.tv_usec/1000000.0);
+ }
+#elif defined(HAVE_GETSYSTEMTIMEASFILETIME)
+ /* based on perl win32/win32.c:win32_gettimeofday() implementation */
+ {
+ union {
+ unsigned __int64 ft_i64;
+ FILETIME ft_val;
+ } ft;
+
+ /* # of 100-nanosecond intervals since January 1, 1601 (UTC) */
+ GetSystemTimeAsFileTime(&ft.ft_val);
+#ifdef __GNUC__
+#define Const64(x) x##LL
+#else
+#define Const64(x) x##i64
+#endif
+/* Number of 100 nanosecond units from 1/1/1601 to 1/1/1970 */
+#define EPOCH_BIAS Const64(116444736000000000)
+ curtime = (ft.ft_i64 - EPOCH_BIAS)/10000000.0;
+#undef Const64
+ }
+#else
+ /* no way to retrieve system time on this platform */
+ curtime = -1;
+ update_ERRNO_string("gettimeofday: not supported on this platform", 1);
+#endif
+
+ return make_number(curtime, result);
+}
+
+/*
+ * Returns 0 if successful in sleeping the requested time;
+ * returns -1 if there is no platform support, or if the sleep request
+ * did not complete successfully (perhaps interrupted)
+ */
+static awk_value_t *
+do_sleep(int nargs, awk_value_t *result)
+{
+ awk_value_t num;
+ double secs;
+ int rc;
+
+ if (do_lint && nargs > 1)
+ lintwarn(ext_id, "sleep: called with too many arguments");
+
+
+ if (get_curfunc_param(0, AWK_NUMBER, &num) == NULL) {
+ update_ERRNO_string("sleep: missing required numeric argument", 1);
+ return make_number(-1, result);
+ }
+ secs = num.num_value;
+
+ if (secs < 0) {
+ update_ERRNO_string("sleep: argument is negative", 1);
+ return make_number(-1, result);
+ }
+
+#if defined(HAVE_NANOSLEEP)
+ {
+ struct timespec req;
+
+ req.tv_sec = secs;
+ req.tv_nsec = (secs-(double)req.tv_sec)*1000000000.0;
+ if ((rc = nanosleep(&req,NULL)) < 0)
+ /* probably interrupted */
+ update_ERRNO_int(errno);
+ }
+#elif defined(HAVE_SELECT)
+ {
+ struct timeval timeout;
+
+ timeout.tv_sec = secs;
+ timeout.tv_usec = (secs-(double)timeout.tv_sec)*1000000.0;
+ if ((rc = select(0,NULL,NULL,NULL,&timeout)) < 0)
+ /* probably interrupted */
+ update_ERRNO_int(errno);
+ }
+#else
+ /* no way to sleep on this platform */
+ rc = -1;
+ set_ERRNO("sleep: not supported on this platform");
+#endif
+
+ return make_number(rc, result);
+}
+
+static awk_ext_func_t func_table[] = {
+ { "gettimeofday", do_gettimeofday, 0 },
+ { "sleep", do_sleep, 1 },
+};
+
+/* define the dl_load function using the boilerplate macro */
+
+dl_load_func(func_table, time, "")