summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog8
-rw-r--r--sysdeps/unix/sysv/linux/adjtime.c24
-rw-r--r--sysdeps/unix/sysv/linux/kernel-features.h5
-rw-r--r--sysdeps/unix/sysv/linux/sys/timex.h3
4 files changed, 36 insertions, 4 deletions
diff --git a/ChangeLog b/ChangeLog
index 560a6e6cc1..c94d0e4cfd 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2007-12-10 Ulrich Drepper <drepper@redhat.com>
+
+ * sysdeps/unix/sysv/linux/adjtime.c: Use ADJ_OFFSET_SS_READ if
+ possible.
+ * sysdeps/unix/sysv/linux/kernel-features.h
+ (__ASSUME_ADJ_OFFSET_SS_READ): Define for 2.6.24.
+ * sysdeps/unix/sysv/linux/sys/timex.h (ADJ_OFFSET_SS_READ): Define.
+
2007-12-08 Ulrich Drepper <drepper@redhat.com>
[BZ #5424]
diff --git a/sysdeps/unix/sysv/linux/adjtime.c b/sysdeps/unix/sysv/linux/adjtime.c
index 38ef805cd5..202bb14485 100644
--- a/sysdeps/unix/sysv/linux/adjtime.c
+++ b/sysdeps/unix/sysv/linux/adjtime.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1995, 1996, 1997, 1998, 2002, 2004
+/* Copyright (C) 1995, 1996, 1997, 1998, 2002, 2004, 2007
Free Software Foundation, Inc.
This file is part of the GNU C Library.
@@ -22,6 +22,8 @@
#include <sys/time.h>
#include <sys/timex.h>
+#include <kernel-features.h>
+
#define MAX_SEC (INT_MAX / 1000000L - 2)
#define MIN_SEC (INT_MIN / 1000000L + 2)
@@ -69,13 +71,29 @@ ADJTIME (const struct TIMEVAL *itv, struct TIMEVAL *otv)
return -1;
}
tntx.offset = tmp.tv_usec + tmp.tv_sec * 1000000L;
+#ifdef ADJ_OFFSET_SS_READ
+ tntx.modes = ADJ_OFFSET_SS_READ;
+#else
tntx.modes = ADJ_OFFSET_SINGLESHOT;
+#endif
}
else
tntx.modes = 0;
- if (ADJTIMEX (&tntx) < 0)
- return -1;
+#if defined ADJ_OFFSET_SS_READ && !defined __ASSUME_ADJ_OFFSET_SS_READ
+ again:
+#endif
+ if (__builtin_expect (ADJTIMEX (&tntx) < 0, 0))
+ {
+#if defined ADJ_OFFSET_SS_READ && !defined __ASSUME_ADJ_OFFSET_SS_READ
+ if (itv && errno == EINVAL && tntx.modes == ADJ_OFFSET_SS_READ)
+ {
+ tntx.modes = ADJ_OFFSET_SINGLESHOT;
+ goto again;
+ }
+#endif
+ return -1;
+ }
if (otv)
{
diff --git a/sysdeps/unix/sysv/linux/kernel-features.h b/sysdeps/unix/sysv/linux/kernel-features.h
index aab3df348e..01baab0903 100644
--- a/sysdeps/unix/sysv/linux/kernel-features.h
+++ b/sysdeps/unix/sysv/linux/kernel-features.h
@@ -487,3 +487,8 @@
|| (__LINUX_KERNEL_VERSION >= 0x020618 && defined __s390__))
# define __ASSUME_FALLOCATE 1
#endif
+
+/* Support for ADJ_OFFSET_SS_READ was added in 2.6.24. */
+#if __LINUX_KERNEL_VERSION >= 0x020618
+# define __ASSUME_ADJ_OFFSET_SS_READ 1
+#endif
diff --git a/sysdeps/unix/sysv/linux/sys/timex.h b/sysdeps/unix/sysv/linux/sys/timex.h
index 773a5ab8d0..f7bd6e7929 100644
--- a/sysdeps/unix/sysv/linux/sys/timex.h
+++ b/sysdeps/unix/sysv/linux/sys/timex.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1995, 1996, 1997, 1999 Free Software Foundation, Inc.
+/* Copyright (C) 1995, 1996, 1997, 1999, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -69,6 +69,7 @@ struct timex
#define ADJ_TIMECONST 0x0020 /* pll time constant */
#define ADJ_TICK 0x4000 /* tick value */
#define ADJ_OFFSET_SINGLESHOT 0x8001 /* old-fashioned adjtime */
+#define ADJ_OFFSET_SS_READ 0xa001 /* read-only adjtime */
/* xntp 3.4 compatibility names */
#define MOD_OFFSET ADJ_OFFSET