]> Savannah Git Hosting - gnulib.git/commitdiff
timespec: fill in other members
authorPaul Eggert <eggert@cs.ucla.edu>
Mon, 15 May 2023 06:27:51 +0000 (23:27 -0700)
committerPaul Eggert <eggert@cs.ucla.edu>
Mon, 15 May 2023 06:30:16 +0000 (23:30 -0700)
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.

20 files changed:
ChangeLog
lib/getsockopt.c
lib/gettime.c
lib/gettimeofday.c
lib/glthread/thread.c
lib/nanosleep.c
lib/parse-datetime.y
lib/poll.c
lib/pselect.c
lib/pthread-cond.c
lib/pthread-rwlock.c
lib/pthread_mutex_timedlock.c
lib/select.c
lib/settime.c
lib/stat-time.h
lib/thrd.c
lib/timespec.h
lib/timespec_getres.c
lib/utimecmp.c
lib/utimens.c

index 34e7d72130916136eae36fed9242fc28331eb8b5..3ed1b1ef8f55059f24349f3b3414fdc5bbdaea0f 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,44 @@
 2023-05-14  Paul Eggert  <eggert@cs.ucla.edu>
 
+       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.
 
index 565c38ef07c51e5b193957e5432048b078fdb037..06302652af9923abd744d85bc860916e72337361 100644 (file)
@@ -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;
index f86cc4efbffce866d76076a4f77e90576dee960d..ec40ff903e1513eff626b91f5ea81eb9a8dd5966 100644 (file)
@@ -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
 }
 
index d896ec132b95e2f060900f3295b7d037af613e9e..69b43a62c86de91eaa5bab9b2161b567f64c5385 100644 (file)
@@ -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;
 
index 1f28be59c8fc41484931e14cfc43879d4f985ab3..3352159edc4d40a65aedcaea7d17256abf8a0cfa 100644 (file)
@@ -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);
             }
           }
index 3f295f49b5dd79ee156e904f2166a7161a593f8c..10974df461ec6fc141db81e68a9784eb4b531029 100644 (file)
@@ -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)
       {
index 45c5e434150923f77bddd9098ed6a5f747289422..a0487a37138cca46ee564e90faace7b219a052a1 100644 (file)
@@ -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;
index a0dc2c5226d71671149782387378b1be8b373c74..941fecf2d30b9cd9fbf53d45a8953a5bc52d635f 100644 (file)
@@ -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 */
index 52d38378783628179f74ff5a6262237531481b3d..1b8c19130c2f0e3dd6b2234ecd4b12dd395a4fe9 100644 (file)
@@ -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
index 8cf542473530a30834f3bd6fc0ea18cef4f684cb..6980cc6ed93ed466d4ce480142ea5925fe49229a 100644 (file)
@@ -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);
     }
 }
index 8713d1abc238b2eb1b09de7450bc3dc036cbd532..5087661b0b7f838613a98988974f6969c48a52c0 100644 (file)
@@ -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);
index feecf6f5193a774e28b5bb69f4b9bd181d40b32f..2394092e83b2c18d673f8487a575ccea59965cdd 100644 (file)
@@ -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);
index 6b6ca4154c1130db6a61ef2485f4c9f9bf7c2c17..991f4754317faefe5a4f1560ced8c26a597e9fed 100644 (file)
@@ -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.  */
index 376d85476a269db115e88bb8fcaa8f5db8919bed..2ce7c03300907a171b29c8ff2fef1f377464db78 100644 (file)
@@ -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
index 5b2702356ee4748992fbf2f3d5427aab9137b3d8..af084102dae8d40b71f1f1283d3caa1297b1d500 100644 (file)
@@ -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;
index bb0e10fc8bf68163405d88eabbabdfba334e4cb4..1a13a51e00b55880d6b05afaa277cbb0209cbbd8 100644 (file)
@@ -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);
             }
           }
index 0bdfd76ef78e725b15157f20e574bb60f7fcb655..e94da75defe6ffd384554ccab032143992e9d61e 100644 (file)
@@ -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.  */
index 38193d2a1b9469f49f1b2ad3d8fcf704e8edee1a..0efaf14712b1fa12b880534c73eb88971aa1ea3a 100644 (file)
@@ -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;
     }
index b1e5e2ba3257aa0505de8a9b7b70166379f58207..639f99d132dc9aff0c70fe22dfca4a00b3f7cd3b 100644 (file)
@@ -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;
index 4c5377eca0f2098e8320105d7f7c41bee0f970de..faa197e6cb5f60ee7d430773e8eff70f0aaab3f8 100644 (file)
@@ -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