Index: /trunk/libc/include/klibc/backend.h
===================================================================
--- /trunk/libc/include/klibc/backend.h	(revision 2909)
+++ /trunk/libc/include/klibc/backend.h	(revision 2910)
@@ -1136,4 +1136,26 @@
 
 /**
+ * Set and/or get the time adjustment delta.
+ *
+ * @returns 0 on success.
+ * @returns Negated errno on failure.
+ *
+ * @param   pi64Delta       The new delta. (optional)
+ * @param   pi64OldDelta    The old delta. (optional)
+ *
+ * @remark  On some hosts this is implemented by using __libc_Back_timeSet().
+ */
+int __libc_Back_timeAdjust(int64_t const *pi64Delta, int64_t *pi64OldDelta);
+
+/**
+ * Gets the system time.
+ *
+ * @returns 0 on success.
+ * @returns Negative error code (errno.h) on failure.
+ * @param   pTime       Where to store the current system time (UCT).
+ */
+int __libc_Back_timeGet(struct timespec *pTime);
+
+/**
  * Gets the current high-resolution timestamp as nanoseconds.
  *
@@ -1141,4 +1163,13 @@
  */
 hrtime_t __libc_Back_timeHighResNano(void);
+
+/**
+ * Sets the system time.
+ *
+ * @returns 0 on success.
+ * @returns Negative error code (errno.h) on failure.
+ * @param   pNewTime    The new time given as UCT.
+ */
+int __libc_Back_timeSet(const struct timespec *pNewTime);
 
 /** @} */
Index: /trunk/libc/include/klibc/time.h
===================================================================
--- /trunk/libc/include/klibc/time.h	(revision 2909)
+++ /trunk/libc/include/klibc/time.h	(revision 2910)
@@ -60,6 +60,6 @@
 extern struct _tzinfo   __libc_gTZInfo;
 extern int16_t const    __libc_gaiYearDay[_YEARS+1];
-extern uint16_t const   __libc_gauMonthDayLeap[];
-extern uint16_t const   __libc_gauMonthDayNonLeap[];
+extern uint16_t const   __libc_gauMonthDayLeap[12+1];
+extern uint16_t const   __libc_gauMonthDayNonLeap[12+1];
 
 
@@ -72,4 +72,5 @@
 time64_t __mktime64(struct tm *);
 void _compute_dst_table(void);
+extern int __libc_days2year_slow(time_t *pcDays);
 
 
@@ -79,4 +80,5 @@
  * @returns 1 if it's a leap year, 0 if it's a normal year.
  * @param   y   The year.
+ * @internal
  */
 static __inline__ int _leap_year(unsigned y)
@@ -87,4 +89,58 @@
 }
 
+/**
+ * Converts from days into the year to month.
+ *
+ * @returns The month of the year. (1 = January)
+ * @param   pcDays  IN: The number of days into the year. (0-based)
+ *                  OUT: The number of days into the month. (0-based)
+ * @param   iYear   The year.
+ * @internal
+ */
+static unsigned __inline__ __libc_dayofyear2month(time_t *pcDays, int iYear)
+{
+    uint16_t const *pauMonthDay = _leap_year(iYear) ? __libc_gauMonthDayLeap : __libc_gauMonthDayNonLeap;
+    const time_t cDays = *pcDays;
+    unsigned iMonth;
+    for (iMonth = cDays <= pauMonthDay[6] ? 0 : 6;
+         cDays >= pauMonthDay[iMonth + 1];
+         iMonth++)
+        /* nothing */;
+    *pcDays = cDays - pauMonthDay[iMonth];
+    return iMonth;
+}
+
+/**
+ * Converts from days from epoch to years.
+ *
+ * @returns Year number.
+ * @param   pcDays  IN: the day count relative to epoch.
+ *                  OUT: the day count relative to the start of the year.
+ * @internal
+ */
+static int __inline__ __libc_days2year(time_t *pcDays)
+{
+    /* Perform a binary search to locate the year (i) which *pSeconds falls in. */
+    const time_t cDays = *pcDays;
+    int iFirst = 0;
+    int iLast = _YEARS;
+    int i;
+    for (;;)
+    {
+        i = (iFirst + iLast) / 2;
+        if (i < 0 || i >= _YEARS)
+            return __libc_days2year_slow(pcDays);
+        if (__libc_gaiYearDay[i] > cDays)
+            iLast = i - 1;
+        else if (__libc_gaiYearDay[i + 1] <= cDays)
+            iFirst = i + 1;
+        else
+        {
+            *pcDays = cDays - __libc_gaiYearDay[i];
+            return i + 1900;
+        }
+    }
+}
+
 __END_DECLS
 
Index: /trunk/libc/include/sys/time.h
===================================================================
--- /trunk/libc/include/sys/time.h	(revision 2909)
+++ /trunk/libc/include/sys/time.h	(revision 2910)
@@ -324,5 +324,5 @@
 
 __BEGIN_DECLS
-/** @todo int	adjtime(const struct timeval *, struct timeval *); */
+int	adjtime(const struct timeval *, struct timeval *);
 int	futimes(int, const struct timeval *);
 int	getitimer(int, struct itimerval *);
Index: /trunk/libc/src/kNIX/Makefile.kmk
===================================================================
--- /trunk/libc/src/kNIX/Makefile.kmk	(revision 2909)
+++ /trunk/libc/src/kNIX/Makefile.kmk	(revision 2910)
@@ -114,5 +114,8 @@
     $(PATH_LIBC_SRC)/kNIX/os2/b_threadStartup.c \
     $(PATH_LIBC_SRC)/kNIX/os2/b_time.c \
+    $(PATH_LIBC_SRC)/kNIX/os2/b_timeAdjust.c \
+    $(PATH_LIBC_SRC)/kNIX/os2/b_timeGet.c \
     $(PATH_LIBC_SRC)/kNIX/os2/b_timeHighResNano.c \
+    $(PATH_LIBC_SRC)/kNIX/os2/b_timeSet.c \
     $(PATH_LIBC_SRC)/kNIX/os2/clock.c \
     $(PATH_LIBC_SRC)/kNIX/os2/core.c \
@@ -164,9 +167,6 @@
     $(PATH_LIBC_SRC)/kNIX/os2/umask.c \
     $(PATH_LIBC_SRC)/kNIX/os2/__chmod.c \
-    $(PATH_LIBC_SRC)/kNIX/os2/__close.c \
     $(PATH_LIBC_SRC)/kNIX/os2/__dup.c \
     $(PATH_LIBC_SRC)/kNIX/os2/__dup2.c \
