From 88811b7d0413ef4b48566e52eca4f91c37be3a3f Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Sun, 14 May 2023 23:27:51 -0700 Subject: timespec: fill in other members MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This problem was found when compiling GNU Emacs with --enable-gcc-warnings on a platform where tv_sec is 64 bits and tv_nsec is 32 bits, and struct timespec has padding. GCC -Wuse-of-uninitialized-value complained when a struct timespec initialized only via assigning to tv_sec and tv_nsec was copied via assignment (this was in lib/timespec.h’s make_timespec). Although behavior is well-defined on this platform, the warning is annoying and the behavior might not be well-defined on theoretical platforms where struct timespec has other members. To work around this, initialize all the struct’s members. * lib/getsockopt.c (rpl_getsockopt): * lib/gettime.c (gettime): * lib/gettimeofday.c (gettimeofday): * lib/glthread/thread.c (gl_thread_self): * lib/nanosleep.c (nanosleep): * lib/parse-datetime.y (digits_to_date_time, set_hhmmss) (signed_seconds, unsigned_seconds, yylex, parse_datetime_body): * lib/poll.c (poll): * lib/pselect.c (pselect): * lib/pthread-cond.c (endlessly, pthread_cond_timedwait): * lib/pthread-rwlock.c (pthread_rwlock_timedrdlock) (pthread_rwlock_timedwrlock): * lib/pthread_mutex_timedlock.c (pthread_mutex_timedlock): * lib/select.c (rpl_select): * lib/settime.c (settime): * lib/stat-time.h (get_stat_atime, get_stat_ctime) (get_stat_mtime, get_stat_birthtime): * lib/thrd.c (rpl_thrd_current): * lib/timespec.h (make_timespec): * lib/timespec_getres.c (timespec_getres): * lib/utimecmp.c (utimecmpat): * lib/utimens.c (fdutimens): When filling in a struct timespec or similar time-related structure that might be copied elsewhere, also assign to any storage other than tv_sec and tv_nsec, to avoid undefined behavior on (likely theoretical) platforms where struct timespec has other members, and also to avoid warnings from GCC and/or valgrind. --- ChangeLog | 39 +++++++++++++++++++++++++++++++++++++++ lib/getsockopt.c | 7 ++++--- lib/gettime.c | 4 ++-- lib/gettimeofday.c | 14 ++++++-------- lib/glthread/thread.c | 4 +--- lib/nanosleep.c | 3 +-- lib/parse-datetime.y | 17 +++++++---------- lib/poll.c | 9 +++++---- lib/pselect.c | 6 ++++-- lib/pthread-cond.c | 10 +++------- lib/pthread-rwlock.c | 8 ++------ lib/pthread_mutex_timedlock.c | 4 +--- lib/select.c | 2 +- lib/settime.c | 6 ++---- lib/stat-time.h | 33 +++++++++++---------------------- lib/thrd.c | 4 +--- lib/timespec.h | 5 +---- lib/timespec_getres.c | 4 ++-- lib/utimecmp.c | 11 ++++++----- lib/utimens.c | 20 ++++++++++---------- 20 files changed, 109 insertions(+), 101 deletions(-) diff --git a/ChangeLog b/ChangeLog index 34e7d72130..3ed1b1ef8f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,44 @@ 2023-05-14 Paul Eggert + timespec: fill in other members + This problem was found when compiling GNU Emacs with + --enable-gcc-warnings on a platform where tv_sec is 64 bits and + tv_nsec is 32 bits, and struct timespec has padding. GCC + -Wuse-of-uninitialized-value complained when a struct timespec + initialized only via assigning to tv_sec and tv_nsec was copied + via assignment (this was in lib/timespec.h’s make_timespec). + Although behavior is well-defined on this platform, the warning is + annoying and the behavior might not be well-defined on theoretical + platforms where struct timespec has other members. To work around + this, initialize all the struct’s members. + * lib/getsockopt.c (rpl_getsockopt): + * lib/gettime.c (gettime): + * lib/gettimeofday.c (gettimeofday): + * lib/glthread/thread.c (gl_thread_self): + * lib/nanosleep.c (nanosleep): + * lib/parse-datetime.y (digits_to_date_time, set_hhmmss) + (signed_seconds, unsigned_seconds, yylex, parse_datetime_body): + * lib/poll.c (poll): + * lib/pselect.c (pselect): + * lib/pthread-cond.c (endlessly, pthread_cond_timedwait): + * lib/pthread-rwlock.c (pthread_rwlock_timedrdlock) + (pthread_rwlock_timedwrlock): + * lib/pthread_mutex_timedlock.c (pthread_mutex_timedlock): + * lib/select.c (rpl_select): + * lib/settime.c (settime): + * lib/stat-time.h (get_stat_atime, get_stat_ctime) + (get_stat_mtime, get_stat_birthtime): + * lib/thrd.c (rpl_thrd_current): + * lib/timespec.h (make_timespec): + * lib/timespec_getres.c (timespec_getres): + * lib/utimecmp.c (utimecmpat): + * lib/utimens.c (fdutimens): + When filling in a struct timespec or similar time-related structure + that might be copied elsewhere, also assign to any storage other + than tv_sec and tv_nsec, to avoid undefined behavior on (likely + theoretical) platforms where struct timespec has other members, + and also to avoid warnings from GCC and/or valgrind. + year2038-recommended: Improve failure diagnostic. * m4/largefile.m4 (AC_SYS_YEAR2038_RECOMMENDED): Sync from Autoconf. diff --git a/lib/getsockopt.c b/lib/getsockopt.c index 565c38ef07..06302652af 100644 --- a/lib/getsockopt.c +++ b/lib/getsockopt.c @@ -53,13 +53,14 @@ rpl_getsockopt (int fd, int level, int optname, void *optval, socklen_t *optlen) { int milliseconds; int milliseconds_len = sizeof (int); - struct timeval tv; size_t n; r = getsockopt (sock, level, optname, (char *) &milliseconds, &milliseconds_len); - tv.tv_sec = milliseconds / 1000; - tv.tv_usec = (milliseconds - 1000 * tv.tv_sec) * 1000; + struct timeval tv = { + .tv_sec = milliseconds / 1000, + .tv_usec = (milliseconds % 1000) * 1000 + }; n = sizeof (struct timeval); if (n > *optlen) n = *optlen; diff --git a/lib/gettime.c b/lib/gettime.c index f86cc4efbf..ec40ff903e 100644 --- a/lib/gettime.c +++ b/lib/gettime.c @@ -35,8 +35,8 @@ gettime (struct timespec *ts) #else struct timeval tv; gettimeofday (&tv, NULL); - ts->tv_sec = tv.tv_sec; - ts->tv_nsec = tv.tv_usec * 1000; + *ts = (struct timespec) { .tv_sec = tv.tv_sec, + .tv_nsec = tv.tv_usec * 1000 }; #endif } diff --git a/lib/gettimeofday.c b/lib/gettimeofday.c index d896ec132b..69b43a62c8 100644 --- a/lib/gettimeofday.c +++ b/lib/gettimeofday.c @@ -113,8 +113,10 @@ gettimeofday (struct timeval *restrict tv, void *restrict tz) ULONGLONG since_1970 = since_1601 - (ULONGLONG) 134774 * (ULONGLONG) 86400 * (ULONGLONG) 10000000; ULONGLONG microseconds_since_1970 = since_1970 / (ULONGLONG) 10; - tv->tv_sec = microseconds_since_1970 / (ULONGLONG) 1000000; - tv->tv_usec = microseconds_since_1970 % (ULONGLONG) 1000000; + *tv = (struct timeval) { + .tv_sec = microseconds_since_1970 / (ULONGLONG) 1000000, + .tv_usec = microseconds_since_1970 % (ULONGLONG) 1000000 + }; return 0; @@ -127,10 +129,7 @@ gettimeofday (struct timeval *restrict tv, void *restrict tz) struct timeval otv; int result = gettimeofday (&otv, (struct timezone *) tz); if (result == 0) - { - tv->tv_sec = otv.tv_sec; - tv->tv_usec = otv.tv_usec; - } + *tv = otv; # else int result = gettimeofday (tv, (struct timezone *) tz); # endif @@ -143,8 +142,7 @@ gettimeofday (struct timeval *restrict tv, void *restrict tz) # error "Only 1-second nominal clock resolution found. Is that intended?" \ "If so, compile with the -DOK_TO_USE_1S_CLOCK option." # endif - tv->tv_sec = time (NULL); - tv->tv_usec = 0; + *tv = (struct timeval) { .tv_sec = time (NULL) }; return 0; diff --git a/lib/glthread/thread.c b/lib/glthread/thread.c index 1f28be59c8..3352159edc 100644 --- a/lib/glthread/thread.c +++ b/lib/glthread/thread.c @@ -139,9 +139,7 @@ gl_thread_self (void) /* Memory allocation failed. There is not much we can do. Have to busy-loop, waiting for the availability of memory. */ { - struct timespec ts; - ts.tv_sec = 1; - ts.tv_nsec = 0; + struct timespec ts = { .tv_sec = 1 }; thrd_sleep (&ts, NULL); } } diff --git a/lib/nanosleep.c b/lib/nanosleep.c index 3f295f49b5..10974df461 100644 --- a/lib/nanosleep.c +++ b/lib/nanosleep.c @@ -60,8 +60,7 @@ nanosleep (const struct timespec *requested_delay, static_assert (TYPE_MAXIMUM (time_t) / 24 / 24 / 60 / 60); const time_t limit = 24 * 24 * 60 * 60; time_t seconds = requested_delay->tv_sec; - struct timespec intermediate; - intermediate.tv_nsec = requested_delay->tv_nsec; + struct timespec intermediate = *requested_delay; while (limit < seconds) { diff --git a/lib/parse-datetime.y b/lib/parse-datetime.y index 45c5e43415..a0487a3713 100644 --- a/lib/parse-datetime.y +++ b/lib/parse-datetime.y @@ -281,8 +281,7 @@ digits_to_date_time (parser_control *pc, textint text_int) pc->hour = text_int.value / 100; pc->minutes = text_int.value % 100; } - pc->seconds.tv_sec = 0; - pc->seconds.tv_nsec = 0; + pc->seconds = (struct timespec) {0}; pc->meridian = MER24; } } @@ -320,8 +319,7 @@ set_hhmmss (parser_control *pc, intmax_t hour, intmax_t minutes, { pc->hour = hour; pc->minutes = minutes; - pc->seconds.tv_sec = sec; - pc->seconds.tv_nsec = nsec; + pc->seconds = (struct timespec) { .tv_sec = sec, .tv_nsec = nsec }; } /* Return a textual representation of the day ordinal/number values @@ -966,14 +964,14 @@ signed_seconds: tSDECIMAL_NUMBER | tSNUMBER { if (time_overflow ($1.value)) YYABORT; - $$.tv_sec = $1.value; $$.tv_nsec = 0; } + $$ = (struct timespec) { .tv_sec = $1.value }; } ; unsigned_seconds: tUDECIMAL_NUMBER | tUNUMBER { if (time_overflow ($1.value)) YYABORT; - $$.tv_sec = $1.value; $$.tv_nsec = 0; } + $$ = (struct timespec) { .tv_sec = $1.value }; } ; number: @@ -1480,8 +1478,8 @@ yylex (union YYSTYPE *lvalp, parser_control *pc) ns = BILLION - ns; } - lvalp->timespec.tv_sec = s; - lvalp->timespec.tv_nsec = ns; + lvalp->timespec = (struct timespec) { .tv_sec = s, + .tv_nsec = ns }; pc->input = p; return sign ? tSDECIMAL_NUMBER : tUDECIMAL_NUMBER; } @@ -1812,8 +1810,7 @@ parse_datetime_body (struct timespec *result, char const *p, pc.day = tmp.tm_mday; pc.hour = tmp.tm_hour; pc.minutes = tmp.tm_min; - pc.seconds.tv_sec = tmp.tm_sec; - pc.seconds.tv_nsec = Start_ns; + pc.seconds = (struct timespec) { .tv_sec = tmp.tm_sec, .tv_nsec = Start_ns }; tm.tm_isdst = tmp.tm_isdst; pc.meridian = MER24; diff --git a/lib/poll.c b/lib/poll.c index a0dc2c5226..941fecf2d3 100644 --- a/lib/poll.c +++ b/lib/poll.c @@ -396,14 +396,15 @@ poll (struct pollfd *pfd, nfds_t nfd, int timeout) if (timeout == 0) { ptv = &tv; - ptv->tv_sec = 0; - ptv->tv_usec = 0; + tv = (struct timeval) {0}; } else if (timeout > 0) { ptv = &tv; - ptv->tv_sec = timeout / 1000; - ptv->tv_usec = (timeout % 1000) * 1000; + tv = (struct timeval) { + .tv_sec = timeout / 1000, + .tv_usec = (timeout % 1000) * 1000; + }; } else if (timeout == INFTIM) /* wait forever */ diff --git a/lib/pselect.c b/lib/pselect.c index 52d3837878..1b8c19130c 100644 --- a/lib/pselect.c +++ b/lib/pselect.c @@ -59,8 +59,10 @@ pselect (int nfds, fd_set *restrict rfds, return -1; } - tv.tv_sec = timeout->tv_sec; - tv.tv_usec = (timeout->tv_nsec + 999) / 1000; + tv = (struct timeval) { + .tv_sec = timeout->tv_sec, + .tv_usec = (timeout->tv_nsec + 999) / 1000 + }; tvp = &tv; } else diff --git a/lib/pthread-cond.c b/lib/pthread-cond.c index 8cf5424735..6980cc6ed9 100644 --- a/lib/pthread-cond.c +++ b/lib/pthread-cond.c @@ -115,10 +115,7 @@ pthread_cond_wait (_GL_UNUSED pthread_cond_t *cond, Wait endlessly. */ for (;;) { - struct timespec duration; - - duration.tv_sec = 86400; - duration.tv_nsec = 0; + struct timespec duration = { .tv_sec = 86400 }; nanosleep (&duration, NULL); } } @@ -134,7 +131,6 @@ pthread_cond_timedwait (_GL_UNUSED pthread_cond_t *cond, { struct timeval currtime; unsigned long remaining; - struct timespec duration; gettimeofday (&currtime, NULL); @@ -169,8 +165,8 @@ pthread_cond_timedwait (_GL_UNUSED pthread_cond_t *cond, return ETIMEDOUT; /* Sleep up to REMAINING ns. */ - duration.tv_sec = remaining / 1000000000; - duration.tv_nsec = remaining % 1000000000; + struct timespec duration = { .tv_sec = remaining / 1000000000, + .tv_nsec = remaining % 1000000000 }; nanosleep (&duration, NULL); } } diff --git a/lib/pthread-rwlock.c b/lib/pthread-rwlock.c index 8713d1abc2..5087661b0b 100644 --- a/lib/pthread-rwlock.c +++ b/lib/pthread-rwlock.c @@ -371,7 +371,6 @@ pthread_rwlock_timedrdlock (pthread_rwlock_t *lock, int err; struct timeval currtime; unsigned long remaining; - struct timespec duration; err = pthread_rwlock_tryrdlock (lock); if (err != EBUSY) @@ -410,8 +409,7 @@ pthread_rwlock_timedrdlock (pthread_rwlock_t *lock, return ETIMEDOUT; /* Sleep 1 ms. */ - duration.tv_sec = 0; - duration.tv_nsec = 1000000; + struct timespec duration = { .tv_nsec = 1000000 }; if (duration.tv_nsec > remaining) duration.tv_nsec = remaining; nanosleep (&duration, NULL); @@ -428,7 +426,6 @@ pthread_rwlock_timedwrlock (pthread_rwlock_t *lock, int err; struct timeval currtime; unsigned long remaining; - struct timespec duration; err = pthread_rwlock_trywrlock (lock); if (err != EBUSY) @@ -467,8 +464,7 @@ pthread_rwlock_timedwrlock (pthread_rwlock_t *lock, return ETIMEDOUT; /* Sleep 1 ms. */ - duration.tv_sec = 0; - duration.tv_nsec = 1000000; + struct timespec duration = { .tv_nsec = 1000000 }; if (duration.tv_nsec > remaining) duration.tv_nsec = remaining; nanosleep (&duration, NULL); diff --git a/lib/pthread_mutex_timedlock.c b/lib/pthread_mutex_timedlock.c index feecf6f519..2394092e83 100644 --- a/lib/pthread_mutex_timedlock.c +++ b/lib/pthread_mutex_timedlock.c @@ -39,7 +39,6 @@ pthread_mutex_timedlock (pthread_mutex_t *mutex, const struct timespec *abstime) int err; struct timeval currtime; unsigned long remaining; - struct timespec duration; err = pthread_mutex_trylock (mutex); if (err != EBUSY) @@ -78,8 +77,7 @@ pthread_mutex_timedlock (pthread_mutex_t *mutex, const struct timespec *abstime) return ETIMEDOUT; /* Sleep 1 ms. */ - duration.tv_sec = 0; - duration.tv_nsec = 1000000; + struct timespec duration = { .tv_nsec = 1000000 }; if (duration.tv_nsec > remaining) duration.tv_nsec = remaining; nanosleep (&duration, NULL); diff --git a/lib/select.c b/lib/select.c index 6b6ca4154c..991f475431 100644 --- a/lib/select.c +++ b/lib/select.c @@ -516,7 +516,7 @@ restart: goto restart; } if (timeout && wait_timeout == 0 && rc == 0) - timeout->tv_sec = timeout->tv_usec = 0; + timeout = (struct timeval) {0}; } /* Now fill in the results. */ diff --git a/lib/settime.c b/lib/settime.c index 376d85476a..2ce7c03300 100644 --- a/lib/settime.c +++ b/lib/settime.c @@ -41,10 +41,8 @@ settime (struct timespec const *ts) #if HAVE_SETTIMEOFDAY { - struct timeval tv; - - tv.tv_sec = ts->tv_sec; - tv.tv_usec = ts->tv_nsec / 1000; + struct timeval tv = { .tv_sec = ts->tv_sec, + .tv_usec = ts->tv_nsec / 1000 }; return settimeofday (&tv, 0); } #elif HAVE_STIME diff --git a/lib/stat-time.h b/lib/stat-time.h index 5b2702356e..af084102da 100644 --- a/lib/stat-time.h +++ b/lib/stat-time.h @@ -122,10 +122,8 @@ get_stat_atime (struct stat const *st) #ifdef STAT_TIMESPEC return STAT_TIMESPEC (st, st_atim); #else - struct timespec t; - t.tv_sec = st->st_atime; - t.tv_nsec = get_stat_atime_ns (st); - return t; + return (struct timespec) { .tv_sec = st->st_atime, + .tv_nsec = get_stat_atime_ns (st) }; #endif } @@ -136,10 +134,8 @@ get_stat_ctime (struct stat const *st) #ifdef STAT_TIMESPEC return STAT_TIMESPEC (st, st_ctim); #else - struct timespec t; - t.tv_sec = st->st_ctime; - t.tv_nsec = get_stat_ctime_ns (st); - return t; + return (struct timespec) { .tv_sec = st->st_ctime, + .tv_nsec = get_stat_ctime_ns (st) }; #endif } @@ -150,10 +146,8 @@ get_stat_mtime (struct stat const *st) #ifdef STAT_TIMESPEC return STAT_TIMESPEC (st, st_mtim); #else - struct timespec t; - t.tv_sec = st->st_mtime; - t.tv_nsec = get_stat_mtime_ns (st); - return t; + return (struct timespec) { .tv_sec = st->st_mtime, + .tv_nsec = get_stat_mtime_ns (st) }; #endif } @@ -168,8 +162,8 @@ get_stat_birthtime (_GL_UNUSED struct stat const *st) || defined HAVE_STRUCT_STAT_ST_BIRTHTIM_TV_NSEC) t = STAT_TIMESPEC (st, st_birthtim); #elif defined HAVE_STRUCT_STAT_ST_BIRTHTIMENSEC - t.tv_sec = st->st_birthtime; - t.tv_nsec = st->st_birthtimensec; + t = (struct timespec) { .tv_sec = st->st_birthtime, + .tv_nsec = st->st_birthtimensec }; #elif defined _WIN32 && ! defined __CYGWIN__ /* Native Windows platforms (but not Cygwin) put the "file creation time" in st_ctime (!). See @@ -177,13 +171,11 @@ get_stat_birthtime (_GL_UNUSED struct stat const *st) # if _GL_WINDOWS_STAT_TIMESPEC t = st->st_ctim; # else - t.tv_sec = st->st_ctime; - t.tv_nsec = 0; + t = (struct timespec) { .tv_sec = st->st_ctime }; # endif #else /* Birth time is not supported. */ - t.tv_sec = -1; - t.tv_nsec = -1; + t = (struct timespec) { .tv_sec = -1, .tv_nsec = -1 }; #endif #if (defined HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC_TV_NSEC \ @@ -195,10 +187,7 @@ get_stat_birthtime (_GL_UNUSED struct stat const *st) sometimes returns junk in the birth time fields; work around this bug if it is detected. */ if (! (t.tv_sec && 0 <= t.tv_nsec && t.tv_nsec < 1000000000)) - { - t.tv_sec = -1; - t.tv_nsec = -1; - } + t = (struct timespec) { .tv_sec = -1, .tv_nsec = -1 }; #endif return t; diff --git a/lib/thrd.c b/lib/thrd.c index bb0e10fc8b..1a13a51e00 100644 --- a/lib/thrd.c +++ b/lib/thrd.c @@ -143,9 +143,7 @@ rpl_thrd_current (void) /* Memory allocation failed. There is not much we can do. Have to busy-loop, waiting for the availability of memory. */ { - struct timespec ts; - ts.tv_sec = 1; - ts.tv_nsec = 0; + struct timespec ts = { .tv_sec = 1 }; thrd_sleep (&ts, NULL); } } diff --git a/lib/timespec.h b/lib/timespec.h index 0bdfd76ef7..e94da75def 100644 --- a/lib/timespec.h +++ b/lib/timespec.h @@ -55,10 +55,7 @@ enum { LOG10_TIMESPEC_RESOLUTION = LOG10_TIMESPEC_HZ }; _GL_TIMESPEC_INLINE struct timespec make_timespec (time_t s, long int ns) { - struct timespec r; - r.tv_sec = s; - r.tv_nsec = ns; - return r; + return (struct timespec) { .tv_sec = s, .tv_nsec = ns }; } /* Return negative, zero, positive if A < B, A == B, A > B, respectively. */ diff --git a/lib/timespec_getres.c b/lib/timespec_getres.c index 38193d2a1b..0efaf14712 100644 --- a/lib/timespec_getres.c +++ b/lib/timespec_getres.c @@ -31,8 +31,8 @@ timespec_getres (struct timespec *ts, int base) clock_getres (CLOCK_REALTIME, ts); #else long int res = gettime_res (); - ts->tv_sec = res / TIMESPEC_HZ; - ts->tv_nsec = res % TIMESPEC_HZ; + *ts = (struct timespec) { .tv_sec = res / TIMESPEC_HZ, + .tv_nsec = res % TIMESPEC_HZ }; #endif return base; } diff --git a/lib/utimecmp.c b/lib/utimecmp.c index b1e5e2ba32..639f99d132 100644 --- a/lib/utimecmp.c +++ b/lib/utimecmp.c @@ -319,7 +319,6 @@ utimecmpat (int dfd, char const *dst_name, if (SYSCALL_RESOLUTION < res) { - struct timespec timespec[2]; struct stat dst_status; /* Ignore source timestamp information that must necessarily @@ -344,10 +343,12 @@ utimecmpat (int dfd, char const *dst_name, destination to the existing access time, except with trailing nonzero digits. */ - timespec[0].tv_sec = dst_a_s; - timespec[0].tv_nsec = dst_a_ns; - timespec[1].tv_sec = dst_m_s | (res == 2 * BILLION); - timespec[1].tv_nsec = dst_m_ns + res / 9; + struct timespec timespec[2] = { + [0].tv_sec = dst_a_s, + [0].tv_nsec = dst_a_ns, + [1].tv_sec = dst_m_s | (res == 2 * BILLION), + [1].tv_nsec = dst_m_ns + res / 9 + }; if (utimensat (dfd, dst_name, timespec, AT_SYMLINK_NOFOLLOW)) return -2; diff --git a/lib/utimens.c b/lib/utimens.c index 4c5377eca0..faa197e6cb 100644 --- a/lib/utimens.c +++ b/lib/utimens.c @@ -405,10 +405,10 @@ fdutimens (int fd, char const *file, struct timespec const timespec[2]) struct timeval *t; if (ts) { - timeval[0].tv_sec = ts[0].tv_sec; - timeval[0].tv_usec = ts[0].tv_nsec / 1000; - timeval[1].tv_sec = ts[1].tv_sec; - timeval[1].tv_usec = ts[1].tv_nsec / 1000; + timeval[0] = (struct timeval) { .tv_sec = ts[0].tv_sec, + .tv_usec = ts[0].tv_nsec / 1000 }; + timeval[1] = (struct timeval) { .tv_sec = ts[1].tv_sec, + .tv_usec = ts[1].tv_nsec / 1000 }; t = timeval; } else @@ -502,8 +502,8 @@ fdutimens (int fd, char const *file, struct timespec const timespec[2]) struct utimbuf *ut; if (ts) { - utimbuf.actime = ts[0].tv_sec; - utimbuf.modtime = ts[1].tv_sec; + utimbuf = (struct utimbuf) { .actime = ts[0].tv_sec, + .modtime = ts[1].tv_sec }; ut = &utimbuf; } else @@ -621,10 +621,10 @@ lutimens (char const *file, struct timespec const timespec[2]) int result; if (ts) { - timeval[0].tv_sec = ts[0].tv_sec; - timeval[0].tv_usec = ts[0].tv_nsec / 1000; - timeval[1].tv_sec = ts[1].tv_sec; - timeval[1].tv_usec = ts[1].tv_nsec / 1000; + timeval[0] = (struct timeval) { .tv_sec = ts[0].tv_sec, + .tv_usec = ts[0].tv_nsec / 1000 }; + timeval[1] = (struct timeval) { .tv_sec = ts[1].tv_sec, + .tv_usec = ts[1].tv_nsec / 1000 }; t = timeval; } else -- cgit v1.2.1