1 /* Copyright (C) 2015-2024 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
4 The GNU C Library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
9 The GNU C Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
14 You should have received a copy of the GNU Lesser General Public
15 License along with the GNU C Library; if not, see
16 <https://www.gnu.org/licenses/>. */
18 #include <sys/socket.h>
21 #include <socketcall.h>
22 #include <socket-constants-time64.h>
25 setsockopt_syscall (int fd
, int level
, int optname
, const void *optval
,
28 #ifdef __ASSUME_SETSOCKOPT_SYSCALL
29 return INLINE_SYSCALL_CALL (setsockopt
, fd
, level
, optname
, optval
, len
);
31 return SOCKETCALL (setsockopt
, fd
, level
, optname
, optval
, len
);
35 #ifndef __ASSUME_TIME64_SYSCALLS
37 setsockopt32 (int fd
, int level
, int optname
, const void *optval
,
42 if (level
!= SOL_SOCKET
)
47 case COMPAT_SO_RCVTIMEO_NEW
:
48 case COMPAT_SO_SNDTIMEO_NEW
:
50 if (len
< sizeof (struct __timeval64
))
56 struct __timeval64
*tv64
= (struct __timeval64
*) optval
;
57 if (! in_int32_t_range (tv64
->tv_sec
))
59 __set_errno (EOVERFLOW
);
63 if (optname
== COMPAT_SO_RCVTIMEO_NEW
)
64 optname
= COMPAT_SO_RCVTIMEO_OLD
;
65 if (optname
== COMPAT_SO_SNDTIMEO_NEW
)
66 optname
= COMPAT_SO_SNDTIMEO_OLD
;
68 struct __timeval32 tv32
= valid_timeval64_to_timeval32 (*tv64
);
70 r
= setsockopt_syscall (fd
, level
, optname
, &tv32
, sizeof (tv32
));
74 case COMPAT_SO_TIMESTAMP_NEW
:
75 case COMPAT_SO_TIMESTAMPNS_NEW
:
77 if (optname
== COMPAT_SO_TIMESTAMP_NEW
)
78 optname
= COMPAT_SO_TIMESTAMP_OLD
;
79 if (optname
== COMPAT_SO_TIMESTAMPNS_NEW
)
80 optname
= COMPAT_SO_TIMESTAMPNS_OLD
;
81 /* The expected type for the option is an 'int' for both types of
82 timestamp formats, so there is no need to convert it. */
83 r
= setsockopt_syscall (fd
, level
, optname
, optval
, len
);
93 __setsockopt (int fd
, int level
, int optname
, const void *optval
, socklen_t len
)
95 int r
= setsockopt_syscall (fd
, level
, optname
, optval
, len
);
97 #ifndef __ASSUME_TIME64_SYSCALLS
98 if (r
== -1 && errno
== ENOPROTOOPT
)
99 r
= setsockopt32 (fd
, level
, optname
, optval
, len
);
104 libc_hidden_def (__setsockopt
)
105 weak_alias (__setsockopt
, setsockopt
)
107 weak_alias (__setsockopt
, __setsockopt64
)