-    $(PATH_LIBC_SRC)/kNIX/os2/__fcntl.c \
-    $(PATH_LIBC_SRC)/kNIX/os2/__ftime.c \
     $(PATH_LIBC_SRC)/kNIX/os2/__imphandle.c \
     $(PATH_LIBC_SRC)/kNIX/os2/__init.c \
@@ -178,5 +178,4 @@
     $(PATH_LIBC_SRC)/kNIX/os2/__read_kbd.c \
     $(PATH_LIBC_SRC)/kNIX/os2/__select.c \
-    $(PATH_LIBC_SRC)/kNIX/os2/__settime.c \
     $(PATH_LIBC_SRC)/kNIX/os2/__spawnve.c \
     $(PATH_LIBC_SRC)/kNIX/os2/386/appinit.s \
Index: /trunk/libc/src/kNIX/kNIX.h
===================================================================
--- /trunk/libc/src/kNIX/kNIX.h	(revision 2909)
+++ /trunk/libc/src/kNIX/kNIX.h	(revision 2910)
@@ -56,4 +56,5 @@
 #include <klibc/umalloc.h>
 #include <klibc/thread.h>
+#include <klibc/time.h>
 #include <klibc/backend.h>
 
Index: unk/libc/src/kNIX/os2/__ftime.c
===================================================================
--- /trunk/libc/src/kNIX/os2/__ftime.c	(revision 2909)
+++ 	(revision )
@@ -1,195 +1,0 @@
-/* $Id: $ */
-/** @file
- *
- * LIBC SYS Backend - ftime.
- *
- * InnoTek Systemberatung GmbH confidential
- *
- * Copyright (c) 2004 InnoTek Systemberatung GmbH
- * Author: knut st. osmundsen <bird-srcspam@anduin.net>
- *
- * All Rights Reserved
- *
- */
-
-#define CALCDIFF
-
-
-/*******************************************************************************
-*   Header Files                                                               *
-*******************************************************************************/
-#include "libc-alias.h"
-#define INCL_BASE
-#define INCL_DOSINFOSEG
-#define INCL_FSMACROS
-#include <os2emx.h>
-#include <sys/timeb.h>
-#include <time.h>
-#include <emx/time.h>
-#include <emx/syscalls.h>
-#include <386/builtin.h>
-#include "syscalls.h"
-
-#ifdef CALCDIFF
-/**
- * Calcs the uDiff in formula timeb.millitm = (msecs + uDiff) % 1000.
- */
-static unsigned calcdiff(void)
-{
-    /*
-     * We make a little effort to lower the chances of preempting
-     * while reading the msecs and hundredths members of GIS.
-     */
-    #pragma pack(1)
-    union combined2
-    {
-        volatile unsigned long long ull;
-        struct s
-        {
-            ULONG   msecs;
-            UCHAR   hour;
-            UCHAR   minutes;
-            UCHAR   seconds;
-            UCHAR   hundredths;
-        } s;
-    };
-    #pragma pack()
-    unsigned            uDiff;
-    PGINFOSEG           pGIS = GETGINFOSEG();
-    union combined2    *pCombined = (union combined2 *)&pGIS->msecs;
-    union combined2     Combined;
-
-    /*
-     * Get a usable data set.
-     *
-     * We try to skip any msecs which end with 0. The two PCs I've got
-     * here indicates that this is a good idea for consistency in the result.
-     */
-    Combined.ull = pCombined->ull;
-    if (!(Combined.s.msecs % 10))
-    {
-        int i = 0;
-        FS_VAR();
-        FS_SAVE_LOAD();
-        do
-        {
-            DosSleep(1);
-            Combined.ull = pCombined->ull;
-        } while (!(Combined.s.msecs % 10) && ++i < 2);
-        FS_RESTORE();
-    }
-
-    /*
-     * Calc the diff value.
-     */
-    uDiff = Combined.s.hundredths * 10 - (Combined.s.msecs % 1000);
-    if ((int)uDiff < 0)
-        uDiff += 1000;                  /* must be positive for the rounding. */
-    /* round up to closes 10. */
-    uDiff += 9;
-    uDiff /= 10;
-    uDiff *= 10;
-    return uDiff;
-}
-#endif /* CALCDIFF */
-
-
-/**
- * Get the current local time.
- * @param   ptr     Where to store the result.
- *                  Note that only the members time and millitm are filled in,
- *                  the caller is expected to fill the remaining fields.
- */
-void __ftime(struct timeb *ptr)
-{
-#pragma pack(1)
-    union last
-    {
-        unsigned long long ull;
-        struct
-        {
-            unsigned secs;
-            unsigned msecs;
-            short    milli;
-        } s;
-    };
-    union combined
-    {
-        struct
-        {
-            ULONG       time;
-            ULONG       msecs;
-            UCHAR       _not_used__hour;
-            UCHAR       _not_used__minutes;
-            UCHAR       _not_used__seconds;
-            UCHAR       hundredths;
-        } s;
-    };
-    static union
-    {
-        PGINFOSEG       pGIS;
-        volatile union combined *pCombined;
-    } uGIS;
-#pragma pack()
-    static volatile union last LastStatic;
-    static volatile unsigned uDiff;
-
-    /*
-     * Init.
-     */
-    if (!uGIS.pGIS)
-    {
-#ifdef CALCDIFF
-        uDiff = calcdiff();
-#endif
-        uGIS.pGIS = GETGINFOSEG();
-    }
-
-    /*
-     * Get the value and convert it to the return format.
-     */
-    /* read times */
-    union combined  Combined = *uGIS.pCombined;
-    union last      LastCopy = LastStatic;
-
-    /* calc now */
-    union last Now;
-    Now.s.secs = Combined.s.time;
-#ifdef CALCDIFF
-    Now.s.milli = (Combined.s.msecs + uDiff) % 1000;
-#else
-    Now.s.milli = (Combined.s.hundredths * 10) | ((Combined.s.msecs + uDiff) % 10);
-#endif
-    Now.s.msecs = Combined.s.msecs;
-
-    /* validate now */
-    unsigned uDiffSecs = Now.s.secs - LastCopy.s.secs;
-    if (!uDiffSecs)
-    {
-        int iDiffMilli = Now.s.milli - LastCopy.s.milli;
-        if (iDiffMilli < 0)
-        {
-            uDiff -= -iDiffMilli + 1;
-            Now = LastCopy;
-        }
-    }
-    else if (uDiffSecs == 1)
-    {
-        unsigned    uDiffMsecs = Now.s.msecs - LastCopy.s.msecs;
-        unsigned    uDiffMilli = Now.s.milli + 1000 - LastCopy.s.milli;
-        if (uDiffMilli > uDiffMsecs + 500)
-        {
-            uDiff += 1000 - Now.s.milli;
-            Now.s.milli = 0;
-        }
-    }
-
-    /* update the last know ok value */
-    LastStatic = Now; /** @todo 8byte + 4 byte exchange! */
-
-    /* store the result in the user buffer */
-    ptr->time       = Now.s.secs;
-    ptr->millitm    = Now.s.milli;
-    ptr->timezone   = 0;
-    ptr->dstflag    = 0;
-}
Index: /trunk/libc/src/kNIX/os2/b_time.c
===================================================================
--- /trunk/libc/src/kNIX/os2/b_time.c	(revision 2909)
+++ /trunk/libc/src/kNIX/os2/b_time.c	(revision 2910)
@@ -2,37 +2,31 @@
 /** @file
  *
- * LIBC SYS Backend - times helpers.
+ * kNIX - Time helpers, OS/2.
  *
- * Copyright (c) 2005 knut st. osmundsen <bird@anduin.net>
+ * Copyright (c) 2005-2006 knut st. osmundsen <bird-srcspam@anduin.net>
  *
  *
- * This file is part of kBuild.
+ * This file is part of kLIBC.
  *
- * kBuild 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 2 of the License, or
+ * kLIBC 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 of the License, or
  * (at your option) any later version.
  *
- * kBuild is distributed in the hope that it will be useful,
+ * kLIBC 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.
+ * GNU Lesser General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with kBuild; if not, write to the Free Software
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with kLIBC; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  */
 
