bug-coreutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: xnanosleep range with 32 bit time_t


From: Paul Eggert
Subject: Re: xnanosleep range with 32 bit time_t
Date: Thu, 31 Aug 2006 00:33:41 -0700
User-agent: Gnus/5.1008 (Gnus v5.10.8) Emacs/21.4 (gnu/linux)

In looking into this problem I discovered a separate bug with
nanosleep that occurs on 32-bit platforms: Linux mishandles nanosleep
arguments longer than (2**31 / 100) == 21,474,836 seconds, or about
249 days.  You might want to add this to your list of Linux kernel
bugs to fix, if you haven't fixed it already.  The coreutils patch
should work around this other bug as well, but it should get fixed in
the kernel too, while you're at it.

This reminds me of a similar bug that was fixed in SunOS about a
decade ago.  It was the same period: about 249 days.  It's Sun bug
1248960 "system goes nuts when lbolt wraps after running for a long
time".  You might want to sweep the Linux kernel for other overflow
bugs in the area, since it seems to be a popular bug to have.

My favorite thing about that Sun bug report was the workaround:

  "Reboot the system regularly.  However the customer cannot do this
   because it increases the chances of losing a satellite
   significantly."

No kidding.

The bug is also present in Linux 2.6.8 (x86, Debian stable).

Here's a program that illustrates the bug.  It works fine on 32-bit
SunOS 5.10, but exits with status 119 on 32-bit GNU/Linux 2.6.8.
(It contains extra tests for 64-bit hosts and fails on 64-bit
SunOS as well as 64-bit Linux, but that's not relevant here.)

Can you please report this bug to whoever's responsible for getting
nanosleep to work in the Linux kernel, if the bug isn't already
fixed in more bleeding-edge versions?

Thanks.


#include <time.h>
#include <errno.h>
#include <limits.h>
#include <signal.h>
#include <unistd.h>
#define TYPE_SIGNED(t) (! ((t) 0 < (t) -1))
#define TYPE_MAXIMUM(t) ((t) (! TYPE_SIGNED (t) ? (t) -1 : ~ (~ (t) 0 << 
(sizeof (t) * CHAR_BIT - 1))))

static void
check_for_SIGALRM (int sig)
{
  if (sig != SIGALRM)
    _exit (1);
}

int
main ()
{
  static struct timespec ts_sleep;
  static struct timespec ts_remaining;
  static struct sigaction act;
  act.sa_handler = check_for_SIGALRM;
  sigemptyset (&act.sa_mask);
  sigaction (SIGALRM, &act, NULL);
  ts_sleep.tv_sec = TYPE_MAXIMUM (time_t);
  ts_sleep.tv_nsec = 999999999;
  alarm (1);
  if (nanosleep (&ts_sleep, &ts_remaining) == -1 && errno == EINTR)
    {
      if (TYPE_MAXIMUM (time_t) - 10 < ts_remaining.tv_sec)
        return 0;
      return 119;
    }
  return 1;
}




reply via email to

[Prev in Thread] Current Thread [Next in Thread]