Join GitHub today
GitHub is home to over 50 million developers working together to host and review code, manage projects, and build software together.
Sign upSupport Freebsd #102
Support Freebsd #102
Conversation
|
Some brief comments on things changed. |
| @@ -26,18 +26,64 @@ use std::thread; | |||
|
|
|||
| const MAX_FDS_IN_CMSG: u32 = 64; | |||
|
|
|||
| const SCM_RIGHTS: c_int = 0x01; | |||
This comment has been minimized.
This comment has been minimized.
| fn CMSG_ALIGN(length: size_t) -> size_t { | ||
| (length + mem::size_of::<size_t>() - 1) & !(mem::size_of::<size_t>() - 1) | ||
| #[cfg(target_os = "freebsd")] | ||
| unsafe fn CMSG_DATA(cmsg: *mut cmsghdr) -> *mut c_void { |
This comment has been minimized.
This comment has been minimized.
dlrobertson
Sep 18, 2016
•
Author
Collaborator
Ensure proper alignment. cmsg.offset(1) on my box is the equivalent of addq 0xc, %rcx, but it should be addq 0x10, %rcx.
| (*cmsg_buffer).cmsg_level = libc::SOL_SOCKET; | ||
| (*cmsg_buffer).cmsg_type = SCM_RIGHTS; | ||
|
|
||
| ptr::copy_nonoverlapping(fds.as_ptr(), | ||
| cmsg_buffer.offset(1) as *mut c_int, | ||
| CMSG_DATA(cmsg_buffer) as *mut c_int, |
This comment has been minimized.
This comment has been minimized.
|
@danlrobertson I'm not sure if/when I get to look at the changes in detail; so some quick comments for now:
|
|
@antrik thanks for the quick reply. Don't feel rushed.
|
l0kod
commented
Sep 19, 2016
|
About the CMSG_DATA, you may be interested in https://github.com/stemjail/fdpass-rs |
65c0e76
to
6e68729
|
@antrik: Updated to include 2 commits. fbafaf1 move static and const declarations and 6e68729 support freebsd @l0kod: per stemjail/fdpass-rs#1, it doesn't seem to be currently working on FreeBSD. Let me know if missed something. A transition to a library like fdpass-rs I think is a great idea (and the path forward), but imo that is currently outside the scope of this PR. That being said, I'm happy to look into it further if the consensus is to do so. |
|
@l0kod I briefly considered |
|
Personally, I'd prefer even finer-grained commits, with changes such as "rename |
| @@ -26,18 +26,64 @@ use std::thread; | |||
|
|
|||
| const MAX_FDS_IN_CMSG: u32 = 64; | |||
|
|
|||
| const SCM_RIGHTS: c_int = 0x01; | |||
This comment has been minimized.
This comment has been minimized.
antrik
Sep 26, 2016
•
Contributor
To be honest, I'm not convinced moving these defines to the top really is an improvement... Personally I prefer definitions to be close to usage, rather than strictly following formal rules such as "all const should go to the top". But I'm aware that I might be in a minority here :-(
(Also, this is a bit off-topic I guess, but I'm still wondering why this one is not defined in libc?...)
This comment has been minimized.
This comment has been minimized.
dlrobertson
Sep 26, 2016
Author
Collaborator
It apears as if everything from cmsg is not defined in libc. It definitely seems like they should be defined somewhere like libc or nix.
This comment has been minimized.
This comment has been minimized.
antrik
Sep 26, 2016
Contributor
libc I'd say. libc is for the raw FFI interfaces; while nix is for safe wrappers around them. Using nix to abstract all these dirty details would be nice to have, but it's a second (much bigger) step...
| // The value Linux returns for SO_SNDBUF | ||
| // is not the size we are actually allowed to use... | ||
| // Empirically, we have to deduct 32 bytes from that. | ||
| const RESERVED_SIZE: usize = 32; |
This comment has been minimized.
This comment has been minimized.
antrik
Sep 26, 2016
•
Contributor
Have you checked that this is actually needed on FreeBSD as well? It's the kind of thing I would have expected to be extremely system-specific...
This comment has been minimized.
This comment has been minimized.
| #[cfg(target_os="linux")] | ||
| type IovLen = usize; | ||
| #[cfg(target_os="linux")] | ||
| type SockLen = usize; |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
dlrobertson
Sep 26, 2016
Author
Collaborator
That's what I was hoping. However, socklen_t:linux = u32 but msghdr.msg_controllen = size_t = usize. This works on FreeBSD though, and was what I originally did. Perhaps this is another change that should be made to libc
This comment has been minimized.
This comment has been minimized.
antrik
Sep 29, 2016
Contributor
Ah, so for some reason the POSIX committee decided to abuse socklen_t for something that is clearly not in any way related to socket address lengths; while glibc decided to stick with the more appropriate size_t... This is so retarded :-(
Calling the type SockLen is very confusing though, as it has no bearing on the primary use of socklen_t -- better call it MsgControllen, or something along these lines. Also, it's probably better to define it as size_t rather than usize, to match the libc definition.
| #[cfg(target_os="linux")] | ||
| type SockLen = usize; | ||
| #[cfg(target_os="linux")] | ||
| #[inline] |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
| let mut sockaddr = sockaddr_un { | ||
| sun_family: libc::AF_UNIX as u16, | ||
| sun_path: [ 0; 108 ], | ||
| }; |
This comment has been minimized.
This comment has been minimized.
antrik
Sep 26, 2016
Contributor
I suspect we could make this code generic, by using mem::zeroed() and then setting only the fields we need, just as we would in C? (Along with using sa_family_t to make the cast generic -- though I wonder why AF_UNIX isn't defined as sa_family_t in libc in the first place...)
This comment has been minimized.
This comment has been minimized.
| libc::strncpy(sockaddr.sun_path.as_mut_ptr(), | ||
| path, | ||
| sockaddr.sun_path.len() - 1); | ||
| let len = mem::size_of::<sockaddr_un>() - 104 + (libc::strlen(sockaddr.sun_path.as_ptr()) as usize); |
This comment has been minimized.
This comment has been minimized.
antrik
Sep 26, 2016
•
Contributor
This doesn't look right -- copy&paste error perhaps?...
I think we could make that code (and thus the entire function) generic as well. It will be uglier than in C due to the lack of offsetof; but it should be doable with &sockaddr.sun_path as *const as usize - &sockaddr as *const as usize or something along these lines?...
BTW, the example in the Linux man page for using AF_UNIX sockets just passes sizeof sockaddr_un as the len parameter to connect(), rather than calculating the actual size in use... The POSIX man page for connect() is a bit unclear what is expected here: it says "the length of the sockaddr structure pointed to by the address argument". I'd tend to assume passing the entire size is probably correct... Which will make the code simpler.
(I suggest changing this in a separate commit before the main change.)
This comment has been minimized.
This comment has been minimized.
dlrobertson
Sep 26, 2016
Author
Collaborator
Yes, this is an error. linux would be - 108, while freebsd would be - 104
| @@ -953,21 +976,32 @@ fn is_socket(fd: c_int) -> bool { | |||
|
|
|||
| // FFI stuff follows: | |||
|
|
|||
| const SCM_RIGHTS: c_int = 0x01; | |||
| #[allow(non_snake_case)] | |||
| fn CMSG_LEN(length: SockLen) -> SockLen { | |||
This comment has been minimized.
This comment has been minimized.
antrik
Sep 26, 2016
Contributor
I don't think it's right for these functions to work on SockLen: I'd say they should stick with size_t; while the cast to socklen_t would only be done by the caller while filling the actual socket structures. This feels more natural to me, and avoids a lot of unnecessary confusing casts.
This comment has been minimized.
This comment has been minimized.
| CMSG_ALIGN(mem::size_of::<cmsghdr>()) + length | ||
| #[cfg(target_os = "linux")] | ||
| unsafe fn CMSG_DATA(cmsg: *mut cmsghdr) -> *mut c_void { | ||
| cmsg.offset(1) as *mut c_void |
This comment has been minimized.
This comment has been minimized.
antrik
Sep 26, 2016
Contributor
While this matches the glibc definition of CMSG_DATA, I think it wouldn't hurt to just use FreeBSD definition everywhere? AIUI, Linux only gets away with the simplistic definition, because sizeof cmsghdr happens to always have the right alignment there. This is inconsistent with the other CMSG_ definitions though, which are defined in a more generic way, always explicitly doing the alignment...
This comment has been minimized.
This comment has been minimized.
dlrobertson
Sep 26, 2016
Author
Collaborator
Didn't think about that. That would make this a bit more simplistic. I'd definitely be okay with making this change
| @@ -0,0 +1,1029 @@ | |||
| // Copyright 2015 The Servo Project Developers. See the COPYRIGHT | |||
This comment has been minimized.
This comment has been minimized.
antrik
Sep 26, 2016
Contributor
Something went wrong with your commit: it introduces both src/platform/unix/mod.rs and src/platform/unix/linux/mod.rs (with identical contents) in place of the original src/platform/linux/mod.rs...
This comment has been minimized.
This comment has been minimized.
|
Thanks for the very thorough review. I'll make the changes and comment when I make the update. I'll also start looking into a better home for |
Move the static and const declarations to the top of the file
6e68729
to
7e2c42e
Updated, and I must admit you were right... It makes a lot more sense this way.
Updated.
Updated.
Updated. |
7e2c42e
to
95dccff
| #[cfg(all(not(feature = "force-inprocess"), target_os = "linux"))] | ||
| include!("linux/mod.rs"); | ||
| #[cfg(all(not(feature = "force-inprocess"), any(target_os = "linux", | ||
| target_os = "freebsd")))] |
This comment has been minimized.
This comment has been minimized.
antrik
Oct 5, 2016
•
Contributor
Personally, I'd add the freebsd case only right before or along with actually adding FreeBSD-specific code, after the generic portability improvements... But this way is fine too I guess :-)
This comment has been minimized.
This comment has been minimized.
dlrobertson
Oct 11, 2016
Author
Collaborator
Not sure what you mean by this. Do you mean use something like a all(unix,not(macos)) instead of specifying linux and freebsd for using the unix module?
This comment has been minimized.
This comment has been minimized.
antrik
Oct 19, 2016
Contributor
No, I was only referring to how changes are split up into patches, rather than the final code. (Sorry for being so pedantic about this... It's really not important; just a suggestion :-) )
Having said that, I already pondered something along the lines of what you said here. I'm honestly not sure. Normally, I'd prefer this approach indeed; but in this specific case, we need to handle each platform explicitly anyway because of the MsgControllen ugliness :-( It might still be a win though -- especially if this can be handled at the libc level at some point?...
This comment has been minimized.
This comment has been minimized.
dlrobertson
Oct 25, 2016
Author
Collaborator
Updated with the suggested patch splits.
Agreed. In the future we could/should be able to get away with just unix.
| unsafe fn new_sockaddr_un(path: *const c_char) -> (sockaddr_un, usize) { | ||
| let mut sockaddr: sockaddr_un = mem::zeroed(); | ||
| libc::strncpy(sockaddr.sun_path.as_mut_ptr(), | ||
| path, sockaddr.sun_path.len() - 1); | ||
| sockaddr.sun_family = libc::AF_UNIX as u16; | ||
| sockaddr.sun_family = libc::AF_UNIX as SunFamily; |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
| @@ -961,7 +954,7 @@ fn CMSG_LEN(length: size_t) -> size_t { | |||
| } | |||
|
|
|||
| #[allow(non_snake_case)] | |||
| fn CMSG_DATA(cmsg: *mut cmsghdr) -> *mut c_void { | |||
| unsafe fn CMSG_DATA(cmsg: *mut cmsghdr) -> *mut c_void { | |||
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
| let mut sockaddr: sockaddr_un = mem::zeroed(); | ||
| libc::strncpy(sockaddr.sun_path.as_mut_ptr(), | ||
| path, sockaddr.sun_path.len() - 1); | ||
| sockaddr.sun_family = libc::AF_UNIX as u16; |
This comment has been minimized.
This comment has been minimized.
antrik
Oct 5, 2016
•
Contributor
I'd split the commits a bit differently: first only split out new_sockaddr_un(), without any change to the actual code moved in there, so it's a pure refactoring; and only after that one or more commits that actually make it platform-agnostic, by introducing mem::zeroed(), sa_family_t, etc.
(Not insisting though -- probably it's clear enough that way as well...)
This comment has been minimized.
This comment has been minimized.
| path, sockaddr.sun_path.len() - 1); | ||
| sockaddr.sun_family = libc::AF_UNIX as u16; | ||
| let len = mem::size_of::<c_short>() + (libc::strlen(sockaddr.sun_path.as_ptr()) | ||
| as usize); |
This comment has been minimized.
This comment has been minimized.
antrik
Oct 5, 2016
Contributor
While this happens to work on Linux and FreeBSD, I don't think it's really generic... As I said, this would probably require some pointer arithmetic -- but I still think the right way to handle this is to just use sizeof sockaddr_un, like in the Linux man page example, rather than trying to determine the actually used size dynamically.
This comment has been minimized.
This comment has been minimized.
dlrobertson
Oct 11, 2016
Author
Collaborator
Good point. Used sizeof(sockaddr_un) in the latest batch of commits.
601b464
to
b9c149d
|
Apart from the pending question regarding handling of platform conditionals, I'd say this is good to go :-) |
myfreeweb
commented
Oct 21, 2016
|
Thank you for doing this work! Got Webrender working on FreeBSD :) |
Rename platform/linux to platform/unix in preparation to adding support for FreeBSD.
Instead of directly using ptr::offset and the equivalent of CMSG_DATA in glibc on Linux, create a CMSG_DATA function that should work on Linux and FreeBSD. This should not cause any side effects, but should make it easier if we should introduce support for another OS that may have a different implementation of CMSG_DATA.
Add the new_sockaddr_un function that builds a sockaddr_un struct in a platform agnostic way.
Add OS specific types that address alignment problems and their respective libc definitions.
b9c149d
to
4886205
|
Updated with the suggested patch splits. |
|
Great, let's get this landed :-) |
|
@bors-servo: r+ |
|
|
Support Freebsd Add support for FreeBSD and rename `linux` module to `unix`. **NB:** Some tests are still currently failing on freebsd. I believe most of which have to do with system limits e.g. (`platform::medium_data` blocks on a `send_followup_fragment` due to system limits and never recovers).
|
|
dlrobertson commentedSep 18, 2016
Add support for FreeBSD and rename
linuxmodule tounix.NB: Some tests are still currently failing on freebsd. I believe most of which have to do with system limits e.g. (
platform::medium_datablocks on asend_followup_fragmentdue to system limits and never recovers).