-
 /*******************************************************************************
 *   Header Files                                                               *
 *******************************************************************************/
-#include "libc-alias.h"
-#define INCL_FSMACROS
-#include <os2emx.h>
-#include "b_time.h"
-#include <time.h>
-
+#include "kNIX.h"
 
 /**
Index: /trunk/libc/src/kNIX/os2/b_time.h
===================================================================
--- /trunk/libc/src/kNIX/os2/b_time.h	(revision 2909)
+++ /trunk/libc/src/kNIX/os2/b_time.h	(revision 2910)
@@ -1,41 +1,1 @@
-/* $Id$ */
-/** @file
- *
- * LIBC SYS Backend - time helpers.
- *
- * Copyright (c) 2005 knut st. osmundsen <bird@anduin.net>
- *
- *
- * This file is part of kBuild.
- *
- * kBuild 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 2 of the License, or
- * (at your option) any later version.
- *
- * kBuild 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 kBuild; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- */
-
-#ifndef __b_time_h__
-#define __b_time_h__
-
-#include <time.h>
-
-/**
- * Converts local unix time to file time.
- *
- * @param   Time    Local unix time (secs).
- * @param   pTime   Where to store the time.
- * @param   pDate   Where to store the date.
- */
-void __libc_back_timeUnix2FileTime(time_t Time, PFTIME pTime, PFDATE pDate);
-
-#endif
+#error dead
Index: /trunk/libc/src/kNIX/os2/b_timeAdjust.c
===================================================================
--- /trunk/libc/src/kNIX/os2/b_timeAdjust.c	(revision 2910)
+++ /trunk/libc/src/kNIX/os2/b_timeAdjust.c	(revision 2910)
@@ -0,0 +1,86 @@
+/* $Id: $ */
+/** @file
+ *
+ * kNIX - adjtime().
+ *
+ * Copyright (c) 2006 knut st. osmundsen <bird-srcspam@anduin.net>
+ *
+ *
+ * This file is part of kLIBC.
+ *
+ * kLIBC 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 of the License, or
+ * (at your option) any later version.
+ *
+ * kLIBC 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 kLIBC; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#include "kNIX.h"
+#define __LIBC_LOG_GROUP __LIBC_LOG_GRP_BACK_TIME
+#include <klibc/logstrict.h>
+
+
+/**
+ * Set and/or get the time adjustment delta.
+ *
+ * @returns 0 on success.
+ * @returns Negated errno on failure.
+ *
+ * @param   pi64Delta       The new delta. (optional)
+ * @param   pi64OldDelta    The old delta. (optional)
+ *
+ * @remark  On some hosts this is implemented by using __libc_Back_timeSet().
+ */
+int __libc_Back_timeAdjust(int64_t const *pi64Delta, int64_t *pi64OldDelta)
+{
+    LIBCLOG_ENTER("pi64Delta=%p:{%lld} pi64OldDelta=%p\n", (void *)pi64Delta, pi64Delta ? (long long)*pi64Delta : 0, (void *)pi64OldDelta);
+
+    /*
+     * Do the adjustment in one shot.
+     */
+    if (pi64Delta)
+    {
+        /* get the current time. */
+        struct timespec TimeSpec;
+        int rc = __libc_Back_timeGet(&TimeSpec);
+        if (rc)
+            LIBCLOG_ERROR_RETURN_INT(rc);
+
+        /* adjust it in one go */
+        int64_t i64Delta = *pi64Delta;
+        TimeSpec.tv_sec += i64Delta / 1000000000;
+        TimeSpec.tv_nsec += i64Delta % 1000000000; /** @todo verify this with regard to negative deltas! */
+        while (TimeSpec.tv_nsec < 0)
+        {
+            TimeSpec.tv_sec--;
+            TimeSpec.tv_nsec += 1000000000;
+        }
+        while (TimeSpec.tv_nsec >= 1000000000)
+        {
+            TimeSpec.tv_sec++;
+            TimeSpec.tv_nsec -= 1000000000;
+        }
+
+        /* set the new time */
+        rc = __libc_Back_timeSet(&TimeSpec);
+        if (rc)
+            LIBCLOG_ERROR_RETURN_INT(rc);
+    }
+
+    /*
+     * The old delta is always 0.
+     */
+    if (pi64OldDelta)
+        *pi64OldDelta = 0;
+    LIBCLOG_RETURN_INT(0);
+}
+
Index: /trunk/libc/src/kNIX/os2/b_timeGet.c
===================================================================
--- /trunk/libc/src/kNIX/os2/b_timeGet.c	(revision 2910)
+++ /trunk/libc/src/kNIX/os2/b_timeGet.c	(revision 2910)
@@ -0,0 +1,191 @@
+/* $Id: $ */
+/** @file
+ *
+ * kNIX - Get The Current Time, OS/2.
+ *
+ * Copyright (c) 2006 knut st. osmundsen <bird-srcspam@anduin.net>
+ *
+ *
+ * This file is part of kLIBC.
+ *
+ * kLIBC 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 of the License, or
+ * (at your option) any later version.
+ *
+ * kLIBC 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 kLIBC; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#include "kNIX.h"
+#define __LIBC_LOG_GROUP __LIBC_LOG_GRP_BACK_TIME
+#include <klibc/logstrict.h>
+
+/**
+ * Calcs the s_uDiff in formula timeb.millitm = (msecs + s_uDiff) % 1000.
+ */
+static unsigned calcdiff(void)
+{
+    /*
+     * We make a little effort to lower the chances of preempting
+     * while reading the msecs and hundredths members of GIS.
+     */
+    #pragma pack(1)
+    union combined2
+    {
+        volatile unsigned long long ull;
+        struct s
+        {
+            ULONG   msecs;
+            UCHAR   hour;
+            UCHAR   minutes;
+            UCHAR   seconds;
+            UCHAR   hundredths;
+        } s;
+    };
+    #pragma pack()
+    unsigned            s_uDiff;
+    PGINFOSEG           pGIS = GETGINFOSEG();
+    union combined2    *pCombined = (union combined2 *)&pGIS->msecs;
+    union combined2     Combined;
+
+    /*
+     * Get a usable data set.
+     *
+     * We try to skip any msecs which end with 0. The two PCs I've got
+     * here indicates that this is a good idea for consistency in the result.
+     */
+    Combined.ull = pCombined->ull;
+    if (!(Combined.s.msecs % 10))
+    {
+        int i = 0;
+        FS_VAR();
+        FS_SAVE_LOAD();
+        do
+        {
+            DosSleep(1);
+            Combined.ull = pCombined->ull;
+        } while (!(Combined.s.msecs % 10) && ++i < 2);
+        FS_RESTORE();
+    }
+
+    /*
+     * Calc the diff value.
+     */
+    s_uDiff = Combined.s.hundredths * 10 - (Combined.s.msecs % 1000);
+    if ((int)s_uDiff < 0)
+        s_uDiff += 1000;                  /* must be positive for the rounding. */
+    /* round up to closes 10. */
+    s_uDiff += 9;
+    s_uDiff /= 10;
+    s_uDiff *= 10;
+    return s_uDiff;
+}
+
+
+/**
+ * Gets the system clock time.
+ *
+ * @returns 0 on success.
+ * @returns Negative error code (errno.h) on failure.
+ * @param   pCurTime    Where to store the current time (as UTC).
+ */
+int __libc_Back_timeGet(struct timespec *pCurTime)
+{
+    LIBCLOG_ENTER("pCurTime=%p\n", (void *)pCurTime);
+
+#pragma pack(1)
+    union last
+    {
+        unsigned long long ull;
+        struct
+        {
+            unsigned secs;
+            unsigned msecs;
+            short    milli;
+        } s;
+    };
+    union combined
+    {
+        struct
+        {
+            ULONG       time;
+            ULONG       msecs;
+            UCHAR       _not_used__hour;
+            UCHAR       _not_used__minutes;
+            UCHAR       _not_used__seconds;
+            UCHAR       hundredths;
+        } s;
+    };
+    static union
+    {
+        PGINFOSEG       pGIS;
+        volatile union combined *pCombined;
+    } s_GIS;
+#pragma pack()
+    static volatile union last s_Last;
+    static volatile unsigned s_uDiff;
+
+    /*
+     * Init.
+     */
+    if (!s_GIS.pGIS)
+    {
+        s_uDiff = calcdiff();
+        s_GIS.pGIS = GETGINFOSEG();
+    }
+    if (!__libc_gfTZInfoOk)
+        tzset();
+
+    /*
+     * Get the value and convert it to the return format.
+     */
+    /* read times */
+    union combined  Combined = *s_GIS.pCombined;
+    union last      LastCopy = s_Last;
+
+    /* calc now */
+    union last Now;
+    Now.s.secs = Combined.s.time;
+    Now.s.milli = (Combined.s.msecs + s_uDiff) % 1000;
+    Now.s.msecs = Combined.s.msecs;
+
+    /* validate now */
+    unsigned uDiffSecs = Now.s.secs - LastCopy.s.secs;
+    if (!uDiffSecs)
+    {
+        int iDiffMilli = Now.s.milli - LastCopy.s.milli;
+        if (iDiffMilli < 0)
+        {
+            s_uDiff -= -iDiffMilli + 1;
+            Now = LastCopy;
+        }
+    }
+    else if (uDiffSecs == 1)
+    {
+        unsigned    uDiffMsecs = Now.s.msecs - LastCopy.s.msecs;
+        unsigned    uDiffMilli = Now.s.milli + 1000 - LastCopy.s.milli;
+        if (uDiffMilli > uDiffMsecs + 500)
+        {
+            s_uDiff += 1000 - Now.s.milli;
+            Now.s.milli = 0;
+        }
+    }
+
+    /* update the last know ok value */
+    s_Last = Now; /** @todo 8byte + 4 byte exchange! */
+
+    /* store the result in the user buffer */
+    pCurTime->tv_nsec = Now.s.milli * 1000000;
+    pCurTime->tv_sec  = Now.s.secs;
+
+    LIBCLOG_RETURN_INT(0);
+}
+
Index: /trunk/libc/src/kNIX/os2/b_timeSet.c
===================================================================
--- /trunk/libc/src/kNIX/os2/b_timeSet.c	(revision 2910)
+++ /trunk/libc/src/kNIX/os2/b_timeSet.c	(revision 2910)
@@ -0,0 +1,87 @@
+/* $Id: $ */
+/** @file
+ *
+ * kNIX - Set Time, OS/2.
+ *
+ * Copyright (c) 2006 knut st. osmundsen <bird-srcspam@anduin.net>
+ *
+ *
+ * This file is part of kLIBC.
+ *
+ * kLIBC 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 of the License, or
+ * (at your option) any later version.
+ *
+ * kLIBC 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 kLIBC; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#include "kNIX.h"
+#define __LIBC_LOG_GROUP __LIBC_LOG_GRP_BACK_TIME
+#include <klibc/logstrict.h>
+
+/**
+ * Converts unix time spec to date time.
+ *
+ * @param   pTime   The unix time. Assumes it's normalized.
+ * @param   pdt     Where to store the OS/2 date time. The timezone field isn't touched.
+ */
+static void __libc_back_time2DateTime(const struct timespec *pTime, PDATETIME pdt)
+{
+    pdt->hundredths = (pTime->tv_nsec / 10000000) % 100;
+    time_t t = pTime->tv_sec;
+    pdt->seconds = t % 60;
+    t /= 60;
+    pdt->minutes = t % 60;
+    t /= 60;
+    pdt->hours = t % 24;
+    t /= 24;
+    pdt->year = __libc_days2year(&t);
+    pdt->month = __libc_dayofyear2month(&t, pdt->year);
+    pdt->day = t + 1;
+
+    pdt->weekday = 0;
+}
+
+
+/**
+ * Sets the system time.
+ *
+ * @returns 0 on success.
+ * @returns Negative error code (errno.h) on failure.
+ * @param   pNewTime    The new time given as UCT.
+ */
+int __libc_Back_timeSet(const struct timespec *pNewTime)
+{
+    LIBCLOG_ENTER("pNewTime=%p:{.tv_sec=%lld, .tv_nsec=%ld}\n", (void *)pNewTime, (long long)pNewTime->tv_sec, pNewTime->tv_nsec);
+
+    /* Call tzset if necessary. */
+    if (!__libc_gfTZInfoOk)
+        tzset();
+
+    /* Convert to local OS/2 time. */
+    struct timespec NewTime = *pNewTime;
+    _gmt2loc(&NewTime.tv_sec);
+
+    FS_VAR_SAVE_LOAD();
+    DATETIME dt;
+    DosGetDateTime(&dt); /* preserve the timezone member. */
+    __libc_back_time2DateTime(&NewTime, &dt);
+
+    /* Try set the time. */
+    int rc = DosSetDateTime(&dt);
+    FS_RESTORE();
+    if (!rc)
+        LIBCLOG_RETURN_INT(rc);
+    rc = -__libc_back_native2errno(rc);
+    LIBCLOG_ERROR_RETURN_INT(rc);
+}
+
Index: /trunk/libc/src/kNIX/os2/kNIX-os2.h
===================================================================
--- /trunk/libc/src/kNIX/os2/kNIX-os2.h	(revision 2909)
+++ /trunk/libc/src/kNIX/os2/kNIX-os2.h	(revision 2910)
@@ -228,4 +228,9 @@
 extern unsigned long __libc_back_ghevWait;
 
