From a838b6a657353350066254e83e1a2a95112dbcea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Josef=20S=C3=B6ntgen?= Date: Mon, 26 Jan 2015 13:51:31 +0100 Subject: [PATCH] noux: add local nanosleep(2) and sleep(3) Up to now Noux used the libc sleep functions, which actually is not possible because the _nanosleep() function implemented by our libc creates a new thread to handle the timeout. Noux childs may have only one thread, e.g., the main thread, though. To fix this issue sleeping is now handled directly by Noux. It is implemented by calling select(2) with a timeout. This fix is needed for mutt(1), which calls sleep when it prints a notification for the user. Fixes #1374. --- repos/ports/src/lib/libc_noux/plugin.cc | 44 +++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/repos/ports/src/lib/libc_noux/plugin.cc b/repos/ports/src/lib/libc_noux/plugin.cc index 11ee4bb800..18d7df47c2 100644 --- a/repos/ports/src/lib/libc_noux/plugin.cc +++ b/repos/ports/src/lib/libc_noux/plugin.cc @@ -657,6 +657,50 @@ extern "C" int kill(int pid, int sig) } +extern "C" int nanosleep(const struct timespec *timeout, + struct timespec *remainder) +{ + Noux::Sysio::Select_fds &in_fds = sysio()->select_in.fds; + + in_fds.num_rd = 0; + in_fds.num_wr = 0; + in_fds.num_ex = 0; + + sysio()->select_in.timeout.sec = timeout->tv_sec; + sysio()->select_in.timeout.usec = timeout->tv_nsec / 1000; + + /* + * Perform syscall + */ + if (!noux_syscall(Noux::Session::SYSCALL_SELECT)) { + switch (sysio()->error.select) { + case Noux::Sysio::SELECT_ERR_INTERRUPT: errno = EINTR; break; + } + + return -1; + } + + if (remainder) { + remainder->tv_sec = 0; + remainder->tv_nsec = 0; + } + + return 0; +} + + +extern "C" unsigned int sleep(unsigned int seconds) +{ + struct timespec dummy = { seconds, 0 }; + + /* + * Always return 0 because our nanosleep() cannot not be interrupted. + */ + nanosleep(&dummy, 0); + return 0; +} + + /******************** ** Time functions ** ********************/