Skip to content

Commit 442c0de

Browse files
committed
Make sigval an union
1 parent 5c8a32d commit 442c0de

File tree

3 files changed

+55
-82
lines changed

3 files changed

+55
-82
lines changed

libc-test/build.rs

Lines changed: 1 addition & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -292,9 +292,6 @@ fn test_apple(target: &str) {
292292
return true;
293293
}
294294
match ty {
295-
// FIXME: actually a union
296-
"sigval" => true,
297-
298295
// FIXME: The size is changed in recent macOSes.
299296
"malloc_zone_t" => true,
300297
// it is a moving target, changing through versions
@@ -388,14 +385,6 @@ fn test_apple(target: &str) {
388385
}
389386
});
390387

391-
cfg.skip_field_type(move |struct_, field| {
392-
match (struct_, field) {
393-
// FIXME: actually a union
394-
("sigevent", "sigev_value") => true,
395-
_ => false,
396-
}
397-
});
398-
399388
cfg.volatile_item(|i| {
400389
use ctest::VolatileItemKind::*;
401390
match i {
@@ -534,18 +523,6 @@ fn test_openbsd(target: &str) {
534523
"sys/param.h",
535524
}
536525

537-
cfg.skip_struct(move |ty| {
538-
if ty.starts_with("__c_anonymous_") {
539-
return true;
540-
}
541-
match ty {
542-
// FIXME: actually a union
543-
"sigval" => true,
544-
545-
_ => false,
546-
}
547-
});
548-
549526
cfg.skip_fn(move |name| {
550527
match name {
551528
// futex() has volatile arguments, but that doesn't exist in Rust.
@@ -926,8 +903,6 @@ fn test_solarish(target: &str) {
926903
return true;
927904
}
928905
match ty {
929-
// union, not a struct
930-
"sigval" => true,
931906
// a bunch of solaris-only fields
932907
"utmpx" if is_illumos => true,
933908
_ => false,
@@ -942,8 +917,6 @@ fn test_solarish(target: &str) {
942917
"sigaction" if field == "sa_sigaction" => true,
943918
// Missing in illumos
944919
"sigevent" if field == "ss_sp" => true,
945-
// Avoid sigval union issues
946-
"sigevent" if field == "sigev_value" => true,
947920
// const issues
948921
"sigevent" if field == "sigev_notify_attributes" => true,
949922

@@ -1159,8 +1132,6 @@ fn test_netbsd(target: &str) {
11591132

11601133
cfg.skip_struct(move |ty| {
11611134
match ty {
1162-
// This is actually a union, not a struct
1163-
"sigval" => true,
11641135
// These are tested as part of the linux_fcntl tests since there are
11651136
// header conflicts when including them with all the other structs.
11661137
"termios2" => true,
@@ -1211,8 +1182,6 @@ fn test_netbsd(target: &str) {
12111182
(struct_ == "ifaddrs" && field == "ifa_ifu") ||
12121183
// sighandler_t type is super weird
12131184
(struct_ == "sigaction" && field == "sa_sigaction") ||
1214-
// sigval is actually a union, but we pretend it's a struct
1215-
(struct_ == "sigevent" && field == "sigev_value") ||
12161185
// aio_buf is "volatile void*" and Rust doesn't understand volatile
12171186
(struct_ == "aiocb" && field == "aio_buf")
12181187
});
@@ -1340,9 +1309,6 @@ fn test_dragonflybsd(target: &str) {
13401309

13411310
t if t.ends_with("_t") => t.to_string(),
13421311

1343-
// sigval is a struct in Rust, but a union in C:
1344-
"sigval" => format!("union sigval"),
1345-
13461312
// put `struct` in front of all structs:.
13471313
t if is_struct => format!("struct {}", t),
13481314

@@ -1436,8 +1402,6 @@ fn test_dragonflybsd(target: &str) {
14361402
(struct_ == "ifaddrs" && field == "ifa_ifu") ||
14371403
// sighandler_t type is super weird
14381404
(struct_ == "sigaction" && field == "sa_sigaction") ||
1439-
// sigval is actually a union, but we pretend it's a struct
1440-
(struct_ == "sigevent" && field == "sigev_value") ||
14411405
// aio_buf is "volatile void*" and Rust doesn't understand volatile
14421406
(struct_ == "aiocb" && field == "aio_buf")
14431407
});
@@ -1708,9 +1672,6 @@ fn test_android(target: &str) {
17081672

17091673
t if t.ends_with("_t") => t.to_string(),
17101674

1711-
// sigval is a struct in Rust, but a union in C:
1712-
"sigval" => format!("union sigval"),
1713-
17141675
// put `struct` in front of all structs:.
17151676
t if is_struct => format!("struct {}", t),
17161677

@@ -1991,8 +1952,6 @@ fn test_android(target: &str) {
19911952
cfg.skip_field_type(move |struct_, field| {
19921953
// This is a weird union, don't check the type.
19931954
(struct_ == "ifaddrs" && field == "ifa_ifu") ||
1994-
// sigval is actually a union, but we pretend it's a struct
1995-
(struct_ == "sigevent" && field == "sigev_value") ||
19961955
// this one is an anonymous union
19971956
(struct_ == "ff_effect" && field == "u") ||
19981957
// FIXME: `sa_sigaction` has type `sighandler_t` but that type is
@@ -2197,9 +2156,6 @@ fn test_freebsd(target: &str) {
21972156

21982157
t if t.ends_with("_t") => t.to_string(),
21992158

2200-
// sigval is a struct in Rust, but a union in C:
2201-
"sigval" => format!("union sigval"),
2202-
22032159
// put `struct` in front of all structs:.
22042160
t if is_struct => format!("struct {}", t),
22052161

@@ -2823,10 +2779,6 @@ fn test_emscripten(target: &str) {
28232779

28242780
cfg.skip_struct(move |ty| {
28252781
match ty {
2826-
// This is actually a union, not a struct
2827-
// FIXME: is this necessary?
2828-
"sigval" => true,
2829-
28302782
// FIXME: It was removed in
28312783
// emscripten-core/emscripten@953e414
28322784
"pthread_mutexattr_t" => true,
@@ -2905,9 +2857,6 @@ fn test_emscripten(target: &str) {
29052857
// sighandler_t type is super weird
29062858
// FIXME: is this necessary?
29072859
(struct_ == "sigaction" && field == "sa_sigaction") ||
2908-
// sigval is actually a union, but we pretend it's a struct
2909-
// FIXME: is this necessary?
2910-
(struct_ == "sigevent" && field == "sigev_value") ||
29112860
// aio_buf is "volatile void*" and Rust doesn't understand volatile
29122861
// FIXME: is this necessary?
29132862
(struct_ == "aiocb" && field == "aio_buf")
@@ -3117,9 +3066,6 @@ fn test_neutrino(target: &str) {
31173066
match ty {
31183067
"Elf64_Phdr" | "Elf32_Phdr" => true,
31193068

3120-
// FIXME: This is actually a union, not a struct
3121-
"sigval" => true,
3122-
31233069
// union
31243070
"_channel_connect_attr" => true,
31253071

@@ -3171,8 +3117,6 @@ fn test_neutrino(target: &str) {
31713117
});
31723118

31733119
cfg.skip_field_type(move |struct_, field| {
3174-
// sigval is actually a union, but we pretend it's a struct
3175-
struct_ == "sigevent" && field == "sigev_value" ||
31763120
// Anonymous structures
31773121
struct_ == "_idle_hook" && field == "time"
31783122
});
@@ -3181,8 +3125,6 @@ fn test_neutrino(target: &str) {
31813125
(struct_ == "__sched_param" && field == "reserved") ||
31823126
(struct_ == "sched_param" && field == "reserved") ||
31833127
(struct_ == "sigevent" && field == "__padding1") || // ensure alignment
3184-
(struct_ == "sigevent" && field == "__padding2") || // union
3185-
(struct_ == "sigevent" && field == "__sigev_un2") || // union
31863128
// sighandler_t type is super weird
31873129
(struct_ == "sigaction" && field == "sa_sigaction") ||
31883130
// does not exist
@@ -3291,10 +3233,8 @@ fn test_vxworks(target: &str) {
32913233

32923234
// FIXME
32933235
cfg.skip_fn(move |name| match name {
3294-
// sigval
3295-
"sigqueue" | "_sigqueue"
32963236
// sighandler_t
3297-
| "signal"
3237+
"signal"
32983238
// not used in static linking by default
32993239
| "dlerror" => true,
33003240
_ => false,
@@ -3693,9 +3633,6 @@ fn test_linux(target: &str) {
36933633
// which is absent in glibc, has to be defined.
36943634
"__timeval" => true,
36953635

3696-
// FIXME: This is actually a union, not a struct
3697-
"sigval" => true,
3698-
36993636
// This type is tested in the `linux_termios.rs` file since there
37003637
// are header conflicts when including them with all the other
37013638
// structs.
@@ -4354,8 +4291,6 @@ fn test_linux(target: &str) {
43544291
(struct_ == "sigaction" && field == "sa_sigaction") ||
43554292
// __timeval type is a patch which doesn't exist in glibc
43564293
(struct_ == "utmpx" && field == "ut_tv") ||
4357-
// sigval is actually a union, but we pretend it's a struct
4358-
(struct_ == "sigevent" && field == "sigev_value") ||
43594294
// this one is an anonymous union
43604295
(struct_ == "ff_effect" && field == "u") ||
43614296
// `__exit_status` type is a patch which is absent in musl
@@ -4788,8 +4723,6 @@ fn test_haiku(target: &str) {
47884723
return true;
47894724
}
47904725
match ty {
4791-
// FIXME: actually a union
4792-
"sigval" => true,
47934726
// FIXME: locale_t does not exist on Haiku
47944727
"locale_t" => true,
47954728
// FIXME: rusage has a different layout on Haiku
@@ -4896,10 +4829,8 @@ fn test_haiku(target: &str) {
48964829
("stat", "st_crtime_nsec") => true,
48974830

48984831
// these are actually unions, but we cannot represent it well
4899-
("siginfo_t", "sigval") => true,
49004832
("sem_t", "named_sem_id") => true,
49014833
("sigaction", "sa_sigaction") => true,
4902-
("sigevent", "sigev_value") => true,
49034834
("fpu_state", "_fpreg") => true,
49044835
("cpu_topology_node_info", "data") => true,
49054836
// these fields have a simplified data definition in libc
@@ -4950,8 +4881,6 @@ fn test_haiku(target: &str) {
49504881
ty.to_string()
49514882
}
49524883

4953-
// is actually a union
4954-
"sigval" => format!("union sigval"),
49554884
t if is_union => format!("union {}", t),
49564885
t if t.ends_with("_t") => t.to_string(),
49574886
t if is_struct => format!("struct {}", t),

src/fuchsia/mod.rs

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -251,11 +251,6 @@ s! {
251251
pub l_linger: ::c_int,
252252
}
253253

254-
pub struct sigval {
255-
// Actually a union of an int and a void*
256-
pub sival_ptr: *mut ::c_void
257-
}
258-
259254
// <sys/time.h>
260255
pub struct itimerval {
261256
pub it_interval: ::timeval,
@@ -979,6 +974,11 @@ s_no_extra_traits! {
979974
pub sigev_notify_attributes: *mut pthread_attr_t,
980975
pub __pad: [::c_char; 56 - 3 * 8 /* 8 == sizeof(long) */],
981976
}
977+
978+
pub union sigval {
979+
pub sival_int: ::int,
980+
pub sival_ptr: *mut ::c_void,
981+
}
982982
}
983983

984984
cfg_if! {
@@ -1306,6 +1306,25 @@ cfg_if! {
13061306
self.sigev_notify_attributes.hash(state);
13071307
}
13081308
}
1309+
1310+
impl PartialEq for sigval {
1311+
fn eq(&self, other: &sigval) -> bool {
1312+
unsafe { self.sival_ptr as usize == other.sival_ptr as usize }
1313+
}
1314+
}
1315+
impl Eq for sigval {}
1316+
impl ::fmt::Debug for sigval {
1317+
fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
1318+
f.debug_struct("sigval")
1319+
.field("sival_ptr", unsafe { &(self.sival_ptr as usize) })
1320+
.finish()
1321+
}
1322+
}
1323+
impl ::hash::Hash for sigval {
1324+
fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
1325+
unsafe { (self.sival_ptr as usize).hash(state) };
1326+
}
1327+
}
13091328
}
13101329
}
13111330

src/unix/mod.rs

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -169,11 +169,6 @@ s! {
169169
pub l_linger: ::c_int,
170170
}
171171

172-
pub struct sigval {
173-
// Actually a union of an int and a void*
174-
pub sival_ptr: *mut ::c_void
175-
}
176-
177172
// <sys/time.h>
178173
pub struct itimerval {
179174
pub it_interval: ::timeval,
@@ -202,6 +197,36 @@ s! {
202197
}
203198
}
204199

200+
s_no_extra_traits! {
201+
pub union sigval {
202+
pub sival_int: ::c_int,
203+
pub sival_ptr: *mut ::c_void,
204+
}
205+
}
206+
207+
cfg_if! {
208+
if #[cfg(feature = "extra_traits")] {
209+
impl PartialEq for sigval {
210+
fn eq(&self, other: &sigval) -> bool {
211+
unsafe { self.sival_ptr as usize == other.sival_ptr as usize }
212+
}
213+
}
214+
impl Eq for sigval {}
215+
impl ::fmt::Debug for sigval {
216+
fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
217+
f.debug_struct("sigval")
218+
.field("sival_ptr", unsafe { &(self.sival_ptr as usize) })
219+
.finish()
220+
}
221+
}
222+
impl ::hash::Hash for sigval {
223+
fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
224+
unsafe { (self.sival_ptr as usize).hash(state) };
225+
}
226+
}
227+
}
228+
}
229+
205230
pub const INT_MIN: c_int = -2147483648;
206231
pub const INT_MAX: c_int = 2147483647;
207232

0 commit comments

Comments
 (0)