+/** @name Time Helpers
+ * @{ */
+void __libc_back_timeUnix2FileTime(time_t Time, PFTIME pTime, PFDATE pDate);
+/** @} */
+
 __END_DECLS
 
Index: /trunk/libc/src/libc/time/Makefile.kmk
===================================================================
--- /trunk/libc/src/libc/time/Makefile.kmk	(revision 2909)
+++ /trunk/libc/src/libc/time/Makefile.kmk	(revision 2910)
@@ -34,4 +34,5 @@
 libc_libc_time_TEMPLATE = libcsub
 libc_libc_time_SOURCES = \
+    $(PATH_LIBC_SRC)/libc/time/adjtime.c \
     $(PATH_LIBC_SRC)/libc/time/asctime.c \
     $(PATH_LIBC_SRC)/libc/time/ctime.c \
@@ -49,5 +50,6 @@
     $(PATH_LIBC_SRC)/libc/time/timedata.c \
     $(PATH_LIBC_SRC)/libc/time/timetabs.c \
-    $(PATH_LIBC_SRC)/libc/time/tzset.c
+    $(PATH_LIBC_SRC)/libc/time/tzset.c \
+    $(PATH_LIBC_SRC)/libc/time/__libc_days2year_slow.c
 
 # configure the variants. */
