Description
On Solaris, struct addrinfo
is defined like this:
struct addrinfo {
int ai_flags; /* AI_PASSIVE, AI_CANONNAME, ... */
int ai_family; /* PF_xxx */
int ai_socktype; /* SOCK_xxx */
int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */
#ifdef __sparcv9
int _ai_pad; /* for backwards compat with old size_t */
#endif /* __sparcv9 */
socklen_t ai_addrlen;
char *ai_canonname; /* canonical name for hostname */
struct sockaddr *ai_addr; /* binary address */
struct addrinfo *ai_next; /* next structure in linked list */
};
That padding member needs to be represented in Rust's copy. This is pretty straightforward, if a bit ugly. The following patch against the 1.19.0 sources fixes all the networking related test failures on SPARC:
--- rustc-1.19.0-src/src/liblibc/src/unix/solaris/mod.rs
+++ rustc-1.19.0-src/src/liblibc/src/unix/solaris/mod.rs
@@ -204,6 +204,8 @@
pub ai_family: ::c_int,
pub ai_socktype: ::c_int,
pub ai_protocol: ::c_int,
+ #[cfg(target_arch = "sparc64")]
+ pub __sparcv9_pad: ::c_int,
pub ai_addrlen: ::socklen_t,
pub ai_canonname: *mut ::c_char,
pub ai_addr: *mut ::sockaddr,
--- rustc-1.19.0-src/src/libstd/sys_common/net.rs
+++ rustc-1.19.0-src/src/libstd/sys_common/net.rs
@@ -165,8 +165,21 @@
init();
let c_host = CString::new(host)?;
+ #[cfg(all(target_os = "solaris", target_arch = "sparc64"))]
let hints = c::addrinfo {
ai_flags: 0,
+ ai_family: 0,
+ ai_socktype: c::SOCK_STREAM,
+ ai_protocol: 0,
+ __sparcv9_pad: 0,
+ ai_addrlen: 0,
+ ai_addr: ptr::null_mut(),
+ ai_canonname: ptr::null_mut(),
+ ai_next: ptr::null_mut()
+ };
+ #[cfg(not(all(target_os = "solaris", target_arch = "sparc64")))]
+ let hints = c::addrinfo {
+ ai_flags: 0,
ai_family: 0,
ai_socktype: c::SOCK_STREAM,
ai_protocol: 0,
Because this is against 1.19.0, so the #[cfg]
directive isn't yet allowed inside the initializer, though presumably that could be used on master
, or beta with struct_field_attributes
.
But I'm struggling to find an idiomatic way to do this in such a way that it needn't be mentioned in net.rs
at all, and just defaulted to 0
in solaris/mod.rs
, as well as a way to make it non-pub
. I haven't yet tried it, but I assume I could use the Default
trait. But that would still require me to add ..Default::default()
to the initializer, and I would need to make the change to all the struct addrinfo
definitions in libc.
Is there a better way to fix this?