aboutsummaryrefslogtreecommitdiff
path: root/support
diff options
context:
space:
mode:
Diffstat (limited to 'support')
-rw-r--r--support/Makefile2
-rw-r--r--support/dtotimespec-time64.c27
-rw-r--r--support/dtotimespec.c50
-rw-r--r--support/shell-container.c28
-rw-r--r--support/timespec.h4
5 files changed, 111 insertions, 0 deletions
diff --git a/support/Makefile b/support/Makefile
index d52c472..05b3115 100644
--- a/support/Makefile
+++ b/support/Makefile
@@ -32,6 +32,8 @@ libsupport-routines = \
check_hostent \
check_netent \
delayed_exit \
+ dtotimespec \
+ dtotimespec-time64 \
ignore_stderr \
next_to_fault \
oom_error \
diff --git a/support/dtotimespec-time64.c b/support/dtotimespec-time64.c
new file mode 100644
index 0000000..b3d5e35
--- /dev/null
+++ b/support/dtotimespec-time64.c
@@ -0,0 +1,27 @@
+/* Convert double to timespec. 64-bit time support.
+ Copyright (C) 2011-2023 Free Software Foundation, Inc.
+ This file is part of the GNU C Library and is also part of gnulib.
+ Patches to this file should be submitted to both projects.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <time.h>
+
+#if __TIMESIZE != 64
+# define timespec __timespec64
+# define time_t __time64_t
+# define dtotimespec dtotimespec_time64
+# include "dtotimespec.c"
+#endif
diff --git a/support/dtotimespec.c b/support/dtotimespec.c
new file mode 100644
index 0000000..cde5b4d
--- /dev/null
+++ b/support/dtotimespec.c
@@ -0,0 +1,50 @@
+/* Convert double to timespec.
+ Copyright (C) 2011-2023 Free Software Foundation, Inc.
+ This file is part of the GNU C Library and is also part of gnulib.
+ Patches to this file should be submitted to both projects.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+/* Convert the double value SEC to a struct timespec. Round toward
+ positive infinity. On overflow, return an extremal value. */
+
+#include <support/timespec.h>
+#include <intprops.h>
+
+struct timespec
+dtotimespec (double sec)
+{
+ if (sec <= TYPE_MINIMUM (time_t))
+ return make_timespec (TYPE_MINIMUM (time_t), 0);
+ else if (sec >= 1.0 + TYPE_MAXIMUM (time_t))
+ return make_timespec (TYPE_MAXIMUM (time_t), TIMESPEC_HZ - 1);
+ else
+ {
+ time_t s = sec;
+ double frac = TIMESPEC_HZ * (sec - s);
+ long ns = frac;
+ ns += ns < frac;
+ s += ns / TIMESPEC_HZ;
+ ns %= TIMESPEC_HZ;
+
+ if (ns < 0)
+ {
+ s--;
+ ns += TIMESPEC_HZ;
+ }
+
+ return make_timespec (s, ns);
+ }
+}
diff --git a/support/shell-container.c b/support/shell-container.c
index ffa3378..b1f9e79 100644
--- a/support/shell-container.c
+++ b/support/shell-container.c
@@ -37,6 +37,7 @@
#include <error.h>
#include <support/support.h>
+#include <support/timespec.h>
/* Design considerations
@@ -169,6 +170,32 @@ kill_func (char **argv)
return 0;
}
+/* Emulate the "/bin/sleep" command. No suffix support. Options are
+ ignored. */
+static int
+sleep_func (char **argv)
+{
+ if (argv[0] == NULL)
+ {
+ fprintf (stderr, "sleep: missing operand\n");
+ return 1;
+ }
+ char *endptr = NULL;
+ double sec = strtod (argv[0], &endptr);
+ if (endptr == argv[0] || errno == ERANGE || sec < 0)
+ {
+ fprintf (stderr, "sleep: invalid time interval '%s'\n", argv[0]);
+ return 1;
+ }
+ struct timespec ts = dtotimespec (sec);
+ if (nanosleep (&ts, NULL) < 0)
+ {
+ fprintf (stderr, "sleep: failed to nanosleep: %s\n", strerror (errno));
+ return 1;
+ }
+ return 0;
+}
+
/* This is a list of all the built-in commands we understand. */
static struct {
const char *name;
@@ -179,6 +206,7 @@ static struct {
{ "cp", copy_func },
{ "exit", exit_func },
{ "kill", kill_func },
+ { "sleep", sleep_func },
{ NULL, NULL }
};
diff --git a/support/timespec.h b/support/timespec.h
index 77b1e4e..9559836 100644
--- a/support/timespec.h
+++ b/support/timespec.h
@@ -57,6 +57,8 @@ int support_timespec_check_in_range (struct timespec expected,
struct timespec observed,
double lower_bound, double upper_bound);
+struct timespec dtotimespec (double sec) __attribute__((const));
+
#else
struct timespec __REDIRECT (timespec_add, (struct timespec, struct timespec),
timespec_add_time64);
@@ -82,6 +84,8 @@ int __REDIRECT (support_timespec_check_in_range, (struct timespec expected,
double lower_bound,
double upper_bound),
support_timespec_check_in_range_time64);
+
+struct timespec __REDIRECT (dtotimespec, (double sec), dtotimespec_time64);
#endif
/* Check that the timespec on the left represents a time before the