Index: /trunk/libc/src/libc/time/__libc_days2year_slow.c
===================================================================
--- /trunk/libc/src/libc/time/__libc_days2year_slow.c	(revision 2910)
+++ /trunk/libc/src/libc/time/__libc_days2year_slow.c	(revision 2910)
@@ -0,0 +1,67 @@
+/* $Id: $ */
+/** @file
+ *
+ * kLIBC - __libc_days2year_slow().
+ *
+ * Copyright (c) 2006 knut st. osmundsen <bird-srcspam@anduin.net>
+ *
+ *
+ * This file is part of kLIBC.
+ *
+ * kLIBC 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 of the License, or
+ * (at your option) any later version.
+ *
+ * kLIBC 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 kLIBC; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#include "libc-alias.h"
+#include <klibc/time.h>
+
+/**
+ * Converts from days from epoch to years.
+ * This is used when the encountering data outside the table.
+ *
+ * @returns Year number.
+ * @param   pcDays  IN: the day count relative to epoch.
+ *                  OUT: the day count relative to the start of the year. (0-based)
+ * @internal
+ */
+int __libc_days2year_slow(time_t *pcDays)
+{
+    int iYear = 1970;
+    time_t cDays = *pcDays;
+    if (cDays >= 0)
+    {
+        for (;;)
+        {
+            const int cDaysInYear = _leap_year(iYear) ? 366 : 365;
+            if (cDays < cDaysInYear)
+                break;
+            cDays -= cDaysInYear;
+            iYear++;
+        }
+    }
+    else
+    {
+        for (;;)
+        {
+            iYear--;
+            cDays += _leap_year(iYear) ? 366 : 365;
+            if (cDays >= 0)
+                break;
+        }
+    }
+    *pcDays = cDays;
+    return iYear;
+}
+
Index: /trunk/libc/src/libc/time/adjtime.c
===================================================================
--- /trunk/libc/src/libc/time/adjtime.c	(revision 2910)
+++ /trunk/libc/src/libc/time/adjtime.c	(revision 2910)
@@ -0,0 +1,73 @@
+/* $Id: $ */
+/** @file
+ *
+ * kLIBC - adjtime().
+ *
+ * Copyright (c) 2006 knut st. osmundsen <bird-srcspam@anduin.net>
+ *
+ *
+ * This file is part of kLIBC.
+ *
+ * kLIBC 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 of the License, or
+ * (at your option) any later version.
+ *
+ * kLIBC 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 kLIBC; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#include "libc-alias.h"
+#include <sys/time.h>
+#include <errno.h>
+#include <klibc/backend.h>
+#define __LIBC_LOG_GROUP __LIBC_LOG_GRP_TIME
+#include <klibc/logstrict.h>
+
+
+int _STD(adjtime)(const struct timeval *pDelta, struct timeval *pOldDelta)
+{
+    LIBCLOG_ENTER("pDelta=%p:{.tv_sec=%lld, .tv_nsec=%ld} pOldDelta=%p\n",
+                  (void *)pDelta, pDelta ? (long long)pDelta->tv_sec : -1, pDelta ? (long)pDelta->tv_usec : -1,
+                  (void *)pOldDelta);
+    int64_t i64Delta = 0;
+    int64_t i64OldDelta = 0;
+
+    /* convert input */
+    if (pDelta)
+    {
+        i64Delta = (int64_t)pDelta->tv_sec * 1000000000;
+        if (i64Delta / 1000000000 != pDelta->tv_sec) /* not perfect but good enough */
+        {
+            errno = E2BIG;
+            LIBCLOG_ERROR_RETURN_INT(-1);
+        }
+        i64Delta += pDelta->tv_usec;
+    }
+
+    /* do the call. */
+    int rc = __libc_Back_timeAdjust(pDelta ? &i64Delta : NULL, pOldDelta ? &i64OldDelta : NULL);
+    if (!rc)
+    {
+        if (!pOldDelta)
+            LIBCLOG_RETURN_INT(0);
+
+        /* convert output */
+        i64OldDelta /= 1000;
+        pOldDelta->tv_usec = i64OldDelta % 1000000;
+        i64OldDelta /= 1000000;
+        pOldDelta->tv_sec = (time_t)i64OldDelta;
+        LIBCLOG_RETURN_MSG(0, "ret 0 (0x0) - pOldDelta=%p:{.tv_sec=%lld, .tv_nsec=%ld}\n",
+                           (void *)pOldDelta, (long long)pOldDelta->tv_sec, (long)pOldDelta->tv_usec);
+    }
+    errno = -rc;
+    LIBCLOG_ERROR_RETURN_INT(-1);
+}
+
Index: /trunk/libc/src/libc/time/ftime.c
===================================================================
--- /trunk/libc/src/libc/time/ftime.c	(revision 2909)
+++ /trunk/libc/src/libc/time/ftime.c	(revision 2910)
@@ -4,5 +4,4 @@
  * kLIBC - ftime().
  *
