On Tue, Apr 24, 2012 at 04:27:00PM +0400, Vadim Zhukov wrote:
> This will somewhat break dual-booting machines with Windblows as
> second OS. :(

Okay, here's an alternative diff that only affects gettimeofday() and
settimeofday(). Users can still set the kernel timezone through
config(8) or boot_config(8), and it will still be used to compensate
for a non-UTC clock, but that's all the kernel timezone will be used
for. As far as userland will see, the kernel will appear hard
configured for UTC: gettimeofday() will always return a UTC timezone
and settimeofday() will return EINVAL if you try to set a non-UTC
timezone.

In base, this should only affect users of date(1)'s -d and -t options,
but I plan to remove those anyway if this diff goes in.

I'm very interested in hearing from Windows dual-booters who use local
time RTCs whether this has any negative consequences for them.


Index: kern_time.c
===================================================================
RCS file: /home/mdempsky/anoncvs/cvs/src/sys/kern/kern_time.c,v
retrieving revision 1.74
diff -u -p -r1.74 kern_time.c
--- kern_time.c 23 Mar 2012 15:51:26 -0000      1.74
+++ kern_time.c 24 Apr 2012 16:17:44 -0000
@@ -391,8 +458,10 @@ sys_gettimeofday(struct proc *p, void *v
                }
 #endif
        }
-       if (tzp)
-               error = copyout(&tz, tzp, sizeof (tz));
+       if (tzp) {
+               const struct timezone tz0 = { 0 };
+               error = copyout(&tz0, tzp, sizeof(tz0));
+       }
        return (error);
 }
 
@@ -415,20 +484,22 @@ sys_settimeofday(struct proc *p, void *v
 
        if ((error = suser(p, 0)))
                return (error);
-       /* Verify all parameters before changing time. */
-       if (tv && (error = copyin(tv, &atv, sizeof(atv))))
-               return (error);
-       if (tzp && (error = copyin(tzp, &atz, sizeof(atz))))
-               return (error);
+       if (tzp) {
+               if ((error = copyin(tzp, &atz, sizeof(atz))) != 0)
+                       return (error);
+               if (atz.tz_minuteswest != 0 || atz.tz_dsttime != 0)
+                       return (EINVAL);
+       }
        if (tv) {
                struct timespec ts;
 
+               if ((error = copyin(tv, &atv, sizeof(atv))) != 0)
+                       return (error);
+
                TIMEVAL_TO_TIMESPEC(&atv, &ts);
                if ((error = settime(&ts)) != 0)
                        return (error);
        }
-       if (tzp)
-               tz = atz;
        return (0);
 }

Reply via email to