Hash :
88811b7d
Author :
Date :
2023-05-14T23:27:51
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.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
/* getsockopt.c --- wrappers for Windows getsockopt function
Copyright (C) 2008-2023 Free Software Foundation, Inc.
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation; either version 2.1 of the
License, or (at your option) any later version.
This file is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>. */
/* Written by Paolo Bonzini */
#include <config.h>
#define WIN32_LEAN_AND_MEAN
/* Get winsock2.h. */
#include <sys/socket.h>
/* Get struct timeval. */
#include <sys/time.h>
/* Get memcpy. */
#include <string.h>
/* Get set_winsock_errno, FD_TO_SOCKET etc. */
#include "w32sock.h"
#undef getsockopt
int
rpl_getsockopt (int fd, int level, int optname, void *optval, socklen_t *optlen)
{
SOCKET sock = FD_TO_SOCKET (fd);
if (sock == INVALID_SOCKET)
{
errno = EBADF;
return -1;
}
else
{
int r;
if (level == SOL_SOCKET
&& (optname == SO_RCVTIMEO || optname == SO_SNDTIMEO))
{
int milliseconds;
int milliseconds_len = sizeof (int);
size_t n;
r = getsockopt (sock, level, optname, (char *) &milliseconds,
&milliseconds_len);
struct timeval tv = {
.tv_sec = milliseconds / 1000,
.tv_usec = (milliseconds % 1000) * 1000
};
n = sizeof (struct timeval);
if (n > *optlen)
n = *optlen;
memcpy (optval, &tv, n);
*optlen = n;
}
else
{
r = getsockopt (sock, level, optname, optval, optlen);
}
if (r < 0)
set_winsock_errno ();
return r;
}
}