- * Copyright (c) 1993-1996 by Eberhard Mattes
  * Copyright (c) 2006 knut st. osmundsen <bird-srcspam@anduin.net>
  *
@@ -28,25 +27,30 @@
 #include "libc-alias.h"
 #include <sys/timeb.h>
-#include <time.h>
 #include <klibc/time.h>
-#include <emx/syscalls.h> /// @todo fixme!
+#include <klibc/backend.h>
 #define __LIBC_LOG_GROUP __LIBC_LOG_GRP_TIME
 #include <klibc/logstrict.h>
 
-void _STD(ftime)(struct timeb *ptr)
+
+void _STD(ftime)(struct timeb *pTimeBuf)
 {
-    LIBCLOG_ENTER("ptr=%p\n", (void *)ptr);
+    LIBCLOG_ENTER("pTimeBuf=%p\n", (void *)pTimeBuf);
 
+    /* Call tzset if required. */
     if (!__libc_gfTZInfoOk)
         tzset();
 
-    __ftime(ptr);
-    time_t t_loc;
-    t_loc = ptr->time;
-    ptr->dstflag = _loc2gmt(&ptr->time, -1);
-    ptr->timezone = __libc_gTZInfo.tz / 60;
+    /* Get the current time (UCT). */
+    struct timespec TimeSpec = {0, 0};
+    __libc_Back_timeGet(&TimeSpec);
 
-    LIBCLOG_RETURN_MSG_VOID("ptr=%p:{.time=%ld, .millitm=%u, .timezone=%d, .dstflag=%d}\n",
-                            (void *)ptr, (long)ptr->time, ptr->millitm, ptr->timezone, ptr->dstflag);
+    /* Convert the timespec to the timeb output struct. */
+    pTimeBuf->time = TimeSpec.tv_sec;
+    pTimeBuf->millitm = TimeSpec.tv_nsec / 1000000;
+    pTimeBuf->timezone = __libc_gTZInfo.tz / 60;
+    pTimeBuf->dstflag = _gmt2loc(&TimeSpec.tv_sec);
+
+    LIBCLOG_RETURN_MSG_VOID("ret void - pTimeBuf=%p:{.time=%lld, .millitm=%u, .timezone=%d, .dstflag=%d}\n",
+                            (void *)pTimeBuf, (long long)pTimeBuf->time, pTimeBuf->millitm, pTimeBuf->timezone, pTimeBuf->dstflag);
 }
 
Index: /trunk/libc/src/libc/time/gettimeofday.c
===================================================================
--- /trunk/libc/src/libc/time/gettimeofday.c	(revision 2909)
+++ /trunk/libc/src/libc/time/gettimeofday.c	(revision 2910)
@@ -1,47 +1,78 @@
-/* gettimeo.c (emx+gcc) -- Copyright (c) 1993-1996 by Eberhard Mattes */
+/* $Id: $ */
+/** @file
+ *
+ * kLIBC - gettimeofday().
+ *
+ * Copyright (c) 2006 knut st. osmundsen <bird-srcspam@anduin.net>
+ *
+ *
+ * This file is part of kLIBC.
+ *
+ * kLIBC 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 of the License, or
+ * (at your option) any later version.
+ *
+ * kLIBC 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 kLIBC; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
 
 #include "libc-alias.h"
-#include <sys/timeb.h>
-#include <time.h>
 #include <sys/time.h>
+#include <errno.h>
 #include <klibc/time.h>
-#include <emx/syscalls.h>
+#include <klibc/backend.h>
 #define __LIBC_LOG_GROUP __LIBC_LOG_GRP_TIME
 #include <klibc/logstrict.h>
 
-int _STD(gettimeofday)(struct timeval *tp, struct timezone *tzp)
+int _STD(gettimeofday)(struct timeval *pTime, struct timezone *pTZ)
 {
-    LIBCLOG_ENTER("tp=%p tzp=%p\n", (void *)tp, (void *)tzp);
-    struct timeb tb;
-    time_t t_loc;
-    int dst;
+    LIBCLOG_ENTER("pTime=%p pTZ=%p\n", (void *)pTime, (void *)pTZ);
 
+    /* call tzset if required. */
     if (!__libc_gfTZInfoOk)
         tzset();
-    __ftime(&tb);
-    t_loc = tb.time;
-    dst = _loc2gmt(&tb.time, -1);
-    if (tp != NULL)
+
+    /* get the time if requested. */
+    if (pTime)
     {
-        tp->tv_sec = tb.time;
-        tp->tv_usec = tb.millitm * 1000;
-    }
-    if (tzp != NULL)
-    {
-        tzp->tz_minuteswest = __libc_gTZInfo.tz / 60;
-        tzp->tz_dsttime = dst;
+        struct timespec TimeSpec;
+        int rc = __libc_Back_timeGet(&TimeSpec);
+        if (rc)
+        {
+            errno = rc;
+            LIBCLOG_ERROR_RETURN_INT(-1);
+        }
+
+        /* convert */
+        pTime->tv_usec = TimeSpec.tv_nsec / 1000;
+        pTime->tv_sec = TimeSpec.tv_sec;
     }
 
+    /* construct the timezone info if requested */
+    if (pTZ)
+    {
+        pTZ->tz_minuteswest = __libc_gTZInfo.tz / 60;
+        pTZ->tz_dsttime = __libc_gTZInfo.dst; /** @todo Figure out tz_dsttime! */
+    }
 
