'struct timeval' and 'struct time_value' have different types for the
microseconds component: int and long int. Casting one to the other
leads to negative numbers not being preserved properly within the
called code.
---
sysdeps/mach/hurd/adjtime.c | 27 +++++++++++++++++++--------
1 file changed, 19 insertions(+), 8 deletions(-)
diff --git a/sysdeps/mach/hurd/adjtime.c b/sysdeps/mach/hurd/adjtime.c
index c25b666a22..e9c0851daa 100644
--- a/sysdeps/mach/hurd/adjtime.c
+++ b/sysdeps/mach/hurd/adjtime.c
@@ -28,24 +28,35 @@ __adjtime (const struct timeval *delta, struct timeval
*olddelta)
{
error_t err;
mach_port_t hostpriv;
- struct timeval dummy;
+ time_value_t rpc_delta, rpc_olddelta;
err = __get_privileged_ports (&hostpriv, NULL);
if (err)
return __hurd_fail (EPERM);
- if (olddelta == NULL)
- olddelta = &dummy;
+ if (delta != NULL)
+ {
+ rpc_delta.seconds = delta->tv_sec;
- err = __host_adjust_time (hostpriv,
- /* `time_value_t' and `struct timeval' are in
- fact identical with the names changed. */
- *(time_value_t *) delta,
- (time_value_t *) olddelta);
+ /* Handle overflow if microsecond types differ. */
+ rpc_delta.microseconds = (delta->tv_usec % TIME_MICROS_MAX);
+ rpc_delta.seconds += (delta->tv_usec / TIME_MICROS_MAX);
+ }
+ else
+ return EINVAL;
+
+ err = __host_adjust_time (hostpriv, rpc_delta, &rpc_olddelta);
__mach_port_deallocate (__mach_task_self (), hostpriv);
if (err)
return __hurd_fail (err);
+
+ if (olddelta != NULL)
+ {
+ olddelta->tv_sec = rpc_olddelta.seconds;
+ olddelta->tv_usec = rpc_olddelta.microseconds;
+ }
+
return 0;
}
--
2.47.3