Skip to content

Commit 9f064da

Browse files
committed
libc_util: add helpers to deal with errno-style functions
1 parent 6bb1fef commit 9f064da

File tree

3 files changed

+82
-112
lines changed

3 files changed

+82
-112
lines changed

src/tools/miri/tests/pass-dep/libc/libc-epoll-no-blocking.rs

Lines changed: 48 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use std::convert::TryInto;
44

55
#[path = "../../utils/libc.rs"]
66
mod libc_utils;
7+
use libc_utils::*;
78

89
fn main() {
910
test_epoll_socketpair();
@@ -51,13 +52,11 @@ fn check_epoll_wait<const N: usize>(epfd: i32, expected_notifications: &[(u32, u
5152

5253
fn test_epoll_socketpair() {
5354
// Create an epoll instance.
54-
let epfd = unsafe { libc::epoll_create1(0) };
55-
assert_ne!(epfd, -1);
55+
let epfd = errno_result(unsafe { libc::epoll_create1(0) }).unwrap();
5656

5757
// Create a socketpair instance.
5858
let mut fds = [-1, -1];
59-
let res = unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) };
60-
assert_eq!(res, 0);
59+
errno_check(unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) });
6160
let fds = [fds[1], fds[0]];
6261

6362
// Write to fd[0]
@@ -92,8 +91,7 @@ fn test_epoll_socketpair() {
9291
check_epoll_wait::<8>(epfd, &[(expected_event, expected_value)]);
9392

9493
// Close the peer socketpair.
95-
let res = unsafe { libc::close(fds[0]) };
96-
assert_eq!(res, 0);
94+
errno_check(unsafe { libc::close(fds[0]) });
9795

9896
// Check result from epoll_wait.
9997
// We expect to get a read, write, HUP notification from the close since closing an FD always unblocks reads and writes on its peer.
@@ -108,13 +106,11 @@ fn test_epoll_socketpair() {
108106
// Also check that the new data value set via MOD is applied properly.
109107
fn test_epoll_ctl_mod() {
110108
// Create an epoll instance.
111-
let epfd = unsafe { libc::epoll_create1(0) };
112-
assert_ne!(epfd, -1);
109+
let epfd = errno_result(unsafe { libc::epoll_create1(0) }).unwrap();
113110

114111
// Create a socketpair instance.
115112
let mut fds = [-1, -1];
116-
let res = unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) };
117-
assert_eq!(res, 0);
113+
errno_check(unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) });
118114

119115
// Register fd[1] with EPOLLIN|EPOLLET, and data of "0".
120116
let mut ev = libc::epoll_event { events: (libc::EPOLLIN | libc::EPOLLET) as _, u64: 0 };
@@ -164,13 +160,11 @@ fn test_epoll_ctl_mod() {
164160

165161
fn test_epoll_ctl_del() {
166162
// Create an epoll instance.
167-
let epfd = unsafe { libc::epoll_create1(0) };
168-
assert_ne!(epfd, -1);
163+
let epfd = errno_result(unsafe { libc::epoll_create1(0) }).unwrap();
169164

170165
// Create a socketpair instance.
171166
let mut fds = [-1, -1];
172-
let res = unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) };
173-
assert_eq!(res, 0);
167+
errno_check(unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) });
174168

175169
// Write to fd[0]
176170
let data = "abcde".as_bytes().as_ptr();
@@ -198,8 +192,7 @@ fn test_two_epoll_instance() {
198192

199193
// Create a socketpair instance.
200194
let mut fds = [-1, -1];
201-
let res = unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) };
202-
assert_eq!(res, 0);
195+
errno_check(unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) });
203196

204197
// Write to the socketpair.
205198
let data = "abcde".as_bytes().as_ptr();
@@ -224,13 +217,11 @@ fn test_two_epoll_instance() {
224217
// Notification should be provided for both.
225218
fn test_two_same_fd_in_same_epoll_instance() {
226219
// Create an epoll instance.
227-
let epfd = unsafe { libc::epoll_create1(0) };
228-
assert_ne!(epfd, -1);
220+
let epfd = errno_result(unsafe { libc::epoll_create1(0) }).unwrap();
229221

230222
// Create a socketpair instance.
231223
let mut fds = [-1, -1];
232-
let res = unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) };
233-
assert_eq!(res, 0);
224+
errno_check(unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) });
234225

235226
// Dup the fd.
236227
let newfd = unsafe { libc::dup(fds[1]) };
@@ -260,14 +251,13 @@ fn test_two_same_fd_in_same_epoll_instance() {
260251
fn test_epoll_eventfd() {
261252
// Create an eventfd instance.
262253
let flags = libc::EFD_NONBLOCK | libc::EFD_CLOEXEC;
263-
let fd = unsafe { libc::eventfd(0, flags) };
254+
let fd = errno_result(unsafe { libc::eventfd(0, flags) }).unwrap();
264255

265256
// Write 1 to the eventfd instance.
266257
libc_utils::write_all_from_slice(fd, &1_u64.to_ne_bytes()).unwrap();
267258

268259
// Create an epoll instance.
269-
let epfd = unsafe { libc::epoll_create1(0) };
270-
assert_ne!(epfd, -1);
260+
let epfd = errno_result(unsafe { libc::epoll_create1(0) }).unwrap();
271261

272262
// Register eventfd with EPOLLIN | EPOLLOUT | EPOLLET
273263
let mut ev = libc::epoll_event { events: EPOLL_IN_OUT_ET, u64: u64::try_from(fd).unwrap() };
@@ -308,13 +298,11 @@ fn test_epoll_eventfd() {
308298
// When read/write happened on one side of the socketpair, only the other side will be notified.
309299
fn test_epoll_socketpair_both_sides() {
310300
// Create an epoll instance.
311-
let epfd = unsafe { libc::epoll_create1(0) };
312-
assert_ne!(epfd, -1);
301+
let epfd = errno_result(unsafe { libc::epoll_create1(0) }).unwrap();
313302

314303
// Create a socketpair instance.
315304
let mut fds = [-1, -1];
316-
let res = unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) };
317-
assert_eq!(res, 0);
305+
errno_check(unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) });
318306

