File: time64.patch

package info (click to toggle)
rust-evdev-rs 0.6.3-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 388 kB
  • sloc: python: 229; makefile: 4; sh: 3
file content (127 lines) | stat: -rw-r--r-- 5,171 bytes parent folder | download
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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
--- a/src/device.rs
+++ b/src/device.rs
@@ -867,25 +867,27 @@
     /// This triggers an internal sync of the device and `next_event` returns
     /// `ReadStatus::Sync`.
     pub fn next_event(&self, flags: ReadFlag) -> io::Result<(ReadStatus, InputEvent)> {
-        let mut ev = raw::input_event {
-            time: raw::timeval {
-                tv_sec: 0,
-                tv_usec: 0,
-            },
-            type_: 0,
-            code: 0,
-            value: 0,
-        };
+        let mut ev = unsafe { std::mem::zeroed()};
 
         let result = unsafe {
             raw::libevdev_next_event(self.raw, flags.bits() as c_uint, &mut ev)
         };
+        #[cfg(all(target_pointer_width = "32", not(target_arch = "x86")))]
+        // unfortunately, the current time64 patches for rust-libc provide
+        // no way to access the timestamp fields on time64 architectures
+        // so we have to do this the ugly way with pointer arithmetic.
+        let time = TimeVal {
+            tv_sec: unsafe { *(&ev as *const libc::input_event as *const u32) } as _,
+            tv_usec: unsafe { *(&ev as *const libc::input_event as *const u32).offset(1) } as _,
+        };
+        #[cfg(not(all(target_pointer_width = "32", not(target_arch = "x86"))))]
+        let time = TimeVal {
+            tv_sec: ev.time.tv_sec,
+            tv_usec: ev.time.tv_usec,
+        };
 
         let event = InputEvent {
-            time: TimeVal {
-                tv_sec: ev.time.tv_sec,
-                tv_usec: ev.time.tv_usec,
-            },
+            time: time,
             event_code: int_to_event_code(ev.type_ as u32, ev.code as u32),
             value: ev.value,
         };
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -207,7 +207,7 @@
     pub const fn new(tv_sec: time_t, tv_usec: suseconds_t) -> TimeVal {
         const MICROS_PER_SEC: suseconds_t = 1_000_000;
         TimeVal {
-            tv_sec: tv_sec + tv_usec / MICROS_PER_SEC,
+            tv_sec: tv_sec + ((tv_usec / MICROS_PER_SEC) as time_t),
             tv_usec: tv_usec % MICROS_PER_SEC,
         }
     }
@@ -215,14 +215,20 @@
     pub const fn from_raw(timeval: &libc::timeval) -> TimeVal {
         TimeVal {
             tv_sec: timeval.tv_sec,
-            tv_usec: timeval.tv_usec,
+            // glibc with time64 currently has a defintion of
+            // sueconds_t which is inconsistent with it's definition
+            // of timeval.
+            tv_usec: timeval.tv_usec as _,
         }
     }
 
     pub const fn as_raw(&self) -> libc::timeval {
         libc::timeval {
             tv_sec: self.tv_sec,
-            tv_usec: self.tv_usec,
+            // glibc with time64 currently has a defintion of
+            // sueconds_t which is inconsistent with it's definition
+            // of timeval.
+            tv_usec: self.tv_usec as _,
         }
     }
 }
@@ -253,8 +259,18 @@
     pub fn from_raw(event: &libc::input_event) -> InputEvent {
         let ev_type = event.type_ as u32;
         let event_code = int_to_event_code(ev_type, event.code as u32);
+        #[cfg(all(target_pointer_width = "32", not(target_arch = "x86")))]
+        // unfortunately, the current time64 patches for rust-libc provide
+        // no way to access the timestamp fields on time64 architectures
+        // so we have to do this the ugly way with pointer arithmetic.
+        let time = TimeVal {
+            tv_sec: unsafe { *(event as *const libc::input_event as *const u32) } as _,
+            tv_usec: unsafe { *(event as *const libc::input_event as *const u32).offset(1) } as _,
+        };
+        #[cfg(not(all(target_pointer_width = "32", not(target_arch = "x86"))))]
+        let time = TimeVal::from_raw(&event.time);
         InputEvent {
-            time: TimeVal::from_raw(&event.time),
+            time: time,
             event_code,
             value: event.value,
         }
@@ -262,12 +278,23 @@
 
     pub fn as_raw(&self) -> libc::input_event {
         let (ev_type, ev_code) = event_code_to_int(&self.event_code);
-        libc::input_event {
-            time: self.time.as_raw(),
-            type_: ev_type as u16,
-            code: ev_code as u16,
-            value: self.value,
-        }
+        let mut result : libc::input_event = unsafe {std::mem::zeroed()};
+        #[cfg(all(target_pointer_width = "32", not(target_arch = "x86")))]
+        // unfortunately, the current time64 patches for rust-libc provide
+        // no way to access the timestamp fields on time64 architectures
+        // so we have to do this the ugly way with pointer arithmetic.
+        unsafe {
+            *(&mut result as *mut libc::input_event as *mut u32) = self.time.tv_sec as u32;
+            *(&mut result as *mut libc::input_event as *mut u32).offset(1) = self.time.tv_usec as u32;
+        }
+        #[cfg(not(all(target_pointer_width = "32", not(target_arch = "x86"))))]
+        {
+            result.time = self.time.as_raw();
+        }
+        result.type_ = ev_type as u16;
+        result.code = ev_code as u16;
+        result.value = self.value;
+        result
     }
 
     pub fn is_type(&self, ev_type: &EventType) -> bool {