[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: usleep
From: |
Eric Blake |
Subject: |
Re: usleep |
Date: |
Wed, 18 Nov 2009 22:16:05 -0700 |
User-agent: |
Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.23) Gecko/20090812 Thunderbird/2.0.0.23 Mnenhy/0.7.6.666 |
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
According to Eric Blake on 11/18/2009 5:56 PM:
> Yep. I'll fix it in my respin. Besides, I found out that rpl_nanosleep
> needs the same bug fix, and not only that, but it has a logic bug - it
> ignores EINTR, forcing the sleep to last until a fatal signal or the
> entire time has elapsed, on systems where the remaining time properly
> decreases. Worse, it goes into an infinite 100% CPU busy loop on cygwin
Actually, the infloop occurs on any platform with nanosleep, if tv_nsec is
out of range. coreutils' sleep(1) was immune, since it always used valid
arguments.
At any rate, here's what I'm now testing, it has passed on cygwin, 64-bit
Linux, and Solaris. The nanosleep code is a complete rewrite, and is
actually lighter-weight (no need to use clock_gettime). Unfortunately,
cross-compiling to mingw is still failing two tests; so some more coding
efforts are needed beyond this preliminary patch.
test-nanosleep.c:60: assertion failed
FAIL: test-nanosleep.exe
[no message; often indicative of stack overflow]
FAIL: test-select-out.sh
- --
Don't work too hard, make some time for fun as well!
Eric Blake address@hidden
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (Cygwin)
Comment: Public key at home.comcast.net/~ericblake/eblake.gpg
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/
iEYEARECAAYFAksE1JUACgkQ84KuGfSFAYB4aACePTAguHKT8tFaLZrzt6RmXdm3
3h4AoKhykPz9QScc3obGsRW4seBzwnhh
=TUNJ
-----END PGP SIGNATURE-----
From e1861efe151da62ff1c8ca10b42fec99f9409a8f Mon Sep 17 00:00:00 2001
From: Eric Blake <address@hidden>
Date: Wed, 18 Nov 2009 20:07:44 -0700
Subject: [PATCH 1/4] sleep: work around cygwin bug
On cygwin 1.5.x, sleep amounts larger than 49.7 days (2**32
milliseconds) failed instantly, but with a garbage return
value from uninitialized memory.
* lib/sleep.c (rpl_sleep): Work around the bug.
* m4/sleep.m4 (gl_FUNC_SLEEP): Detect the bug.
(gl_PREREQ_SLEEP): Delete unused macro.
* modules/sleep (Depends-on): Add verify.
* m4/unistd_h.m4 (gl_UNISTD_H_DEFAULTS): Add default.
* modules/unistd (Makefile.am): Substitute witness.
* lib/unistd.in.h (sleep): Update prototype.
* doc/posix-functions/sleep.texi (sleep): Document the bug.
* tests/test-sleep.c (main) [HAVE_DECL_ALARM]: Test it.
* modules/sleep-tests (Depends-on): Check for alarm.
Signed-off-by: Eric Blake <address@hidden>
---
ChangeLog | 12 ++++++++++++
doc/posix-functions/sleep.texi | 3 +++
lib/sleep.c | 33 +++++++++++++++++++++++++++++++--
lib/unistd.in.h | 6 +++++-
m4/sleep.m4 | 37 +++++++++++++++++++++++++++++++------
m4/unistd_h.m4 | 3 ++-
modules/sleep | 2 ++
modules/sleep-tests | 2 +-
modules/unistd | 1 +
tests/test-sleep.c | 40 ++++++++++++++++++++++++++++++----------
10 files changed, 118 insertions(+), 21 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index a868d1d..ac96813 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,17 @@
2009-11-18 Eric Blake <address@hidden>
+ sleep: work around cygwin bug
+ * lib/sleep.c (rpl_sleep): Work around the bug.
+ * m4/sleep.m4 (gl_FUNC_SLEEP): Detect the bug.
+ (gl_PREREQ_SLEEP): Delete unused macro.
+ * modules/sleep (Depends-on): Add verify.
+ * m4/unistd_h.m4 (gl_UNISTD_H_DEFAULTS): Add default.
+ * modules/unistd (Makefile.am): Substitute witness.
+ * lib/unistd.in.h (sleep): Update prototype.
+ * doc/posix-functions/sleep.texi (sleep): Document the bug.
+ * tests/test-sleep.c (main) [HAVE_DECL_ALARM]: Test it.
+ * modules/sleep-tests (Depends-on): Check for alarm.
+
tests: avoid false negative with --with-packager
* tests/test-version-etc.sh: Discard packager information.
* tests/test-argp-version-etc-1.sh: Likewise.
diff --git a/doc/posix-functions/sleep.texi b/doc/posix-functions/sleep.texi
index 9a7a74f..6df8693 100644
--- a/doc/posix-functions/sleep.texi
+++ b/doc/posix-functions/sleep.texi
@@ -15,6 +15,9 @@ sleep
This function takes milliseconds as argument and returns @code{void} on some
platforms:
mingw (2005 and older).
address@hidden
+This function cannot sleep longer than 49.7 days on some platforms:
+Cygwin 1.5.x.
@end itemize
Portability problems not fixed by Gnulib:
diff --git a/lib/sleep.c b/lib/sleep.c
index 9c56b9b..90b482c 100644
--- a/lib/sleep.c
+++ b/lib/sleep.c
@@ -1,5 +1,5 @@
/* Pausing execution of the current thread.
- Copyright (C) 2007 Free Software Foundation, Inc.
+ Copyright (C) 2007, 2009 Free Software Foundation, Inc.
Written by Bruno Haible <address@hidden>, 2007.
This program is free software: you can redistribute it and/or modify
@@ -20,6 +20,10 @@
/* Specification. */
#include <unistd.h>
+#include <limits.h>
+
+#include "verify.h"
+
#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
# define WIN32_LEAN_AND_MEAN /* avoid including junk */
@@ -39,7 +43,32 @@ sleep (unsigned int seconds)
return remaining;
}
-#else
+#elif HAVE_SLEEP
+
+# undef sleep
+
+/* Guarantee unlimited sleep and a reasonable return value. Cygwin
+ 1.5.x rejects attempts to sleep more than 49.7 days (2**32
+ milliseconds), but uses uninitialized memory which results in a
+ garbage answer. */
+unsigned int
+rpl_sleep (unsigned int seconds)
+{
+ /* This requires int larger than 16 bits. */
+ verify (UINT_MAX / 49 / 24 / 60 / 60);
+ const unsigned int limit = 49 * 24 * 60 * 60;
+ while (limit < seconds)
+ {
+ unsigned int result;
+ seconds -= limit;
+ result = sleep (limit);
+ if (result)
+ return seconds + result;
+ }
+ return sleep (seconds);
+}
+
+#else /* !HAVE_SLEEP */
#error "Please port gnulib sleep.c to your platform, possibly using usleep()
or select(), then report this to bug-gnulib."
diff --git a/lib/unistd.in.h b/lib/unistd.in.h
index 30f7bdd..9a9a671 100644
--- a/lib/unistd.in.h
+++ b/lib/unistd.in.h
@@ -714,11 +714,15 @@ extern int rmdir (char const *name);
#if @GNULIB_SLEEP@
+# if @REPLACE_SLEEP@
+# undef sleep
+# define sleep rpl_sleep
+# endif
/* Pause the execution of the current thread for N seconds.
Returns the number of seconds left to sleep.
See the POSIX:2001 specification
<http://www.opengroup.org/susv3xsh/sleep.html>. */
-# if address@hidden@
+# if address@hidden@ || @REPLACE_SLEEP@
extern unsigned int sleep (unsigned int n);
# endif
#elif defined GNULIB_POSIXCHECK
diff --git a/m4/sleep.m4 b/m4/sleep.m4
index 474ba07..c59b383 100644
--- a/m4/sleep.m4
+++ b/m4/sleep.m4
@@ -1,5 +1,5 @@
-# sleep.m4 serial 2
-dnl Copyright (C) 2007-2008 Free Software Foundation, Inc.
+# sleep.m4 serial 3
+dnl Copyright (C) 2007-2009 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
@@ -13,12 +13,37 @@ AC_DEFUN([gl_FUNC_SLEEP],
dnl it takes the number of milliseconds as argument and returns void.
dnl mingw does not declare this function.
AC_CHECK_DECLS([sleep], , , [#include <unistd.h>])
+ AC_CHECK_FUNCS_ONCE([sleep])
if test $ac_cv_have_decl_sleep != yes; then
HAVE_SLEEP=0
AC_LIBOBJ([sleep])
- gl_PREREQ_SLEEP
+ else
+ dnl Cygwin 1.5.x has a bug where sleep can't exceed 49.7 days.
+ AC_CACHE_CHECK([for working sleep], [gl_cv_func_sleep_works],
+ [AC_RUN_IFELSE([AC_LANG_PROGRAM([[
+#include <errno.h>
+#include <unistd.h>
+#include <signal.h>
+static void
+handle_alarm (int sig)
+{
+ if (sig != SIGALRM)
+ _exit (2);
+}
+]], [[
+ /* Failure to compile this test due to missing alarm is okay,
+ since all such platforms (mingw) also lack sleep. */
+ unsigned int pentecost = 50 * 24 * 60 * 60; /* 50 days. */
+ unsigned int remaining;
+ signal (SIGALRM, handle_alarm);
+ alarm (1);
+ remaining = sleep (pentecost);
+ return !(pentecost - 10 < remaining && remaining <= pentecost);]])],
+ [gl_cv_func_sleep_works=yes], [gl_cv_func_sleep_works=no],
+ [gl_cv_func_sleep_works="guessing no"])])
+ if test "$gl_cv_func_sleep_works" != yes; then
+ REPLACE_SLEEP=1
+ AC_LIBOBJ([sleep])
+ fi
fi
])
-
-# Prerequisites of lib/sleep.c.
-AC_DEFUN([gl_PREREQ_SLEEP], [:])
diff --git a/m4/unistd_h.m4 b/m4/unistd_h.m4
index 25bdb59..0a5b5d5 100644
--- a/m4/unistd_h.m4
+++ b/m4/unistd_h.m4
@@ -1,4 +1,4 @@
-# unistd_h.m4 serial 35
+# unistd_h.m4 serial 36
dnl Copyright (C) 2006-2009 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
@@ -113,6 +113,7 @@ AC_DEFUN([gl_UNISTD_H_DEFAULTS],
REPLACE_LSEEK=0; AC_SUBST([REPLACE_LSEEK])
REPLACE_READLINK=0; AC_SUBST([REPLACE_READLINK])
REPLACE_RMDIR=0; AC_SUBST([REPLACE_RMDIR])
+ REPLACE_SLEEP=0; AC_SUBST([REPLACE_SLEEP])
REPLACE_SYMLINK=0; AC_SUBST([REPLACE_SYMLINK])
REPLACE_UNLINK=0; AC_SUBST([REPLACE_UNLINK])
REPLACE_UNLINKAT=0; AC_SUBST([REPLACE_UNLINKAT])
diff --git a/modules/sleep b/modules/sleep
index d8af514..e859e59 100644
--- a/modules/sleep
+++ b/modules/sleep
@@ -6,7 +6,9 @@ lib/sleep.c
m4/sleep.m4
Depends-on:
+stdint
unistd
+verify
configure.ac:
gl_FUNC_SLEEP
diff --git a/modules/sleep-tests b/modules/sleep-tests
index 91de2ee..0871d51 100644
--- a/modules/sleep-tests
+++ b/modules/sleep-tests
@@ -4,8 +4,8 @@ tests/test-sleep.c
Depends-on:
configure.ac:
+AC_CHECK_DECLS_ONCE([alarm])
Makefile.am:
TESTS += test-sleep
check_PROGRAMS += test-sleep
-
diff --git a/modules/unistd b/modules/unistd
index 008ccdf..1282e53 100644
--- a/modules/unistd
+++ b/modules/unistd
@@ -105,6 +105,7 @@ unistd.h: unistd.in.h
-e 's|@''REPLACE_LSEEK''@|$(REPLACE_LSEEK)|g' \
-e 's|@''REPLACE_READLINK''@|$(REPLACE_READLINK)|g' \
-e 's|@''REPLACE_RMDIR''@|$(REPLACE_RMDIR)|g' \
+ -e 's|@''REPLACE_SLEEP''@|$(REPLACE_SLEEP)|g' \
-e 's|@''REPLACE_SYMLINK''@|$(REPLACE_SYMLINK)|g' \
-e 's|@''REPLACE_UNLINK''@|$(REPLACE_UNLINK)|g' \
-e 's|@''REPLACE_UNLINKAT''@|$(REPLACE_UNLINKAT)|g' \
diff --git a/tests/test-sleep.c b/tests/test-sleep.c
index ed5a5a0..48abce1 100644
--- a/tests/test-sleep.c
+++ b/tests/test-sleep.c
@@ -1,5 +1,5 @@
/* Test of sleep() function.
- Copyright (C) 2007-2008 Free Software Foundation, Inc.
+ Copyright (C) 2007-2009 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -20,21 +20,31 @@
#include <unistd.h>
+#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#define ASSERT(expr) \
- do \
- { \
- if (!(expr)) \
- { \
+ do \
+ { \
+ if (!(expr)) \
+ { \
fprintf (stderr, "%s:%d: assertion failed\n", __FILE__, __LINE__); \
- fflush (stderr); \
- abort (); \
- } \
- } \
+ fflush (stderr); \
+ abort (); \
+ } \
+ } \
while (0)
+#if HAVE_DECL_ALARM
+static void
+handle_alarm (int sig)
+{
+ if (sig != SIGALRM)
+ _exit (1);
+}
+#endif
+
int
main()
{
@@ -42,6 +52,16 @@ main()
ASSERT (sleep (0) == 0);
+#if HAVE_DECL_ALARM
+ {
+ const unsigned int pentecost = 50 * 24 * 60 * 60; /* 50 days. */
+ unsigned int remaining;
+ signal (SIGALRM, handle_alarm);
+ alarm (1);
+ remaining = sleep (pentecost);
+ ASSERT (pentecost - 10 < remaining && remaining <= pentecost);
+ }
+#endif
+
return 0;
}
-
--
1.6.5.rc1
From 3ae558b1bc0ff294c6f097504a6fd8bd983ab4bc Mon Sep 17 00:00:00 2001
From: Eric Blake <address@hidden>
Date: Wed, 18 Nov 2009 20:10:42 -0700
Subject: [PATCH 2/4] nanosleep: work around cygwin bug
Cygwin 1.5.x mistakenly failed with EINVAL for a duration longer
than 49.7 days (2**32 milliseconds). Meanwhile, the existing
code for HAVE_BUG_BIG_NANOSLEEP would infloop, instead of return
failure, for invalid arguments.
* lib/nanosleep.c (rpl_nanosleep) [HAVE_BUG_BIG_NANOSLEEP]:
Fix logic bug when nanosleep fails. Work around cygwin 1.5.x
bug.
(getnow): Delete, not needed.
* m4/nanosleep.m4 (gl_FUNC_NANOSLEEP): No longer require
LIB_CLOCK_GETTIME.
* modules/nanosleep (Depends-on): Add intprops and verify. Drop
clock-time, gettime.
* doc/posix-functions/nanosleep.texi (nanosleep): Document the
bug.
* modules/nanosleep-tests: New test.
* tests/test-nanosleep.c: New file.
Signed-off-by: Eric Blake <address@hidden>
---
ChangeLog | 14 +++++
doc/posix-functions/nanosleep.texi | 3 +
lib/nanosleep.c | 82 ++++++++++++++-----------------
m4/nanosleep.m4 | 9 +---
modules/nanosleep | 4 +-
modules/nanosleep-tests | 12 +++++
tests/test-nanosleep.c | 94 ++++++++++++++++++++++++++++++++++++
7 files changed, 162 insertions(+), 56 deletions(-)
create mode 100644 modules/nanosleep-tests
create mode 100644 tests/test-nanosleep.c
diff --git a/ChangeLog b/ChangeLog
index ac96813..5bd4205 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,19 @@
2009-11-18 Eric Blake <address@hidden>
+ nanosleep: work around cygwin bug
+ * lib/nanosleep.c (rpl_nanosleep) [HAVE_BUG_BIG_NANOSLEEP]:
+ Fix logic bug when nanosleep fails. Work around cygwin 1.5.x
+ bug.
+ (getnow): Delete, not needed.
+ * m4/nanosleep.m4 (gl_FUNC_NANOSLEEP): No longer require
+ LIB_CLOCK_GETTIME.
+ * modules/nanosleep (Depends-on): Add intprops and verify. Drop
+ clock-time, gettime.
+ * doc/posix-functions/nanosleep.texi (nanosleep): Document the
+ bug.
+ * modules/nanosleep-tests: New test.
+ * tests/test-nanosleep.c: New file.
+
sleep: work around cygwin bug
* lib/sleep.c (rpl_sleep): Work around the bug.
* m4/sleep.m4 (gl_FUNC_SLEEP): Detect the bug.
diff --git a/doc/posix-functions/nanosleep.texi
b/doc/posix-functions/nanosleep.texi
index a44ffa7..f4f0b56 100644
--- a/doc/posix-functions/nanosleep.texi
+++ b/doc/posix-functions/nanosleep.texi
@@ -19,6 +19,9 @@ nanosleep
This function mishandles large arguments when interrupted by a signal on some
platforms:
Linux 64-bit, Solaris 64-bit.
address@hidden
+This function cannot sleep longer than 49.7 days on some platforms:
+Cygwin 1.5.x.
@end itemize
Portability problems not fixed by Gnulib:
diff --git a/lib/nanosleep.c b/lib/nanosleep.c
index 7a7cc02..a9311f8 100644
--- a/lib/nanosleep.c
+++ b/lib/nanosleep.c
@@ -1,7 +1,7 @@
/* Provide a replacement for the POSIX nanosleep function.
- Copyright (C) 1999, 2000, 2002, 2004, 2005, 2006, 2007, 2008 Free
- Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2002, 2004, 2005, 2006, 2007, 2008, 2009
+ Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -22,8 +22,9 @@
#include <time.h>
+#include "intprops.h"
#include "sig-handler.h"
-#include "timespec.h"
+#include "verify.h"
#include <stdbool.h>
#include <stdio.h>
@@ -42,56 +43,45 @@ enum { BILLION = 1000 * 1000 * 1000 };
#if HAVE_BUG_BIG_NANOSLEEP
-static void
-getnow (struct timespec *t)
-{
-# if defined CLOCK_MONOTONIC && HAVE_CLOCK_GETTIME
- if (clock_gettime (CLOCK_MONOTONIC, t) == 0)
- return;
-# endif
- gettime (t);
-}
-
int
rpl_nanosleep (const struct timespec *requested_delay,
struct timespec *remaining_delay)
{
/* nanosleep mishandles large sleeps due to internal overflow
- problems, so check that the proper amount of time has actually
- elapsed. */
-
- struct timespec delay = *requested_delay;
- struct timespec t0;
- getnow (&t0);
-
- for (;;)
+ problems. The worst known case of this is cygwin 1.5.x, which
+ can't sleep more than 49.7 days (2**32 milliseconds). Solve this
+ by breaking the sleep up into smaller chunks. Verify that time_t
+ is large enough. */
+ verify (TYPE_MAXIMUM (time_t) / 49 / 24 / 60 / 60);
+ const time_t limit = 49 * 24 * 60 * 60;
+ time_t seconds = requested_delay->tv_sec;
+ struct timespec intermediate;
+ intermediate.tv_nsec = 0;
+
+ while (limit < seconds)
{
- int r = nanosleep (&delay, remaining_delay);
- if (r == 0)
- {
- time_t secs_sofar;
- struct timespec now;
- getnow (&now);
-
- secs_sofar = now.tv_sec - t0.tv_sec;
- if (requested_delay->tv_sec < secs_sofar)
- return 0;
- delay.tv_sec = requested_delay->tv_sec - secs_sofar;
- delay.tv_nsec = requested_delay->tv_nsec - (now.tv_nsec - t0.tv_nsec);
- if (delay.tv_nsec < 0)
- {
- if (delay.tv_sec == 0)
- return 0;
- delay.tv_nsec += BILLION;
- delay.tv_sec--;
- }
- else if (BILLION <= delay.tv_nsec)
- {
- delay.tv_nsec -= BILLION;
- delay.tv_sec++;
- }
- }
+ int result;
+ intermediate.tv_sec = limit;
+ result = nanosleep (&intermediate, remaining_delay);
+ seconds -= limit;
+ if (result)
+ {
+ if (remaining_delay)
+ {
+ remaining_delay->tv_sec += seconds;
+ remaining_delay->tv_nsec += requested_delay->tv_nsec;
+ if (BILLION <= requested_delay->tv_nsec)
+ {
+ remaining_delay->tv_sec++;
+ remaining_delay->tv_nsec -= BILLION;
+ }
+ }
+ return result;
+ }
}
+ intermediate.tv_sec = seconds;
+ intermediate.tv_nsec = requested_delay->tv_nsec;
+ return nanosleep (&intermediate, remaining_delay);
}
#else
diff --git a/m4/nanosleep.m4 b/m4/nanosleep.m4
index d991b61..211b367 100644
--- a/m4/nanosleep.m4
+++ b/m4/nanosleep.m4
@@ -1,4 +1,4 @@
-# serial 28
+# serial 29
dnl From Jim Meyering.
dnl Check for the nanosleep function.
@@ -17,7 +17,6 @@ AC_DEFUN([gl_FUNC_NANOSLEEP],
AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
AC_REQUIRE([gl_HEADER_TIME_H_DEFAULTS])
- AC_REQUIRE([gl_CLOCK_TIME])
AC_CHECK_HEADERS_ONCE([sys/time.h])
nanosleep_save_libs=$LIBS
@@ -103,12 +102,6 @@ AC_DEFUN([gl_FUNC_NANOSLEEP],
if test "$gl_cv_func_nanosleep" = 'no (mishandles large arguments)'; then
AC_DEFINE([HAVE_BUG_BIG_NANOSLEEP], [1],
[Define to 1 if nanosleep mishandles large arguments.])
- for ac_lib in $LIB_CLOCK_GETTIME; do
- case " $LIB_NANOSLEEP " in
- *" $ac_lib "*) ;;
- *) LIB_NANOSLEEP="$LIB_NANOSLEEP $ac_lib";;
- esac
- done
fi
AC_LIBOBJ([nanosleep])
gl_PREREQ_NANOSLEEP
diff --git a/modules/nanosleep b/modules/nanosleep
index a652e53..d457b6f 100644
--- a/modules/nanosleep
+++ b/modules/nanosleep
@@ -6,9 +6,8 @@ lib/nanosleep.c
m4/nanosleep.m4
Depends-on:
-clock-time
extensions
-gettime
+intprops
multiarch
select
sigaction
@@ -16,6 +15,7 @@ stdbool
sys_select
sys_time
time
+verify
configure.ac:
gl_FUNC_NANOSLEEP
diff --git a/modules/nanosleep-tests b/modules/nanosleep-tests
new file mode 100644
index 0000000..67e6d4e
--- /dev/null
+++ b/modules/nanosleep-tests
@@ -0,0 +1,12 @@
+Files:
+tests/test-nanosleep.c
+
+Depends-on:
+
+configure.ac:
+AC_CHECK_DECLS_ONCE([alarm])
+
+Makefile.am:
+TESTS += test-nanosleep
+check_PROGRAMS += test-nanosleep
+test_nanosleep_LDADD = $(LDADD) $(LIB_NANOSLEEP)
diff --git a/tests/test-nanosleep.c b/tests/test-nanosleep.c
new file mode 100644
index 0000000..eb4bef6
--- /dev/null
+++ b/tests/test-nanosleep.c
@@ -0,0 +1,94 @@
+/* Test of nanosleep() function.
+ Copyright (C) 2009 Free Software Foundation, Inc.
+
+ This program 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.
+
+ This program 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, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Eric Blake <address@hidden>, 2009. */
+
+#include <config.h>
+
+#include <time.h>
+
+#include <errno.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "intprops.h"
+
+#define ASSERT(expr) \
+ do \
+ { \
+ if (!(expr)) \
+ { \
+ fprintf (stderr, "%s:%d: assertion failed\n", __FILE__, __LINE__); \
+ fflush (stderr); \
+ abort (); \
+ } \
+ } \
+ while (0)
+
+#if HAVE_DECL_ALARM
+static void
+handle_alarm (int sig)
+{
+ if (sig != SIGALRM)
+ _exit (1);
+}
+#endif
+
+int
+main()
+{
+ struct timespec ts;
+
+ ts.tv_sec = 1000;
+ ts.tv_nsec = -1;
+ errno = 0;
+ ASSERT (nanosleep (&ts, NULL) == -1);
+ ASSERT (errno == EINVAL);
+ ts.tv_nsec = 1000000000;
+ errno = 0;
+ ASSERT (nanosleep (&ts, NULL) == -1);
+ ASSERT (errno == EINVAL);
+
+ ts.tv_sec = 0;
+ ts.tv_nsec = 1;
+ ASSERT (nanosleep (&ts, &ts) == 0);
+ /* Remaining time is only defined on EINTR failure; but on success,
+ it is typically either 0 or unchanged from input. At any rate,
+ it shouldn't be randomly changed to unrelated values. */
+ ASSERT (ts.tv_sec == 0);
+ ASSERT (ts.tv_nsec == 0 || ts.tv_nsec == 1);
+ ts.tv_nsec = 0;
+ ASSERT (nanosleep (&ts, NULL) == 0);
+
+#if HAVE_DECL_ALARM
+ {
+ const time_t pentecost = 50 * 24 * 60 * 60; /* 50 days. */
+ signal (SIGALRM, handle_alarm);
+ alarm (1);
+ ts.tv_sec = pentecost;
+ ts.tv_nsec = 999999999;
+ errno = 0;
+ ASSERT (nanosleep (&ts, &ts) == -1);
+ ASSERT (errno == EINTR);
+ ASSERT (pentecost - 10 < ts.tv_sec && ts.tv_sec <= pentecost);
+ ASSERT (0 <= ts.tv_nsec && ts.tv_nsec <= 999999999);
+ }
+#endif
+
+ return 0;
+}
--
1.6.5.rc1
From 65b314a386dedd0ff089ad69ed0e213a9249eb09 Mon Sep 17 00:00:00 2001
From: Eric Blake <address@hidden>
Date: Wed, 18 Nov 2009 21:46:35 -0700
Subject: [PATCH 3/4] build: avoid compiler warnings
Silence some warnings found on mingw.
* lib/select.c (rpl_select): Delete unused variable.
* lib/setsockopt.c (rpl_setsockopt): Avoid incompatible pointer.
Signed-off-by: Eric Blake <address@hidden>
---
ChangeLog | 6 ++++++
lib/select.c | 2 --
lib/setsockopt.c | 3 ++-
3 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 5bd4205..832d773 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2009-11-19 Eric Blake <address@hidden>
+
+ build: avoid compiler warnings
+ * lib/select.c (rpl_select): Delete unused variable.
+ * lib/setsockopt.c (rpl_setsockopt): Avoid incompatible pointer.
+
2009-11-18 Eric Blake <address@hidden>
nanosleep: work around cygwin bug
diff --git a/lib/select.c b/lib/select.c
index 12d3e51..e82bf88 100644
--- a/lib/select.c
+++ b/lib/select.c
@@ -322,8 +322,6 @@ rpl_select (int nfds, fd_set *rfds, fd_set *wfds, fd_set
*xfds,
/* Classify handles. Create fd sets for sockets, poll the others. */
for (i = 0; i < nfds; i++)
{
- WSANETWORKEVENTS ev;
-
if ((anyfds_in[i / CHAR_BIT] & (1 << (i & (CHAR_BIT - 1)))) == 0)
continue;
diff --git a/lib/setsockopt.c b/lib/setsockopt.c
index 96a00cc..daff382 100644
--- a/lib/setsockopt.c
+++ b/lib/setsockopt.c
@@ -41,7 +41,8 @@ rpl_setsockopt (int fd, int level, int optname, const void
*optval, socklen_t op
{
const struct timeval *tv = optval;
int milliseconds = tv->tv_sec * 1000 + tv->tv_usec / 1000;
- r = setsockopt (sock, level, optname, &milliseconds, sizeof (int));
+ optval = &milliseconds;
+ r = setsockopt (sock, level, optname, optval, sizeof (int));
}
else
{
--
1.6.5.rc1
From cf75ab9ee53a8942201f31bfee63f72f7f46f7bc Mon Sep 17 00:00:00 2001
From: Eric Blake <address@hidden>
Date: Wed, 18 Nov 2009 22:14:39 -0700
Subject: [PATCH 4/4] WIP: build nanosleep on mingw
---
m4/nanosleep.m4 | 8 ++++++++
m4/select.m4 | 1 +
2 files changed, 9 insertions(+), 0 deletions(-)
diff --git a/m4/nanosleep.m4 b/m4/nanosleep.m4
index 211b367..3524ac0 100644
--- a/m4/nanosleep.m4
+++ b/m4/nanosleep.m4
@@ -18,6 +18,7 @@ AC_DEFUN([gl_FUNC_NANOSLEEP],
AC_REQUIRE([gl_HEADER_TIME_H_DEFAULTS])
AC_CHECK_HEADERS_ONCE([sys/time.h])
+ AC_REQUIRE([gl_FUNC_SELECT])
nanosleep_save_libs=$LIBS
@@ -102,6 +103,13 @@ AC_DEFUN([gl_FUNC_NANOSLEEP],
if test "$gl_cv_func_nanosleep" = 'no (mishandles large arguments)'; then
AC_DEFINE([HAVE_BUG_BIG_NANOSLEEP], [1],
[Define to 1 if nanosleep mishandles large arguments.])
+ else
+ for ac_lib in $LIBSOCKET; do
+ case " $LIB_NANOSLEEP " in
+ *" $ac_lib "*) ;;
+ *) LIB_NANOSLEEP="$LIB_NANOSLEEP $ac_lib";;
+ esac
+ done
fi
AC_LIBOBJ([nanosleep])
gl_PREREQ_NANOSLEEP
diff --git a/m4/select.m4 b/m4/select.m4
index 53cc059..984ca3c 100644
--- a/m4/select.m4
+++ b/m4/select.m4
@@ -8,6 +8,7 @@ AC_DEFUN([gl_FUNC_SELECT],
[
AC_REQUIRE([gl_HEADER_SYS_SELECT])
AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
+ AC_REQUIRE([gl_SOCKETS])
if test "$ac_cv_header_winsock2_h" = yes; then
AC_LIBOBJ([select])
else
--
1.6.5.rc1
- Re: pending patches?, Eric Blake, 2009/11/13
- Re: pending patches?, Eric Blake, 2009/11/13
- Re: pending patches?, Pádraig Brady, 2009/11/13
- Re: pending patches?, Jim Meyering, 2009/11/14
- Re: pending patches?, Eric Blake, 2009/11/14
- usleep (was: pending patches?), Eric Blake, 2009/11/18
- Re: usleep (was: pending patches?), Eric Blake, 2009/11/18
- Re: usleep, Ludovic Courtès, 2009/11/18
- Re: usleep, Eric Blake, 2009/11/18
- Re: usleep,
Eric Blake <=
- Re: usleep, Eric Blake, 2009/11/20
- Re: pending patches?, Eric Blake, 2009/11/14
- OpenBSD chown (was: pending patches?), Eric Blake, 2009/11/17
- Re: OpenBSD chown, Eric Blake, 2009/11/18