-    if (tp && tzp)
-        LIBCLOG_RETURN_MSG(0, "ret 0 - tp=%p:{.tv_sec=%ld, .tv_usec=%ld} tzp=%p:{.tz_minuteswest=%d, .tz_dsttime=%d}\n",
-                           (void *)tp, tp->tv_sec, tp->tv_usec,
-                           (void *)tzp, tzp->tz_minuteswest, tzp->tz_dsttime);
-    else if (tp)
-        LIBCLOG_RETURN_MSG(0, "ret 0 - tp=%p:{.tv_sec=%ld, .tv_usec=%ld}\n",
-                           (void *)tp, tp->tv_sec, tp->tv_usec);
+    /* done */
+    if (pTime && pTZ)
+        LIBCLOG_RETURN_MSG(0, "ret 0 - pTime=%p:{.tv_sec=%ld, .tv_usec=%ld} pTZ=%p:{.tz_minuteswest=%d, .tz_dsttime=%d}\n",
+                           (void *)pTime, pTime->tv_sec, pTime->tv_usec,
+                           (void *)pTZ, pTZ->tz_minuteswest, pTZ->tz_dsttime);
+    else if (pTime)
+        LIBCLOG_RETURN_MSG(0, "ret 0 - pTime=%p:{.tv_sec=%ld, .tv_usec=%ld}\n",
+                           (void *)pTime, pTime->tv_sec, pTime->tv_usec);
     else
-        LIBCLOG_RETURN_MSG(0, "ret 0 - tzp=%p:{.tz_minuteswest=%d, .tz_dsttime=%d}\n",
-                           (void *)tzp, tzp->tz_minuteswest, tzp->tz_dsttime);
+        LIBCLOG_RETURN_MSG(0, "ret 0 - pTZ=%p:{.tz_minuteswest=%d, .tz_dsttime=%d}\n",
+                           (void *)pTZ, pTZ->tz_minuteswest, pTZ->tz_dsttime);
 }
 
Index: /trunk/libc/src/libc/time/gmtloc.c
===================================================================
--- /trunk/libc/src/libc/time/gmtloc.c	(revision 2909)
+++ /trunk/libc/src/libc/time/gmtloc.c	(revision 2910)
@@ -270,5 +270,6 @@
         return sw->shift != 0;
     }
-    else if (is_dst == 0)
+
+    if (is_dst == 0)
     {
         /* Our caller says that *P is specified as standard time.
@@ -283,45 +284,43 @@
         return sw->shift != 0;
     }
-    else
-    {
-        /* Our caller does not know whether *P is specified as DST or
-           standard time.  Try to find out.  First try DST. */
-
-        count = 0;
-        if (ADD_OK(*p, __libc_gTZInfo.tz - __libc_gTZInfo.shift))
-        {
-            x = *p + __libc_gTZInfo.tz - __libc_gTZInfo.shift;
-            sw = find_switch(x);
-            if (sw->shift != 0)
-            {
-                *p = x;
-                return 1;         /* DST */
-            }
-            ++count;
-        }
-
-        if (ADD_OK(*p, __libc_gTZInfo.tz))
-        {
-            x = *p + __libc_gTZInfo.tz;
-            sw = find_switch(x);
-            if (sw->shift == 0)
-            {
-                *p = x;
-                return 0;         /* Not DST */
-            }
-            ++count;
-        }
-
-        if (count != 2)
-            return -1;            /* Overflow */
-
-        /* Assume that DST does not apply in the gap.  This makes moving
-           into the gap from below work, but breaks moving into the gap
-           from above.  The advantage of this choice is that ftime()
-           works correctly in the gap if the clock is not adjusted. */
-
-        *p += __libc_gTZInfo.tz;
-        return 0;                 /* Not DST */
-    }
+
+    /* Our caller does not know whether *P is specified as DST or
+       standard time.  Try to find out.  First try DST. */
+
+    count = 0;
+    if (ADD_OK(*p, __libc_gTZInfo.tz - __libc_gTZInfo.shift))
+    {
+        x = *p + __libc_gTZInfo.tz - __libc_gTZInfo.shift;
+        sw = find_switch(x);
+        if (sw->shift != 0)
+        {
+            *p = x;
+            return 1;         /* DST */
+        }
+        ++count;
+    }
+
+    if (ADD_OK(*p, __libc_gTZInfo.tz))
+    {
+        x = *p + __libc_gTZInfo.tz;
+        sw = find_switch(x);
+        if (sw->shift == 0)
+        {
+            *p = x;
+            return 0;         /* Not DST */
+        }
+        ++count;
+    }
+
+    if (count != 2)
+        return -1;            /* Overflow */
+
+    /* Assume that DST does not apply in the gap.  This makes moving
+       into the gap from below work, but breaks moving into the gap
+       from above.  The advantage of this choice is that ftime()
+       works correctly in the gap if the clock is not adjusted. */
+
+    *p += __libc_gTZInfo.tz;
+    return 0;                 /* Not DST */
 }
 
@@ -352,5 +351,6 @@
         return sw->shift != 0;
     }
