Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Get rid of a lot of transmutes #700

Merged
merged 2 commits into from
Aug 17, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/sched.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ pub fn sched_setaffinity(pid: Pid, cpuset: &CpuSet) -> Result<()> {
let res = unsafe {
libc::sched_setaffinity(pid.into(),
mem::size_of::<CpuSet>() as libc::size_t,
mem::transmute(cpuset))
&cpuset.cpu_set)
};

Errno::result(res).map(drop)
Expand Down
10 changes: 2 additions & 8 deletions src/sys/quota.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,16 +111,10 @@ pub fn quotactl_sync<P: ?Sized + NixPath>(which: quota::QuotaType, special: Opti
}

pub fn quotactl_get<P: ?Sized + NixPath>(which: quota::QuotaType, special: &P, id: c_int, dqblk: &mut quota::Dqblk) -> Result<()> {
use std::mem;
unsafe {
quotactl(quota::QuotaCmd(quota::Q_GETQUOTA, which), Some(special), id, mem::transmute(dqblk))
}
quotactl(quota::QuotaCmd(quota::Q_GETQUOTA, which), Some(special), id, dqblk as *mut _ as *mut c_char)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you need to cast twice?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because you can only cast a reference to a raw pointer to the exact same type

}

pub fn quotactl_set<P: ?Sized + NixPath>(which: quota::QuotaType, special: &P, id: c_int, dqblk: &quota::Dqblk) -> Result<()> {
use std::mem;
let mut dqblk_copy = *dqblk;
unsafe {
quotactl(quota::QuotaCmd(quota::Q_SETQUOTA, which), Some(special), id, mem::transmute(&mut dqblk_copy))
}
quotactl(quota::QuotaCmd(quota::Q_SETQUOTA, which), Some(special), id, &mut dqblk_copy as *mut _ as *mut c_char)
}
8 changes: 4 additions & 4 deletions src/sys/signal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -364,10 +364,10 @@ impl SigAction {
pub fn new(handler: SigHandler, flags: SaFlags, mask: SigSet) -> SigAction {
let mut s = unsafe { mem::uninitialized::<libc::sigaction>() };
s.sa_sigaction = match handler {
SigHandler::SigDfl => unsafe { mem::transmute(libc::SIG_DFL) },
SigHandler::SigIgn => unsafe { mem::transmute(libc::SIG_IGN) },
SigHandler::Handler(f) => unsafe { mem::transmute(f) },
SigHandler::SigAction(f) => unsafe { mem::transmute(f) },
SigHandler::SigDfl => libc::SIG_DFL,
SigHandler::SigIgn => libc::SIG_IGN,
SigHandler::Handler(f) => f as *const extern fn(libc::c_int) as usize,
SigHandler::SigAction(f) => f as *const extern fn(libc::c_int, *mut libc::siginfo_t, *mut libc::c_void) as usize,
};
s.sa_flags = match handler {
SigHandler::SigAction(_) => (flags | SA_SIGINFO).bits(),
Expand Down
4 changes: 2 additions & 2 deletions src/sys/socket/addr.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use super::sa_family_t;
use {Errno, Error, Result, NixPath};
use libc;
use std::{fmt, hash, mem, net, ptr};
use std::{fmt, hash, mem, net, ptr, slice};
use std::ffi::OsStr;
use std::path::Path;
use std::os::unix::ffi::OsStrExt;
Expand Down Expand Up @@ -581,7 +581,7 @@ impl UnixAddr {
}

fn sun_path(&self) -> &[u8] {
unsafe { mem::transmute(&self.0.sun_path[..self.1]) }
unsafe { slice::from_raw_parts(self.0.sun_path.as_ptr() as *const u8, self.1) }
}

/// If this address represents a filesystem path, return that path.
Expand Down
2 changes: 1 addition & 1 deletion src/sys/socket/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ impl<'a> Iterator for CmsgIterator<'a> {
if self.buf.len() < sizeof_cmsghdr {
return None;
}
let cmsg: &cmsghdr = unsafe { mem::transmute(self.buf.as_ptr()) };
let cmsg: &'a cmsghdr = unsafe { &*(self.buf.as_ptr() as *const cmsghdr) };

// This check is only in the glibc implementation of CMSG_NXTHDR
// (although it claims the kernel header checks this), but such
Expand Down
84 changes: 42 additions & 42 deletions src/sys/socket/sockopt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -178,38 +178,38 @@ sockopt_impl!(GetOnly, OriginalDst, libc::SOL_IP, libc::SO_ORIGINAL_DST, libc::s
*
*/

trait Get<T> {
unsafe trait Get<T> {
unsafe fn blank() -> Self;
unsafe fn ffi_ptr(&mut self) -> *mut c_void;
unsafe fn ffi_len(&mut self) -> *mut socklen_t;
fn ffi_ptr(&mut self) -> *mut c_void;
fn ffi_len(&mut self) -> *mut socklen_t;
unsafe fn unwrap(self) -> T;
}

trait Set<'a, T> {
unsafe trait Set<'a, T> {
fn new(val: &'a T) -> Self;
unsafe fn ffi_ptr(&self) -> *const c_void;
unsafe fn ffi_len(&self) -> socklen_t;
fn ffi_ptr(&self) -> *const c_void;
fn ffi_len(&self) -> socklen_t;
}

struct GetStruct<T> {
len: socklen_t,
val: T,
}

impl<T> Get<T> for GetStruct<T> {
unsafe impl<T> Get<T> for GetStruct<T> {
unsafe fn blank() -> Self {
GetStruct {
len: mem::size_of::<T>() as socklen_t,
val: mem::zeroed(),
}
}

unsafe fn ffi_ptr(&mut self) -> *mut c_void {
mem::transmute(&mut self.val)
fn ffi_ptr(&mut self) -> *mut c_void {
&mut self.val as *mut T as *mut c_void
}

unsafe fn ffi_len(&mut self) -> *mut socklen_t {
mem::transmute(&mut self.len)
fn ffi_len(&mut self) -> *mut socklen_t {
&mut self.len
}

unsafe fn unwrap(self) -> T {
Expand All @@ -222,16 +222,16 @@ struct SetStruct<'a, T: 'static> {
ptr: &'a T,
}

impl<'a, T> Set<'a, T> for SetStruct<'a, T> {
unsafe impl<'a, T> Set<'a, T> for SetStruct<'a, T> {
fn new(ptr: &'a T) -> SetStruct<'a, T> {
SetStruct { ptr: ptr }
}

unsafe fn ffi_ptr(&self) -> *const c_void {
mem::transmute(self.ptr)
fn ffi_ptr(&self) -> *const c_void {
self.ptr as *const T as *const c_void
}

unsafe fn ffi_len(&self) -> socklen_t {
fn ffi_len(&self) -> socklen_t {
mem::size_of::<T>() as socklen_t
}
}
Expand All @@ -241,20 +241,20 @@ struct GetBool {
val: c_int,
}

impl Get<bool> for GetBool {
unsafe impl Get<bool> for GetBool {
unsafe fn blank() -> Self {
GetBool {
len: mem::size_of::<c_int>() as socklen_t,
val: mem::zeroed(),
}
}

unsafe fn ffi_ptr(&mut self) -> *mut c_void {
mem::transmute(&mut self.val)
fn ffi_ptr(&mut self) -> *mut c_void {
&mut self.val as *mut c_int as *mut c_void
}

unsafe fn ffi_len(&mut self) -> *mut socklen_t {
mem::transmute(&mut self.len)
fn ffi_len(&mut self) -> *mut socklen_t {
&mut self.len
}

unsafe fn unwrap(self) -> bool {
Expand All @@ -267,16 +267,16 @@ struct SetBool {
val: c_int,
}

impl<'a> Set<'a, bool> for SetBool {
unsafe impl<'a> Set<'a, bool> for SetBool {
fn new(val: &'a bool) -> SetBool {
SetBool { val: if *val { 1 } else { 0 } }
}

unsafe fn ffi_ptr(&self) -> *const c_void {
mem::transmute(&self.val)
fn ffi_ptr(&self) -> *const c_void {
&self.val as *const c_int as *const c_void
}

unsafe fn ffi_len(&self) -> socklen_t {
fn ffi_len(&self) -> socklen_t {
mem::size_of::<c_int>() as socklen_t
}
}
Expand All @@ -286,20 +286,20 @@ struct GetU8 {
val: uint8_t,
}

impl Get<u8> for GetU8 {
unsafe impl Get<u8> for GetU8 {
unsafe fn blank() -> Self {
GetU8 {
len: mem::size_of::<uint8_t>() as socklen_t,
val: mem::zeroed(),
}
}

unsafe fn ffi_ptr(&mut self) -> *mut c_void {
mem::transmute(&mut self.val)
fn ffi_ptr(&mut self) -> *mut c_void {
&mut self.val as *mut uint8_t as *mut c_void
}

unsafe fn ffi_len(&mut self) -> *mut socklen_t {
mem::transmute(&mut self.len)
fn ffi_len(&mut self) -> *mut socklen_t {
&mut self.len
}

unsafe fn unwrap(self) -> u8 {
Expand All @@ -312,16 +312,16 @@ struct SetU8 {
val: uint8_t,
}

impl<'a> Set<'a, u8> for SetU8 {
unsafe impl<'a> Set<'a, u8> for SetU8 {
fn new(val: &'a u8) -> SetU8 {
SetU8 { val: *val as uint8_t }
}

unsafe fn ffi_ptr(&self) -> *const c_void {
mem::transmute(&self.val)
fn ffi_ptr(&self) -> *const c_void {
&self.val as *const uint8_t as *const c_void
}

unsafe fn ffi_len(&self) -> socklen_t {
fn ffi_len(&self) -> socklen_t {
mem::size_of::<c_int>() as socklen_t
}
}
Expand All @@ -331,20 +331,20 @@ struct GetUsize {
val: c_int,
}

impl Get<usize> for GetUsize {
unsafe impl Get<usize> for GetUsize {
unsafe fn blank() -> Self {
GetUsize {
len: mem::size_of::<c_int>() as socklen_t,
val: mem::zeroed(),
}
}

unsafe fn ffi_ptr(&mut self) -> *mut c_void {
mem::transmute(&mut self.val)
fn ffi_ptr(&mut self) -> *mut c_void {
&mut self.val as *mut c_int as *mut c_void
}

unsafe fn ffi_len(&mut self) -> *mut socklen_t {
mem::transmute(&mut self.len)
fn ffi_len(&mut self) -> *mut socklen_t {
&mut self.len
}

unsafe fn unwrap(self) -> usize {
Expand All @@ -357,16 +357,16 @@ struct SetUsize {
val: c_int,
}

impl<'a> Set<'a, usize> for SetUsize {
unsafe impl<'a> Set<'a, usize> for SetUsize {
fn new(val: &'a usize) -> SetUsize {
SetUsize { val: *val as c_int }
}

unsafe fn ffi_ptr(&self) -> *const c_void {
mem::transmute(&self.val)
fn ffi_ptr(&self) -> *const c_void {
&self.val as *const c_int as *const c_void
}

unsafe fn ffi_len(&self) -> socklen_t {
fn ffi_len(&self) -> socklen_t {
mem::size_of::<c_int>() as socklen_t
}
}
Expand Down
9 changes: 6 additions & 3 deletions test/sys/test_socket.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use nix::sys::socket::{InetAddr, UnixAddr, getsockname};
use std::mem;
use std::{mem, slice};
use std::net::{self, Ipv6Addr, SocketAddr, SocketAddrV6};
use std::path::Path;
use std::str::FromStr;
Expand Down Expand Up @@ -52,10 +52,13 @@ pub fn test_inetv6_addr_to_sock_addr() {

#[test]
pub fn test_path_to_sock_addr() {
let actual = Path::new("/foo/bar");
let path = "/foo/bar";
let actual = Path::new(path);
let addr = UnixAddr::new(actual).unwrap();

let expect: &'static [c_char] = unsafe { mem::transmute(&b"/foo/bar"[..]) };
let expect: &[c_char] = unsafe {
slice::from_raw_parts(path.as_bytes().as_ptr() as *const c_char, path.len())
};
assert_eq!(&addr.0.sun_path[..8], expect);

assert_eq!(addr.path(), Some(actual));
Expand Down