Skip to content

struct addrinfo needs padding on Solaris/SPARC #43649

Closed
@dhduvall

Description

@dhduvall

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?

Metadata

Metadata

Assignees

No one assigned

    Labels

    O-SPARCTarget: SPARC processorsT-libs-apiRelevant to the library API team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions