diff --git a/src/tools/miri/tests/pass-dep/libc/libc-epoll.rs b/src/tools/miri/tests/pass-dep/libc/libc-epoll.rs index 95fdf2f6035..364a784574a 100644 --- a/src/tools/miri/tests/pass-dep/libc/libc-epoll.rs +++ b/src/tools/miri/tests/pass-dep/libc/libc-epoll.rs @@ -5,20 +5,24 @@ use std::mem::MaybeUninit; fn main() { + test_epoll_socketpair(); + test_epoll_socketpair_both_sides(); + test_socketpair_read(); + test_epoll_eventfd(); + test_event_overwrite(); test_not_fully_closed_fd(); test_closed_fd(); - test_epoll_socketpair_special_case(); test_two_epoll_instance(); test_epoll_ctl_mod(); - test_epoll_socketpair(); - test_epoll_eventfd(); test_epoll_ctl_del(); test_pointer(); test_two_same_fd_in_same_epoll_instance(); - test_socketpair_read(); } +// Using `as` cast since `EPOLLET` wraps around +const EPOLL_IN_OUT_ET: u32 = (libc::EPOLLIN | libc::EPOLLOUT | libc::EPOLLET) as _; + #[track_caller] fn check_epoll_wait( epfd: i32, @@ -58,21 +62,17 @@ fn test_epoll_socketpair() { // Create a socketpair instance. let mut fds = [-1, -1]; - let mut res = - unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) }; + let res = unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) }; assert_eq!(res, 0); // Write to fd[0] let data = "abcde".as_bytes().as_ptr(); - res = unsafe { libc::write(fds[0], data as *const libc::c_void, 5).try_into().unwrap() }; + let res = unsafe { libc::write(fds[0], data as *const libc::c_void, 5) }; assert_eq!(res, 5); - // Register fd[1] with EPOLLIN|EPOLLOUT|EPOLLET - // EPOLLET is negative number for i32 so casting is needed to do proper bitwise OR for u32. - let epollet = libc::EPOLLET as u32; - let flags = u32::try_from(libc::EPOLLIN | libc::EPOLLOUT | libc::EPOLLRDHUP).unwrap() | epollet; + // Register fd[1] with EPOLLIN|EPOLLOUT|EPOLLET|EPOLLRDHUP let mut ev = libc::epoll_event { - events: u32::try_from(flags).unwrap(), + events: (libc::EPOLLIN | libc::EPOLLOUT | libc::EPOLLET | libc::EPOLLRDHUP) as _, u64: u64::try_from(fds[1]).unwrap(), }; let res = unsafe { libc::epoll_ctl(epfd, libc::EPOLL_CTL_ADD, fds[1], &mut ev) }; @@ -100,23 +100,17 @@ fn test_epoll_ctl_mod() { // Create a socketpair instance. let mut fds = [-1, -1]; - let mut res = - unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) }; + let res = unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) }; assert_eq!(res, 0); // Write to fd[0]. let data = "abcde".as_bytes().as_ptr(); - res = unsafe { libc::write(fds[0], data as *const libc::c_void, 5).try_into().unwrap() }; + let res = unsafe { libc::write(fds[0], data as *const libc::c_void, 5) }; assert_eq!(res, 5); // Register fd[1] with EPOLLIN|EPOLLOUT|EPOLLET. - // EPOLLET is negative number for i32 so casting is needed to do proper bitwise OR for u32. - let epollet = libc::EPOLLET as u32; - let mut flags = u32::try_from(libc::EPOLLIN | libc::EPOLLOUT).unwrap() | epollet; - let mut ev = libc::epoll_event { - events: u32::try_from(flags).unwrap(), - u64: u64::try_from(fds[1]).unwrap(), - }; + // (Not using checked cast as EPOLLET wraps around.) + let mut ev = libc::epoll_event { events: EPOLL_IN_OUT_ET, u64: u64::try_from(fds[1]).unwrap() }; let res = unsafe { libc::epoll_ctl(epfd, libc::EPOLL_CTL_ADD, fds[1], &mut ev) }; assert_ne!(res, -1); @@ -126,9 +120,8 @@ fn test_epoll_ctl_mod() { assert!(check_epoll_wait::<8>(epfd, vec![(expected_event, expected_value)])); // Test EPOLLRDHUP. - flags |= u32::try_from(libc::EPOLLRDHUP).unwrap(); let mut ev = libc::epoll_event { - events: u32::try_from(flags).unwrap(), + events: (libc::EPOLLIN | libc::EPOLLOUT | libc::EPOLLET | libc::EPOLLRDHUP) as _, u64: u64::try_from(fds[1]).unwrap(), }; let res = unsafe { libc::epoll_ctl(epfd, libc::EPOLL_CTL_MOD, fds[1], &mut ev) }; @@ -151,23 +144,16 @@ fn test_epoll_ctl_del() { // Create a socketpair instance. let mut fds = [-1, -1]; - let mut res = - unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) }; + let res = unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) }; assert_eq!(res, 0); // Write to fd[0] let data = "abcde".as_bytes().as_ptr(); - res = unsafe { libc::write(fds[0], data as *const libc::c_void, 5).try_into().unwrap() }; + let res = unsafe { libc::write(fds[0], data as *const libc::c_void, 5) }; assert_eq!(res, 5); // Register fd[1] with EPOLLIN|EPOLLOUT|EPOLLET - // EPOLLET is negative number for i32 so casting is needed to do proper bitwise OR for u32. - let epollet = libc::EPOLLET as u32; - let flags = u32::try_from(libc::EPOLLIN | libc::EPOLLOUT).unwrap() | epollet; - let mut ev = libc::epoll_event { - events: u32::try_from(flags).unwrap(), - u64: u64::try_from(fds[1]).unwrap(), - }; + let mut ev = libc::epoll_event { events: EPOLL_IN_OUT_ET, u64: u64::try_from(fds[1]).unwrap() }; let res = unsafe { libc::epoll_ctl(epfd, libc::EPOLL_CTL_ADD, fds[1], &mut ev) }; assert_ne!(res, -1); @@ -185,22 +171,16 @@ fn test_two_epoll_instance() { // Create a socketpair instance. let mut fds = [-1, -1]; - let mut res = - unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) }; + let res = unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) }; assert_eq!(res, 0); // Write to the socketpair. let data = "abcde".as_bytes().as_ptr(); - res = unsafe { libc::write(fds[0], data as *const libc::c_void, 5).try_into().unwrap() }; + let res = unsafe { libc::write(fds[0], data as *const libc::c_void, 5) }; assert_eq!(res, 5); // Register one side of the socketpair with EPOLLIN | EPOLLOUT | EPOLLET. - let epollet = libc::EPOLLET as u32; - let flags = u32::try_from(libc::EPOLLIN | libc::EPOLLOUT).unwrap() | epollet; - let mut ev = libc::epoll_event { - events: u32::try_from(flags).unwrap(), - u64: u64::try_from(fds[1]).unwrap(), - }; + let mut ev = libc::epoll_event { events: EPOLL_IN_OUT_ET, u64: u64::try_from(fds[1]).unwrap() }; let res = unsafe { libc::epoll_ctl(epfd1, libc::EPOLL_CTL_ADD, fds[1], &mut ev) }; assert_ne!(res, -1); let res = unsafe { libc::epoll_ctl(epfd2, libc::EPOLL_CTL_ADD, fds[1], &mut ev) }; @@ -230,17 +210,15 @@ fn test_two_same_fd_in_same_epoll_instance() { assert_ne!(newfd, -1); // Register both fd to the same epoll instance. - let epollet = libc::EPOLLET as u32; - let flags = u32::try_from(libc::EPOLLIN | libc::EPOLLOUT).unwrap() | epollet; - let mut ev = libc::epoll_event { events: u32::try_from(flags).unwrap(), u64: 5 as u64 }; - let mut res = unsafe { libc::epoll_ctl(epfd, libc::EPOLL_CTL_ADD, fds[1], &mut ev) }; + let mut ev = libc::epoll_event { events: EPOLL_IN_OUT_ET, u64: 5 as u64 }; + let res = unsafe { libc::epoll_ctl(epfd, libc::EPOLL_CTL_ADD, fds[1], &mut ev) }; assert_ne!(res, -1); - res = unsafe { libc::epoll_ctl(epfd, libc::EPOLL_CTL_ADD, newfd, &mut ev) }; + let res = unsafe { libc::epoll_ctl(epfd, libc::EPOLL_CTL_ADD, newfd, &mut ev) }; assert_ne!(res, -1); // Write to the socketpair. let data = "abcde".as_bytes().as_ptr(); - res = unsafe { libc::write(fds[0], data as *const libc::c_void, 5).try_into().unwrap() }; + let res = unsafe { libc::write(fds[0], data as *const libc::c_void, 5) }; assert_eq!(res, 5); //Two notification should be received. @@ -259,9 +237,7 @@ fn test_epoll_eventfd() { // Write to the eventfd instance. let sized_8_data: [u8; 8] = 1_u64.to_ne_bytes(); - let res: i32 = unsafe { - libc::write(fd, sized_8_data.as_ptr() as *const libc::c_void, 8).try_into().unwrap() - }; + let res = unsafe { libc::write(fd, sized_8_data.as_ptr() as *const libc::c_void, 8) }; assert_eq!(res, 8); // Create an epoll instance. @@ -269,13 +245,7 @@ fn test_epoll_eventfd() { assert_ne!(epfd, -1); // Register eventfd with EPOLLIN | EPOLLOUT | EPOLLET - // EPOLLET is negative number for i32 so casting is needed to do proper bitwise OR for u32. - let epollet = libc::EPOLLET as u32; - let flags = u32::try_from(libc::EPOLLIN | libc::EPOLLOUT).unwrap() | epollet; - let mut ev = libc::epoll_event { - events: u32::try_from(flags).unwrap(), - u64: u64::try_from(fd).unwrap(), - }; + let mut ev = libc::epoll_event { events: EPOLL_IN_OUT_ET, u64: u64::try_from(fd).unwrap() }; let res = unsafe { libc::epoll_ctl(epfd, libc::EPOLL_CTL_ADD, fd, &mut ev) }; assert_ne!(res, -1); @@ -296,20 +266,15 @@ fn test_pointer() { assert_eq!(res, 0); // Register fd[1] with EPOLLIN|EPOLLOUT|EPOLLET - // EPOLLET is negative number for i32 so casting is needed to do proper bitwise OR for u32. - let epollet = libc::EPOLLET as u32; - let flags = u32::try_from(libc::EPOLLIN | libc::EPOLLOUT | libc::EPOLLRDHUP).unwrap() | epollet; let data = MaybeUninit::::uninit().as_ptr(); - let mut ev = libc::epoll_event { - events: u32::try_from(flags).unwrap(), - u64: data.expose_provenance() as u64, - }; + let mut ev = + libc::epoll_event { events: EPOLL_IN_OUT_ET, u64: data.expose_provenance() as u64 }; let res = unsafe { libc::epoll_ctl(epfd, libc::EPOLL_CTL_ADD, fds[1], &mut ev) }; assert_ne!(res, -1); } // When read/write happened on one side of the socketpair, only the other side will be notified. -fn test_epoll_socketpair_special_case() { +fn test_epoll_socketpair_both_sides() { // Create an epoll instance. let epfd = unsafe { libc::epoll_create1(0) }; assert_ne!(epfd, -1); @@ -320,18 +285,16 @@ fn test_epoll_socketpair_special_case() { assert_eq!(res, 0); // Register both fd to the same epoll instance. - let epollet = libc::EPOLLET as u32; - let flags = u32::try_from(libc::EPOLLIN | libc::EPOLLOUT).unwrap() | epollet; - let mut ev = libc::epoll_event { events: u32::try_from(flags).unwrap(), u64: fds[0] as u64 }; - let mut res = unsafe { libc::epoll_ctl(epfd, libc::EPOLL_CTL_ADD, fds[0], &mut ev) }; + let mut ev = libc::epoll_event { events: EPOLL_IN_OUT_ET, u64: fds[0] as u64 }; + let res = unsafe { libc::epoll_ctl(epfd, libc::EPOLL_CTL_ADD, fds[0], &mut ev) }; assert_ne!(res, -1); - let mut ev = libc::epoll_event { events: u32::try_from(flags).unwrap(), u64: fds[1] as u64 }; - res = unsafe { libc::epoll_ctl(epfd, libc::EPOLL_CTL_ADD, fds[1], &mut ev) }; + let mut ev = libc::epoll_event { events: EPOLL_IN_OUT_ET, u64: fds[1] as u64 }; + let res = unsafe { libc::epoll_ctl(epfd, libc::EPOLL_CTL_ADD, fds[1], &mut ev) }; assert_ne!(res, -1); // Write to fds[1]. let data = "abcde".as_bytes().as_ptr(); - res = unsafe { libc::write(fds[1], data as *const libc::c_void, 5).try_into().unwrap() }; + let res = unsafe { libc::write(fds[1], data as *const libc::c_void, 5) }; assert_eq!(res, 5); //Two notification should be received. @@ -346,9 +309,7 @@ fn test_epoll_socketpair_special_case() { // Read from fds[0]. let mut buf: [u8; 5] = [0; 5]; - res = unsafe { - libc::read(fds[0], buf.as_mut_ptr().cast(), buf.len() as libc::size_t).try_into().unwrap() - }; + let res = unsafe { libc::read(fds[0], buf.as_mut_ptr().cast(), buf.len() as libc::size_t) }; assert_eq!(res, 5); assert_eq!(buf, "abcde".as_bytes()); @@ -370,21 +331,13 @@ fn test_closed_fd() { let fd = unsafe { libc::eventfd(0, flags) }; // Register eventfd with EPOLLIN | EPOLLOUT | EPOLLET - // EPOLLET is negative number for i32 so casting is needed to do proper bitwise OR for u32. - let epollet = libc::EPOLLET as u32; - let flags = u32::try_from(libc::EPOLLIN | libc::EPOLLOUT).unwrap() | epollet; - let mut ev = libc::epoll_event { - events: u32::try_from(flags).unwrap(), - u64: u64::try_from(fd).unwrap(), - }; + let mut ev = libc::epoll_event { events: EPOLL_IN_OUT_ET, u64: u64::try_from(fd).unwrap() }; let res = unsafe { libc::epoll_ctl(epfd, libc::EPOLL_CTL_ADD, fd, &mut ev) }; assert_ne!(res, -1); // Write to the eventfd instance. let sized_8_data: [u8; 8] = 1_u64.to_ne_bytes(); - let res: i32 = unsafe { - libc::write(fd, sized_8_data.as_ptr() as *const libc::c_void, 8).try_into().unwrap() - }; + let res = unsafe { libc::write(fd, sized_8_data.as_ptr() as *const libc::c_void, 8) }; assert_eq!(res, 8); // Close the eventfd. @@ -415,13 +368,7 @@ fn test_not_fully_closed_fd() { assert_ne!(newfd, -1); // Register eventfd with EPOLLIN | EPOLLOUT | EPOLLET - // EPOLLET is negative number for i32 so casting is needed to do proper bitwise OR for u32. - let epollet = libc::EPOLLET as u32; - let flags = u32::try_from(libc::EPOLLIN | libc::EPOLLOUT).unwrap() | epollet; - let mut ev = libc::epoll_event { - events: u32::try_from(flags).unwrap(), - u64: u64::try_from(fd).unwrap(), - }; + let mut ev = libc::epoll_event { events: EPOLL_IN_OUT_ET, u64: u64::try_from(fd).unwrap() }; let res = unsafe { libc::epoll_ctl(epfd, libc::EPOLL_CTL_ADD, fd, &mut ev) }; assert_ne!(res, -1); @@ -436,9 +383,7 @@ fn test_not_fully_closed_fd() { // Write to the eventfd instance to produce notification. let sized_8_data: [u8; 8] = 1_u64.to_ne_bytes(); - let res: i32 = unsafe { - libc::write(newfd, sized_8_data.as_ptr() as *const libc::c_void, 8).try_into().unwrap() - }; + let res = unsafe { libc::write(newfd, sized_8_data.as_ptr() as *const libc::c_void, 8) }; assert_eq!(res, 8); // Close the dupped fd. @@ -458,9 +403,7 @@ fn test_event_overwrite() { // Write to the eventfd instance. let sized_8_data: [u8; 8] = 1_u64.to_ne_bytes(); - let res: i32 = unsafe { - libc::write(fd, sized_8_data.as_ptr() as *const libc::c_void, 8).try_into().unwrap() - }; + let res = unsafe { libc::write(fd, sized_8_data.as_ptr() as *const libc::c_void, 8) }; assert_eq!(res, 8); // Create an epoll instance. @@ -468,11 +411,8 @@ fn test_event_overwrite() { assert_ne!(epfd, -1); // Register eventfd with EPOLLIN | EPOLLOUT | EPOLLET - // EPOLLET is negative number for i32 so casting is needed to do proper bitwise OR for u32. - let epollet = libc::EPOLLET as u32; - let flags = u32::try_from(libc::EPOLLIN | libc::EPOLLOUT).unwrap() | epollet; let mut ev = libc::epoll_event { - events: u32::try_from(flags).unwrap(), + events: (libc::EPOLLIN | libc::EPOLLOUT | libc::EPOLLET) as _, u64: u64::try_from(fd).unwrap(), }; let res = unsafe { libc::epoll_ctl(epfd, libc::EPOLL_CTL_ADD, fd, &mut ev) }; @@ -480,7 +420,7 @@ fn test_event_overwrite() { // Read from the eventfd instance. let mut buf: [u8; 8] = [0; 8]; - let res: i32 = unsafe { libc::read(fd, buf.as_mut_ptr().cast(), 8).try_into().unwrap() }; + let res = unsafe { libc::read(fd, buf.as_mut_ptr().cast(), 8) }; assert_eq!(res, 8); // Check result from epoll_wait. @@ -502,18 +442,22 @@ fn test_socketpair_read() { assert_eq!(res, 0); // Register both fd to the same epoll instance. - let epollet = libc::EPOLLET as u32; - let flags = u32::try_from(libc::EPOLLIN | libc::EPOLLOUT).unwrap() | epollet; - let mut ev = libc::epoll_event { events: u32::try_from(flags).unwrap(), u64: fds[0] as u64 }; - let mut res = unsafe { libc::epoll_ctl(epfd, libc::EPOLL_CTL_ADD, fds[0], &mut ev) }; + let mut ev = libc::epoll_event { + events: (libc::EPOLLIN | libc::EPOLLOUT | libc::EPOLLET) as _, + u64: fds[0] as u64, + }; + let res = unsafe { libc::epoll_ctl(epfd, libc::EPOLL_CTL_ADD, fds[0], &mut ev) }; assert_ne!(res, -1); - let mut ev = libc::epoll_event { events: u32::try_from(flags).unwrap(), u64: fds[1] as u64 }; - res = unsafe { libc::epoll_ctl(epfd, libc::EPOLL_CTL_ADD, fds[1], &mut ev) }; + let mut ev = libc::epoll_event { + events: (libc::EPOLLIN | libc::EPOLLOUT | libc::EPOLLET) as _, + u64: fds[1] as u64, + }; + let res = unsafe { libc::epoll_ctl(epfd, libc::EPOLL_CTL_ADD, fds[1], &mut ev) }; assert_ne!(res, -1); // Write 5 bytes to fds[1]. let data = "abcde".as_bytes().as_ptr(); - res = unsafe { libc::write(fds[1], data as *const libc::c_void, 5).try_into().unwrap() }; + let res = unsafe { libc::write(fds[1], data as *const libc::c_void, 5) }; assert_eq!(res, 5); //Two notification should be received. @@ -528,9 +472,7 @@ fn test_socketpair_read() { // Read 3 bytes from fds[0]. let mut buf: [u8; 3] = [0; 3]; - res = unsafe { - libc::read(fds[0], buf.as_mut_ptr().cast(), buf.len() as libc::size_t).try_into().unwrap() - }; + let res = unsafe { libc::read(fds[0], buf.as_mut_ptr().cast(), buf.len() as libc::size_t) }; assert_eq!(res, 3); assert_eq!(buf, "abc".as_bytes()); @@ -542,9 +484,7 @@ fn test_socketpair_read() { // Read until the buffer is empty. let mut buf: [u8; 2] = [0; 2]; - res = unsafe { - libc::read(fds[0], buf.as_mut_ptr().cast(), buf.len() as libc::size_t).try_into().unwrap() - }; + let res = unsafe { libc::read(fds[0], buf.as_mut_ptr().cast(), buf.len() as libc::size_t) }; assert_eq!(res, 2); assert_eq!(buf, "de".as_bytes());