-    else if (is_dst == 0)
+
+    if (is_dst == 0)
     {
         /* Our caller says that *P is specified as standard time.
@@ -364,43 +364,41 @@
         return sw->shift != 0;
     }
-    else
-    {
-        /* Our caller does not know whether *P is specified as DST or
-           standard time.  Try to find out.  First try DST. */
-        count = 0;
-        x = *p + __libc_gTZInfo.tz - __libc_gTZInfo.shift;
-        if (!(__libc_gTZInfo.tz - __libc_gTZInfo.shift > 0 ? x < *p : x > *p))
-        {
-            sw = find_switch(x);
-            if (sw->shift != 0)
-            {
-                *p = x;
-                return 1;         /* DST */
-            }
-            ++count;
-        }
-
-        x = *p + __libc_gTZInfo.tz;
-        if (!(__libc_gTZInfo.tz > 0 ? x < *p : x > *p))
-        {
-            sw = find_switch(x);
-            if (sw->shift == 0)
-            {
-                *p = x;
-                return 0;         /* Not DST */
-            }
-            ++count;
-        }
-
-        if (count != 2)
-            return -1;            /* Overflow */
-
-        /* Assume that DST does not apply in the gap.  This makes moving
-           into the gap from below work, but breaks moving into the gap
-           from above.  The advantage of this choice is that ftime()
-           works correctly in the gap if the clock is not adjusted. */
-        *p += __libc_gTZInfo.tz;
-        return 0;                 /* Not DST */
-    }
-}
-
+
+    /* Our caller does not know whether *P is specified as DST or
+       standard time.  Try to find out.  First try DST. */
+    count = 0;
+    x = *p + __libc_gTZInfo.tz - __libc_gTZInfo.shift;
+    if (!(__libc_gTZInfo.tz - __libc_gTZInfo.shift > 0 ? x < *p : x > *p))
+    {
+        sw = find_switch(x);
+        if (sw->shift != 0)
+        {
+            *p = x;
+            return 1;         /* DST */
+        }
+        ++count;
+    }
+
+    x = *p + __libc_gTZInfo.tz;
+    if (!(__libc_gTZInfo.tz > 0 ? x < *p : x > *p))
+    {
+        sw = find_switch(x);
+        if (sw->shift == 0)
+        {
+            *p = x;
+            return 0;         /* Not DST */
+        }
+        ++count;
+    }
+
+    if (count != 2)
+        return -1;            /* Overflow */
+
+    /* Assume that DST does not apply in the gap.  This makes moving
+       into the gap from below work, but breaks moving into the gap
+       from above.  The advantage of this choice is that ftime()
+       works correctly in the gap if the clock is not adjusted. */
+    *p += __libc_gTZInfo.tz;
+    return 0;                 /* Not DST */
+}
+
Index: /trunk/libc/src/libc/time/settimeofday.c
===================================================================
--- /trunk/libc/src/libc/time/settimeofday.c	(revision 2909)
+++ /trunk/libc/src/libc/time/settimeofday.c	(revision 2910)
@@ -1,35 +1,79 @@
-/* settimeo.c (emx+gcc) -- Copyright (c) 1995-1996 by Eberhard Mattes */
+/* $Id: $ */
+/** @file
+ *
+ * kLIBC - settimeofday().
+ *
+ * Copyright (c) 2006 knut st. osmundsen <bird-srcspam@anduin.net>
+ *
+ *
+ * This file is part of kLIBC.
+ *
+ * kLIBC 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 of the License, or
+ * (at your option) any later version.
+ *
+ * kLIBC 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 kLIBC; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
 
 #include "libc-alias.h"
-#include <time.h>
 #include <sys/time.h>
 #include <errno.h>
-#include <klibc/time.h>
-#include <emx/syscalls.h> /** @todo fixme! */
+#include <klibc/backend.h>
 #define __LIBC_LOG_GROUP __LIBC_LOG_GRP_TIME
 #include <klibc/logstrict.h>
 
-int _STD(settimeofday)(const struct timeval *tp, const struct timezone *tzp)
+
+/**
+ * Set the time of day and/or modify the kernel timezone.
+ *
+ * @remark  Unlike the BSD implementation, this call will never fail with permission
+ *          denied when both parameters are NULL.
+ * @remark  Changing the time zone is not yet implemented.
+ */
+int _STD(settimeofday)(const struct timeval *pNewTime, const struct timezone *pNewTZ)
 {
-    LIBCLOG_ENTER("tp=%p:{.tv_sec=%lld, .tv_usec=%ld} tzp=%p:{.tz_minuteswest=%d, .tz_dsttime=%d}\n",
-                  (void *)tp, tp ? (long long)tp->tv_sec : -1, tp ? (long)tp->tv_usec : -1,
-                  (void *)tzp, tzp ? tzp->tz_minuteswest : -1, tzp ? tzp->tz_dsttime : -1);
-    struct timeval local;
-    time_t t;
+    LIBCLOG_ENTER("pNewTime=%p:{.tv_sec=%lld, .tv_usec=%ld} pNewTZ=%p:{.tz_minuteswest=%d, .tz_dsttime=%d}\n",
+                  (void *)pNewTime, pNewTime ? (long long)pNewTime->tv_sec : -1, pNewTime ? (long)pNewTime->tv_usec : -1,
+                  (void *)pNewTZ, pNewTZ ? pNewTZ->tz_minuteswest : -1, pNewTZ ? pNewTZ->tz_dsttime : -1);
 
-    if (tzp != NULL)
+    if (pNewTime)
     {
-        errno = EINVAL;
-        LIBCLOG_ERROR_RETURN(-1, "ret -1 - tzp is NULL!\n");
+        /* Convert to timespec and normalize the input (specs?). */
+        struct timespec TimeSpec;
+        TimeSpec.tv_sec = pNewTime->tv_sec;
+        TimeSpec.tv_nsec = pNewTime->tv_usec * 1000;
+        while (TimeSpec.tv_nsec < 0)
+        {
+            TimeSpec.tv_nsec += 1000000000;
+            TimeSpec.tv_sec--;
+        }
+        while (TimeSpec.tv_nsec > 1000000000)
+        {
+            TimeSpec.tv_nsec -=  1000000000;
+            TimeSpec.tv_sec++;
+        }
+        int rc = __libc_Back_timeSet(&TimeSpec);
+        if (rc)
+        {
+            errno = -rc;
+            LIBCLOG_ERROR_RETURN_INT(-1);
+        }
     }
-    if (!__libc_gfTZInfoOk)
-        tzset();
-    t = tp->tv_sec;
-    _gmt2loc(&t);
-    local.tv_sec = t;
-    local.tv_usec = tp->tv_usec;
-    int rc = __settime(&local);
-    if (!rc)
-        LIBCLOG_RETURN_INT(rc);
-    LIBCLOG_ERROR_RETURN_INT(rc);
+
+    if (pNewTZ)
+    {
+        /** @todo implement pNewTZ */
+    }
+
+    LIBCLOG_RETURN_INT(0);
 }
+
Index: /trunk/libc/src/libc/time/timetabs.c
===================================================================
--- /trunk/libc/src/libc/time/timetabs.c	(revision 2909)
+++ /trunk/libc/src/libc/time/timetabs.c	(revision 2910)
@@ -31,5 +31,4 @@
 #include "libc-alias.h"
 #include <klibc/time.h>
-#include <limits.h>
 
 
@@ -58,5 +57,5 @@
     25567, 25933, 26298, 26663, 27028, 27394, 27759, 28124, 28489, 28855,  /* 2040 - 2049 */
     29220, 29585, 29950, 30316, 30681, 31046, 31411, 31777, 32142, 32507,  /* 2050 - 2059 */
-    SHRT_MAX
+    0x7fff
 };
 
@@ -65,7 +64,7 @@
  * The day number is relative to 01-Jan, of day 01 for January through December.
  */
-uint16_t const __libc_gauMonthDayNonLeap[] =
+uint16_t const __libc_gauMonthDayNonLeap[12+1] =
 {
-    0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, USHRT_MAX
+    0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 0xffff
 };
 
@@ -74,7 +73,7 @@
  * The day number is relative to 01-Jan, of day 01 for January through December.
  */
-uint16_t const __libc_gauMonthDayLeap[] =
+uint16_t const __libc_gauMonthDayLeap[12+1] =
 {
-    0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, USHRT_MAX
+    0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 0xffff
 };
 
