about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2019-10-20 01:43:22 -0400
committerRich Felker <dalias@aerifal.cx>2019-10-20 01:43:22 -0400
commit928674dcd0c5c643b8a4440466103be841151f5e (patch)
tree8a3af196a753e9aca618ff96b78e7bf3e69976ba /src
parent5850546e9669f793aab61dfc7c4f2c1ff35c4b29 (diff)
downloadmusl-928674dcd0c5c643b8a4440466103be841151f5e.tar.gz
musl-928674dcd0c5c643b8a4440466103be841151f5e.tar.xz
musl-928674dcd0c5c643b8a4440466103be841151f5e.zip
clock_adjtime: generalize time64 not to assume old struct layout match
commit 2b4fd6f75b4fa66d28cddcf165ad48e8fda486d1 added time64 for this
function, but did so with a hidden assumption that the new time64
version of struct timex will be layout-compatible with the old one.
however, there is little benefit to doing it that way, and the cost is
permanent special-casing of 32-bit archs with 64-bit time_t in the
public interface definitions.

instead, do a full translation of the structure going in and out. this
commit is actually a revision to an earlier uncommited version of the
code.
Diffstat (limited to 'src')
-rw-r--r--src/linux/clock_adjtime.c57
1 files changed, 46 insertions, 11 deletions
diff --git a/src/linux/clock_adjtime.c b/src/linux/clock_adjtime.c
index 2f531397..23eb8729 100644
--- a/src/linux/clock_adjtime.c
+++ b/src/linux/clock_adjtime.c
@@ -94,21 +94,56 @@ int clock_adjtime (clockid_t clock_id, struct timex *utx)
 		return __syscall_ret(-ENOTSUP);
 #endif
 	if (sizeof(time_t) > sizeof(long)) {
-		union {
-			struct timex utx;
-			struct ktimex ktx;
-		} u = { *utx };
-		u.ktx.time_sec = utx->time.tv_sec;
-		u.ktx.time_usec = utx->time.tv_usec;
+		struct ktimex ktx = {
+			.modes = utx->modes,
+			.offset = utx->offset,
+			.freq = utx->freq,
+			.maxerror = utx->maxerror,
+			.esterror = utx->esterror,
+			.status = utx->status,
+			.constant = utx->constant,
+			.precision = utx->precision,
+			.tolerance = utx->tolerance,
+			.time_sec = utx->time.tv_sec,
+			.time_usec = utx->time.tv_usec,
+			.tick = utx->tick,
+			.ppsfreq = utx->ppsfreq,
+			.jitter = utx->jitter,
+			.shift = utx->shift,
+			.stabil = utx->stabil,
+			.jitcnt = utx->jitcnt,
+			.calcnt = utx->calcnt,
+			.errcnt = utx->errcnt,
+			.stbcnt = utx->stbcnt,
+			.tai = utx->tai,
+		};
 #ifdef SYS_adjtimex
-		if (clock_id==CLOCK_REALTIME) r = __syscall(SYS_adjtimex, &u);
+		if (clock_id==CLOCK_REALTIME) r = __syscall(SYS_adjtimex, &ktx);
 		else
 #endif
-		r = __syscall(SYS_clock_adjtime, clock_id, &u);
+		r = __syscall(SYS_clock_adjtime, clock_id, &ktx);
 		if (r>=0) {
-			*utx = u.utx;
-			utx->time.tv_sec = u.ktx.time_sec;
-			utx->time.tv_usec = u.ktx.time_usec;
+			utx->modes = ktx.modes;
+			utx->offset = ktx.offset;
+			utx->freq = ktx.freq;
+			utx->maxerror = ktx.maxerror;
+			utx->esterror = ktx.esterror;
+			utx->status = ktx.status;
+			utx->constant = ktx.constant;
+			utx->precision = ktx.precision;
+			utx->tolerance = ktx.tolerance;
+			utx->time.tv_sec = ktx.time_sec;
+			utx->time.tv_usec = ktx.time_usec;
+			utx->tick = ktx.tick;
+			utx->ppsfreq = ktx.ppsfreq;
+			utx->jitter = ktx.jitter;
+			utx->shift = ktx.shift;
+			utx->stabil = ktx.stabil;
+			utx->jitcnt = ktx.jitcnt;
+			utx->calcnt = ktx.calcnt;
+			utx->errcnt = ktx.errcnt;
+			utx->stbcnt = ktx.stbcnt;
+			utx->tai = ktx.tai;
 		}
 		return __syscall_ret(r);
 	}