History

net: socket: implement 64-bit timestamps

The 'timeval' and 'timespec' data structures used for socket timestamps are going to be redefined in user space based on 64-bit time_t in future versions of the C library to deal with the y2038 overflow problem, which breaks the ABI definition. Unlike many modern ioctl commands, SIOCGSTAMP and SIOCGSTAMPNS do not use the _IOR() macro to encode the size of the transferred data, so it remains ambiguous whether the application uses the old or new layout. The best workaround I could find is rather ugly: we redefine the command code based on the size of the respective data structure with a ternary operator. This lets it get evaluated as late as possible, hopefully after that structure is visible to the caller. We cannot use an #ifdef here, because inux/sockios.h might have been included before any libc header that could determine the size of time_t. The ioctl implementation now interprets the new command codes as always referring to the 64-bit structure on all architectures, while the old architecture specific command code still refers to the old architecture specific layout. The new command number is only used when they are actually different.

Arnd Bergmann committed 7 years ago

Commit 0768e171 parent 5ce5d8a7 files · +50 −16Browse files

Showing the changes to include/uapi/linux (1 of 7 files). Show all

Unified · Split

include/uapi/linux/sockios.h+21−0
@@ -19,6 +19,7 @@ · 18 unmodified lines
19#ifndef _LINUX_SOCKIOS_H19#ifndef _LINUX_SOCKIOS_H
20#define _LINUX_SOCKIOS_H20#define _LINUX_SOCKIOS_H
21 21
22#include <asm/bitsperlong.h>
22#include <asm/sockios.h>23#include <asm/sockios.h>
23 24
24/* Linux-specific socket ioctls */25/* Linux-specific socket ioctls */
@@ -27,6 +28,26 @@ · 2 unmodified lines
27 28
28#define SOCK_IOC_TYPE 0x8929#define SOCK_IOC_TYPE 0x89
29 30
31/*
32 * the timeval/timespec data structure layout is defined by libc,
33 * so we need to cover both possible versions on 32-bit.
34 */
35/* Get stamp (timeval) */
36#define SIOCGSTAMP_NEW _IOR(SOCK_IOC_TYPE, 0x06, long long[2])
37/* Get stamp (timespec) */
38#define SIOCGSTAMPNS_NEW _IOR(SOCK_IOC_TYPE, 0x07, long long[2])
39
40#if __BITS_PER_LONG == 64 || (defined(__x86_64__) && defined(__ILP32__))
41/* on 64-bit and x32, avoid the ?: operator */
42#define SIOCGSTAMP SIOCGSTAMP_OLD
43#define SIOCGSTAMPNS SIOCGSTAMPNS_OLD
44#else
45#define SIOCGSTAMP ((sizeof(struct timeval)) == 8 ? \
46 SIOCGSTAMP_OLD : SIOCGSTAMP_NEW)
47#define SIOCGSTAMPNS ((sizeof(struct timespec)) == 8 ? \
48 SIOCGSTAMPNS_OLD : SIOCGSTAMPNS_NEW)
49#endif
50
30/* Routing table calls. */51/* Routing table calls. */
31#define SIOCADDRT 0x890B /* add routing table entry */52#define SIOCADDRT 0x890B /* add routing table entry */
32#define SIOCDELRT 0x890C /* delete routing table entry */53#define SIOCDELRT 0x890C /* delete routing table entry */

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t