319307
// Register both fd to the same epoll instance.
320308
let mut ev = libc::epoll_event { events: EPOLL_IN_OUT_ET, u64: fds[0] as u64 };
@@ -358,12 +346,11 @@ fn test_epoll_socketpair_both_sides() {
358346
// that file description.
359347
fn test_closed_fd() {
360348
// Create an epoll instance.
361-
let epfd = unsafe { libc::epoll_create1(0) };
362-
assert_ne!(epfd, -1);
349+
let epfd = errno_result(unsafe { libc::epoll_create1(0) }).unwrap();
363350

364351
// Create an eventfd instance.
365352
let flags = libc::EFD_NONBLOCK | libc::EFD_CLOEXEC;
366-
let fd = unsafe { libc::eventfd(0, flags) };
353+
let fd = errno_result(unsafe { libc::eventfd(0, flags) }).unwrap();
367354

368355
// Register eventfd with EPOLLIN | EPOLLOUT | EPOLLET
369356
let mut ev = libc::epoll_event { events: EPOLL_IN_OUT_ET, u64: u64::try_from(fd).unwrap() };
@@ -376,8 +363,7 @@ fn test_closed_fd() {
376363
assert_eq!(res, 8);
377364

378365
// Close the eventfd.
379-
let res = unsafe { libc::close(fd) };
380-
assert_eq!(res, 0);
366+
errno_check(unsafe { libc::close(fd) });
381367

382368
// No notification should be provided because the file description is closed.
383369
check_epoll_wait::<8>(epfd, &[]);
@@ -391,25 +377,22 @@ fn test_closed_fd() {
391377
// referring to the underlying open file description have been closed.
392378
fn test_not_fully_closed_fd() {
393379
// Create an epoll instance.
394-
let epfd = unsafe { libc::epoll_create1(0) };
395-
assert_ne!(epfd, -1);
380+
let epfd = errno_result(unsafe { libc::epoll_create1(0) }).unwrap();
396381

397382
// Create an eventfd instance.
398-
let flags = libc::EFD_NONBLOCK | libc::EFD_CLOEXEC;
399-
let fd = unsafe { libc::eventfd(0, flags) };
383+
let fd =
384+
errno_result(unsafe { libc::eventfd(0, libc::EFD_NONBLOCK | libc::EFD_CLOEXEC) }).unwrap();
400385

401386
// Dup the fd.
402-
let newfd = unsafe { libc::dup(fd) };
403-
assert_ne!(newfd, -1);
387+
let newfd = errno_result(unsafe { libc::dup(fd) }).unwrap();
404388

405389
// Register eventfd with EPOLLIN | EPOLLOUT | EPOLLET
406390
let mut ev = libc::epoll_event { events: EPOLL_IN_OUT_ET, u64: u64::try_from(fd).unwrap() };
407391
let res = unsafe { libc::epoll_ctl(epfd, libc::EPOLL_CTL_ADD, fd, &mut ev) };
408392
assert_eq!(res, 0);
409393

410394
// Close the original fd that being used to register with epoll.
411-
let res = unsafe { libc::close(fd) };
412-
assert_eq!(res, 0);
395+
errno_check(unsafe { libc::close(fd) });
413396

414397
// Notification should still be provided because the file description is not closed.
415398
let expected_event = u32::try_from(libc::EPOLLOUT).unwrap();
@@ -423,8 +406,7 @@ fn test_not_fully_closed_fd() {
423406
assert_eq!(res, 8);
424407

425408
// Close the dupped fd.
426-
let res = unsafe { libc::close(newfd) };
427-
assert_eq!(res, 0);
409+
errno_check(unsafe { libc::close(newfd) });
428410

429411
// No notification should be provided.
430412
check_epoll_wait::<1>(epfd, &[]);
@@ -434,17 +416,16 @@ fn test_not_fully_closed_fd() {
434416
// at the moment the latest event occurred.
435417
fn test_event_overwrite() {
436418
// Create an eventfd instance.
437-
let flags = libc::EFD_NONBLOCK | libc::EFD_CLOEXEC;
438-
let fd = unsafe { libc::eventfd(0, flags) };
419+
let fd =
420+
errno_result(unsafe { libc::eventfd(0, libc::EFD_NONBLOCK | libc::EFD_CLOEXEC) }).unwrap();
439421

440422
// Write to the eventfd instance.
441423
let sized_8_data: [u8; 8] = 1_u64.to_ne_bytes();
442424
let res = unsafe { libc_utils::write_all(fd, sized_8_data.as_ptr() as *const libc::c_void, 8) };
443425
assert_eq!(res, 8);
444426

445427
// Create an epoll instance.
446-
let epfd = unsafe { libc::epoll_create1(0) };
447-
assert_ne!(epfd, -1);
428+
let epfd = errno_result(unsafe { libc::epoll_create1(0) }).unwrap();
448429

449430
// Register eventfd with EPOLLIN | EPOLLOUT | EPOLLET
450431
let mut ev = libc::epoll_event {
@@ -469,13 +450,11 @@ fn test_event_overwrite() {
469450
// This behaviour differs from the real system.
470451
fn test_socketpair_read() {
471452
// Create an epoll instance.
472-
let epfd = unsafe { libc::epoll_create1(0) };
473-
assert_ne!(epfd, -1);
453+
let epfd = errno_result(unsafe { libc::epoll_create1(0) }).unwrap();
474454

475455
// Create a socketpair instance.
476456
let mut fds = [-1, -1];
477-
let res = unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) };
478-
assert_eq!(res, 0);
457+
errno_check(unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) });
479458

480459
// Register both fd to the same epoll instance.
481460
let mut ev = libc::epoll_event {
@@ -533,13 +512,11 @@ fn test_socketpair_read() {
533512
// This is to test whether flag that we don't register won't trigger notification.
534513
fn test_no_notification_for_unregister_flag() {
535514
// Create an epoll instance.
536-
let epfd = unsafe { libc::epoll_create1(0) };
537-
assert_ne!(epfd, -1);
515+
let epfd = errno_result(unsafe { libc::epoll_create1(0) }).unwrap();
538516

539517
// Create a socketpair instance.
540518
let mut fds = [-1, -1];
541-
let res = unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) };
542-
assert_eq!(res, 0);
519+
errno_check(unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) });
543520

544521
// Register fd[0] with EPOLLOUT|EPOLLET.
545522
let mut ev = libc::epoll_event {
@@ -565,8 +542,7 @@ fn test_no_notification_for_unregister_flag() {
565542

566543
fn test_epoll_wait_maxevent_zero() {
567544
// Create an epoll instance.
568-
let epfd = unsafe { libc::epoll_create1(0) };
569-
assert_ne!(epfd, -1);
545+
let epfd = errno_result(unsafe { libc::epoll_create1(0) }).unwrap();
570546
// It is ok to use a dangling pointer here because it will error out before the
571547
// pointer actually gets accessed.
572548
let array_ptr = std::ptr::without_provenance_mut::<libc::epoll_event>(0x100);
@@ -578,13 +554,11 @@ fn test_epoll_wait_maxevent_zero() {
578554

579555
fn test_socketpair_epollerr() {
580556
// Create an epoll instance.
581-
let epfd = unsafe { libc::epoll_create1(0) };
582-
assert_ne!(epfd, -1);
557+
let epfd = errno_result(unsafe { libc::epoll_create1(0) }).unwrap();
583558

584559
// Create a socketpair instance.
585560
let mut fds = [-1, -1];
586-
let res = unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) };
587-
assert_eq!(res, 0);
561+
errno_check(unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) });
588562

589563
// Write to fd[0]
590564
let data = "abcde".as_bytes().as_ptr();
@@ -593,8 +567,7 @@ fn test_socketpair_epollerr() {
593567

594568
// Close fds[1].
595569
// EPOLLERR will be triggered if we close peer fd that still has data in its read buffer.
596-
let res = unsafe { libc::close(fds[1]) };
597-
assert_eq!(res, 0);
570+
errno_check(unsafe { libc::close(fds[1]) });
598571

599572
// Register fd[1] with EPOLLIN|EPOLLOUT|EPOLLET|EPOLLRDHUP
600573
let mut ev = libc::epoll_event {
@@ -617,13 +590,11 @@ fn test_socketpair_epollerr() {
617590
// epoll can lose events if they don't fit in the output buffer.
618591
fn test_epoll_lost_events() {
619592
// Create an epoll instance.
620-
let epfd = unsafe { libc::epoll_create1(0) };
621-
assert_ne!(epfd, -1);
593+
let epfd = errno_result(unsafe { libc::epoll_create1(0) }).unwrap();
622594

623595
// Create a socketpair instance.
624596
let mut fds = [-1, -1];
625-
let res = unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) };
626-
assert_eq!(res, 0);
597+
errno_check(unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) });
627598

628599
// Register both fd to the same epoll instance.
629600
let mut ev = libc::epoll_event { events: EPOLL_IN_OUT_ET, u64: fds[0] as u64 };
@@ -649,13 +620,12 @@ fn test_epoll_lost_events() {
649620
// Related discussion in https://github.com/rust-lang/miri/pull/3818#discussion_r1720679440.
650621
fn test_ready_list_fetching_logic() {
651622
// Create an epoll instance.
652-
let epfd = unsafe { libc::epoll_create1(0) };
653-
assert_ne!(epfd, -1);
623+
let epfd = errno_result(unsafe { libc::epoll_create1(0) }).unwrap();
654624

655625
// Create two eventfd instances.
656626
let flags = libc::EFD_NONBLOCK | libc::EFD_CLOEXEC;
657-
let fd0 = unsafe { libc::eventfd(0, flags) };
658-
let fd1 = unsafe { libc::eventfd(0, flags) };
627+
let fd0 = errno_result(unsafe { libc::eventfd(0, flags) }).unwrap();
628+
let fd1 = errno_result(unsafe { libc::eventfd(0, flags) }).unwrap();
659629

660630
// Register both fd to the same epoll instance. At this point, both of them are on the ready list.
661631
let mut ev = libc::epoll_event { events: EPOLL_IN_OUT_ET, u64: fd0 as u64 };
@@ -666,8 +636,7 @@ fn test_ready_list_fetching_logic() {
666636
assert_eq!(res, 0);
667637

668638
// Close fd0 so the first entry in the ready list will be empty.
669-
let res = unsafe { libc::close(fd0) };
670-
assert_eq!(res, 0);
639+
errno_check(unsafe { libc::close(fd0) });
671640

672641
// Notification for fd1 should be returned.
673642
let expected_event1 = u32::try_from(libc::EPOLLOUT).unwrap();
@@ -679,8 +648,7 @@ fn test_ready_list_fetching_logic() {
679648
// (The docs say loops cause EINVAL, but experiments show it is EFAULT.)
680649
fn test_epoll_ctl_epfd_equal_fd() {
681650
// Create an epoll instance.
682-
let epfd = unsafe { libc::epoll_create1(0) };
683-
assert_ne!(epfd, -1);
651+
let epfd = errno_result(unsafe { libc::epoll_create1(0) }).unwrap();
684652

685653
let array_ptr = std::ptr::without_provenance_mut::<libc::epoll_event>(0x100);
686654
let res = unsafe { libc::epoll_ctl(epfd, libc::EPOLL_CTL_ADD, epfd, array_ptr) };
@@ -699,8 +667,7 @@ fn test_epoll_ctl_notification() {
699667

700668
// Create a socketpair instance.
701669
let mut fds = [-1, -1];
702-
let res = unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) };
703-
assert_eq!(res, 0);
670+
errno_check(unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) });
704671

705672
// Register one side of the socketpair with epoll.
706673
let mut ev = libc::epoll_event { events: EPOLL_IN_OUT_ET, u64: fds[0] as u64 };
@@ -736,11 +703,10 @@ fn test_epoll_ctl_notification() {
736703
fn test_issue_3858() {
737704
// Create an eventfd instance.
738705
let flags = libc::EFD_NONBLOCK | libc::EFD_CLOEXEC;
739-
let fd = unsafe { libc::eventfd(0, flags) };
706+
let fd = errno_result(unsafe { libc::eventfd(0, flags) }).unwrap();
740707

741708
// Create an epoll instance.
742-
let epfd = unsafe { libc::epoll_create1(0) };
743-
assert_ne!(epfd, -1);
709+
let epfd = errno_result(unsafe { libc::epoll_create1(0) }).unwrap();
744710

745711
// Register eventfd with EPOLLIN | EPOLLET.
746712
let mut ev = libc::epoll_event {
@@ -755,8 +721,7 @@ fn test_issue_3858() {
755721
assert_ne!(newfd, -1);
756722

757723
// Close the old epoll instance, so the new FD is now the only FD.
758-
let res = unsafe { libc::close(epfd) };
759-
assert_eq!(res, 0);
724+
errno_check(unsafe { libc::close(epfd) });
760725

761726
// Write to the eventfd instance.
762727
let sized_8_data: [u8; 8] = 1_u64.to_ne_bytes();
@@ -772,8 +737,7 @@ fn test_issue_4374() {
772737

773738
// Create a socketpair instance, make it non-blocking.
774739
let mut fds = [-1, -1];
775-
let res = unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) };
776-
assert_eq!(res, 0);
740+
errno_check(unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) });
777741
assert_eq!(unsafe { libc::fcntl(fds[0], libc::F_SETFL, libc::O_NONBLOCK) }, 0);
778742
assert_eq!(unsafe { libc::fcntl(fds[1], libc::F_SETFL, libc::O_NONBLOCK) }, 0);
779743

@@ -805,8 +769,7 @@ fn test_issue_4374_reads() {
805769

806770
// Create a socketpair instance, make it non-blocking.
807771
let mut fds = [-1, -1];
808-
let res = unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) };
809-
assert_eq!(res, 0);
772+
errno_check(unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) });
810773
assert_eq!(unsafe { libc::fcntl(fds[0], libc::F_SETFL, libc::O_NONBLOCK) }, 0);
811774
assert_eq!(unsafe { libc::fcntl(fds[1], libc::F_SETFL, libc::O_NONBLOCK) }, 0);
812775

0 commit comments

Comments
 (0)