From 32bfac2fa58c815d4f58ac8ce3153e7f3a2be791 Mon Sep 17 00:00:00 2001 From: myub <1067852565@qq.com> Date: Wed, 26 Aug 2020 01:02:42 -0700 Subject: [PATCH 1/6] add async select --- linux-object/src/process.rs | 6 ++ linux-object/src/time.rs | 9 ++ linux-syscall/Cargo.toml | 1 + linux-syscall/src/file/poll.rs | 179 ++++++++++++++++++++++++++++++++- linux-syscall/src/lib.rs | 7 +- 5 files changed, 199 insertions(+), 3 deletions(-) diff --git a/linux-object/src/process.rs b/linux-object/src/process.rs index aede3d861..8f9fa1696 100644 --- a/linux-object/src/process.rs +++ b/linux-object/src/process.rs @@ -305,6 +305,12 @@ impl LinuxProcess { inner.files.get(&fd).cloned().ok_or(LxError::EBADF) } + /// + pub fn get_files(&self) -> LxResult>> { + let inner = self.inner.lock(); + Ok(inner.files.clone()) + } + /// Close file descriptor `fd`. pub fn close_file(&self, fd: FileDesc) -> LxResult { let mut inner = self.inner.lock(); diff --git a/linux-object/src/time.rs b/linux-object/src/time.rs index fbea871a4..6861abede 100644 --- a/linux-object/src/time.rs +++ b/linux-object/src/time.rs @@ -30,6 +30,10 @@ impl TimeVal { pub fn now() -> TimeVal { TimeSpec::now().into() } + /// to msec + pub fn to_msec(&self) -> usize { + self.sec * 1_000 + self.usec / 1_000 + } } impl TimeSpec { @@ -54,6 +58,11 @@ impl TimeSpec { inode.set_metadata(&metadata).ok(); } } + + /// to msec + pub fn to_msec(&self) -> usize { + self.sec * 1_000 + self.nsec / 1_000_000 + } } impl Into for TimeSpec { diff --git a/linux-syscall/Cargo.toml b/linux-syscall/Cargo.toml index cd2c1a477..05683d2cd 100644 --- a/linux-syscall/Cargo.toml +++ b/linux-syscall/Cargo.toml @@ -17,3 +17,4 @@ linux-object = { path = "../linux-object" } kernel-hal = { path = "../kernel-hal" } rcore-fs = { git = "https://github.com/rcore-os/rcore-fs", rev = "517af47" } lazy_static = { version = "1.4", features = ["spin_no_std"] } +bitvec = { version = "0.17", default-features = false, features = ["alloc"] } diff --git a/linux-syscall/src/file/poll.rs b/linux-syscall/src/file/poll.rs index 5da278431..3802dc9b1 100644 --- a/linux-syscall/src/file/poll.rs +++ b/linux-syscall/src/file/poll.rs @@ -7,7 +7,9 @@ use super::*; use alloc::boxed::Box; use alloc::vec::Vec; +use bitvec::prelude::{BitVec, Lsb0}; use core::future::Future; +use core::mem::size_of; use core::pin::Pin; use core::task::{Context, Poll}; use linux_object::fs::FileDesc; @@ -96,11 +98,119 @@ impl Syscall<'_> { 1 << 31 // infinity } else { let timeout = timeout.read().unwrap(); - timeout.sec * 1_000 + timeout.nsec / 1_000_000 + timeout.to_msec() }; self.sys_poll(ufds, nfds, timeout_msecs as usize).await } + + /// + pub async fn sys_select( + &mut self, + nfds: usize, + read: UserInOutPtr, + write: UserInOutPtr, + err: UserInOutPtr, + timeout: UserInPtr, + ) -> SysResult { + info!( + "select: nfds: {}, read: {:?}, write: {:?}, err: {:?}, timeout: {:?}", + nfds, read, write, err, timeout + ); + if nfds as u64 == 0 { + return Ok(0); + } + let mut read_fds = FdSet::new(read, nfds)?; + let mut write_fds = FdSet::new(write, nfds)?; + let mut err_fds = FdSet::new(err, nfds)?; + + let timeout_msecs = if !timeout.is_null() { + let timeout = timeout.read()?; + timeout.to_msec() + } else { + // infinity + 1 << 31 + }; + let begin_time_ms = TimeVal::now().to_msec(); + + #[must_use = "future does nothing unless polled/`await`-ed"] + struct SelectFuture<'a> { + read_fds: &'a mut FdSet, + write_fds: &'a mut FdSet, + err_fds: &'a mut FdSet, + timeout_msecs: usize, + begin_time_ms: usize, + syscall: &'a Syscall<'a>, + } + + impl<'a> Future for SelectFuture<'a> { + type Output = SysResult; + + fn poll(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll { + let files = self.syscall.linux_process().get_files()?; + + let mut events = 0; + for (&fd, file_like) in files.iter() { + // if fd >= nfds { + // continue; + // } + if !self.err_fds.contains(fd) + && !self.read_fds.contains(fd) + && !self.write_fds.contains(fd) + { + continue; + } + let mut fut = Box::pin(file_like.async_poll()); + let status = match fut.as_mut().poll(cx) { + Poll::Ready(Ok(ret)) => ret, + Poll::Ready(Err(err)) => return Poll::Ready(Err(err)), + Poll::Pending => continue, + }; + if status.error && self.err_fds.contains(fd) { + self.err_fds.set(fd); + events += 1; + } + if status.read && self.read_fds.contains(fd) { + self.read_fds.set(fd); + events += 1; + } + if status.write && self.write_fds.contains(fd) { + self.write_fds.set(fd); + events += 1; + } + } + + // some event happens, so evoke the process + if events > 0 { + return Poll::Ready(Ok(events)); + } + + if self.timeout_msecs == 0 { + // no timeout, return now; + return Poll::Ready(Ok(0)); + } + + let current_time_ms = TimeVal::now().to_msec(); + // infinity check + if self.timeout_msecs < (1 << 31) + && current_time_ms - self.begin_time_ms > self.timeout_msecs as usize + { + return Poll::Ready(Ok(0)); + } + + Poll::Pending + } + } + let future = SelectFuture { + read_fds: &mut read_fds, + write_fds: &mut write_fds, + err_fds: &mut err_fds, + timeout_msecs, + begin_time_ms, + syscall: self, + }; + future.await + } } #[repr(C)] @@ -125,3 +235,70 @@ bitflags! { const INVAL = 0x0020; } } + +/// +const FD_PER_ITEM: usize = 8 * size_of::(); +/// +const MAX_FDSET_SIZE: usize = 1024 / FD_PER_ITEM; + +/// +struct FdSet { + /// + addr: UserInOutPtr, + /// + origin: BitVec, +} + +impl FdSet { + /// Initialize a `FdSet` from pointer and number of fds + /// Check if the array is large enough + fn new(mut addr: UserInOutPtr, nfds: usize) -> Result { + if addr.is_null() { + Ok(FdSet { + addr, + origin: BitVec::new(), + }) + } else { + let len = (nfds + FD_PER_ITEM - 1) / FD_PER_ITEM; + if len > MAX_FDSET_SIZE { + return Err(LxError::EINVAL); + } + let slice = addr.read_array(len)?; + + // save the fdset, and clear it + let origin = BitVec::from_vec(slice); + let mut vec0 = Vec::::new(); + vec0.resize(len, 0); + addr.write_array(&vec0)?; + Ok(FdSet { addr, origin }) + } + } + + /// Try to set fd in `FdSet` + /// Return true when `FdSet` is valid, and false when `FdSet` is bad (i.e. null pointer) + /// Fd should be less than nfds + fn set(&mut self, fd: FileDesc) -> bool { + let fd: usize = fd.into(); + if self.origin.is_empty() { + return false; + } + self.origin.set(fd, true); + let vec: Vec = self.origin.clone().into(); + if let Ok(_) = self.addr.write_array(&vec) { + return true; + } else { + return false; + } + } + + /// Check to see whether `fd` is in original `FdSet` + /// Fd should be less than nfds + fn contains(&self, fd: FileDesc) -> bool { + let fd: usize = fd.into(); + if fd < self.origin.len() { + self.origin[fd] + } else { + false + } + } +} diff --git a/linux-syscall/src/lib.rs b/linux-syscall/src/lib.rs index 601a751e7..9e806dd6b 100644 --- a/linux-syscall/src/lib.rs +++ b/linux-syscall/src/lib.rs @@ -244,7 +244,7 @@ impl Syscall<'_> { #[cfg(target_arch = "x86_64")] /// syscall specified for x86_64 async fn x86_64_syscall(&mut self, sys_type: Sys, args: [usize; 6]) -> SysResult { - let [a0, a1, a2, _a3, _a4, _a5] = args; + let [a0, a1, a2, a3, a4, _a5] = args; match sys_type { Sys::OPEN => self.sys_open(a0.into(), a1, a2), Sys::STAT => self.sys_stat(a0.into(), a1.into()), @@ -252,7 +252,10 @@ impl Syscall<'_> { Sys::POLL => self.sys_poll(a0.into(), a1, a2).await, Sys::ACCESS => self.sys_access(a0.into(), a1), Sys::PIPE => self.sys_pipe(a0.into()), - // Sys::SELECT => self.sys_select(a0, a1.into(), a2.into(), a3.into(), a4.into()), + Sys::SELECT => { + self.sys_select(a0, a1.into(), a2.into(), a3.into(), a4.into()) + .await + } Sys::DUP2 => self.sys_dup2(a0.into(), a1.into()), // Sys::ALARM => self.unimplemented("alarm", Ok(0)), Sys::FORK => self.sys_fork(), From 31fe6fb853628c56e75a29b37bb1fe5747f52e41 Mon Sep 17 00:00:00 2001 From: myub <1067852565@qq.com> Date: Wed, 26 Aug 2020 01:49:52 -0700 Subject: [PATCH 2/6] add simple test ( currently time is no available) --- linux-syscall/test/testselect.c | 34 +++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 linux-syscall/test/testselect.c diff --git a/linux-syscall/test/testselect.c b/linux-syscall/test/testselect.c new file mode 100644 index 000000000..59242ef9f --- /dev/null +++ b/linux-syscall/test/testselect.c @@ -0,0 +1,34 @@ +#include +#include +#include +#include +#include + +int +main(void) +{ + fd_set rfds; + struct timeval tv; + int retval; + + /* Watch stdin (fd 0) to see when it has input. */ + FD_ZERO(&rfds); + FD_SET(0, &rfds); + + /* Wait up to five seconds. */ + tv.tv_sec = 5; + tv.tv_usec = 0; + + retval = select(1, &rfds, NULL, NULL, &tv); + /* Don't rely on the value of tv now! */ + + if (retval == -1) + perror("select()"); + else if (retval) + printf("Data is available now.\n"); + /* FD_ISSET(0, &rfds) will be true. */ + else + printf("No data within five seconds.\n"); + + exit(EXIT_SUCCESS); +} \ No newline at end of file From 1a50149efd28285f7218bf7e640d54889342975c Mon Sep 17 00:00:00 2001 From: myub <1067852565@qq.com> Date: Wed, 26 Aug 2020 01:56:33 -0700 Subject: [PATCH 3/6] add pselect interface --- linux-syscall/src/file/poll.rs | 13 +++++++++++++ linux-syscall/src/lib.rs | 5 ++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/linux-syscall/src/file/poll.rs b/linux-syscall/src/file/poll.rs index 3802dc9b1..77d60f589 100644 --- a/linux-syscall/src/file/poll.rs +++ b/linux-syscall/src/file/poll.rs @@ -104,6 +104,19 @@ impl Syscall<'_> { self.sys_poll(ufds, nfds, timeout_msecs as usize).await } + /// + pub async fn sys_pselect6( + &mut self, + nfds: usize, + read: UserInOutPtr, + write: UserInOutPtr, + err: UserInOutPtr, + timeout: UserInPtr, + _sigset: usize, + ) -> SysResult { + self.sys_select(nfds, read, write, err, timeout).await + } + /// pub async fn sys_select( &mut self, diff --git a/linux-syscall/src/lib.rs b/linux-syscall/src/lib.rs index 9e806dd6b..db42e4698 100644 --- a/linux-syscall/src/lib.rs +++ b/linux-syscall/src/lib.rs @@ -114,7 +114,10 @@ impl Syscall<'_> { } // io multiplexing - // Sys::PSELECT6 => self.sys_pselect6(a0, a1.into(), a2.into(), a3.into(), a4.into(), a5.into()), + Sys::PSELECT6 => { + self.sys_pselect6(a0, a1.into(), a2.into(), a3.into(), a4.into(), a5) + .await + } Sys::PPOLL => self.sys_ppoll(a0.into(), a1, a2.into()).await, // ignore sigmask // Sys::EPOLL_CREATE1 => self.sys_epoll_create1(a0), // Sys::EPOLL_CTL => self.sys_epoll_ctl(a0, a1, a2, a3.into()), From dfaa472146c460b62cee043ed513e1e3f2a3b50d Mon Sep 17 00:00:00 2001 From: myub <1067852565@qq.com> Date: Wed, 26 Aug 2020 03:14:33 -0700 Subject: [PATCH 4/6] update doc --- linux-object/src/process.rs | 2 +- linux-syscall/src/file/poll.rs | 25 ++++++++++++------------- linux-syscall/test/testselect.c | 2 +- 3 files changed, 14 insertions(+), 15 deletions(-) diff --git a/linux-object/src/process.rs b/linux-object/src/process.rs index 8f9fa1696..efaf00321 100644 --- a/linux-object/src/process.rs +++ b/linux-object/src/process.rs @@ -305,7 +305,7 @@ impl LinuxProcess { inner.files.get(&fd).cloned().ok_or(LxError::EBADF) } - /// + /// get all files pub fn get_files(&self) -> LxResult>> { let inner = self.inner.lock(); Ok(inner.files.clone()) diff --git a/linux-syscall/src/file/poll.rs b/linux-syscall/src/file/poll.rs index 77d60f589..aa6b96bbc 100644 --- a/linux-syscall/src/file/poll.rs +++ b/linux-syscall/src/file/poll.rs @@ -1,8 +1,7 @@ //! IO Multiplex operations //! -//! - select4 +//! - select, pselect //! - poll, ppoll -//! - epoll: create, ctl, wait use super::*; use alloc::boxed::Box; @@ -104,7 +103,7 @@ impl Syscall<'_> { self.sys_poll(ufds, nfds, timeout_msecs as usize).await } - /// + /// similar to select, but have sigmask argument pub async fn sys_pselect6( &mut self, nfds: usize, @@ -117,7 +116,10 @@ impl Syscall<'_> { self.sys_select(nfds, read, write, err, timeout).await } + /// allow a program to monitor multiple file descriptors, + /// waiting until one or more of the file descriptors become "ready" for some class of I/O operation. /// + /// A file descriptor is considered ready if it is possible to perform the corresponding I/O operation (e.g., read) without blocking. pub async fn sys_select( &mut self, nfds: usize, @@ -164,9 +166,6 @@ impl Syscall<'_> { let mut events = 0; for (&fd, file_like) in files.iter() { - // if fd >= nfds { - // continue; - // } if !self.err_fds.contains(fd) && !self.read_fds.contains(fd) && !self.write_fds.contains(fd) @@ -249,16 +248,16 @@ bitflags! { } } -/// +/// fd size per item const FD_PER_ITEM: usize = 8 * size_of::(); -/// +/// max Fdset size const MAX_FDSET_SIZE: usize = 1024 / FD_PER_ITEM; -/// +/// FdSet data struct for select struct FdSet { - /// + /// input addr, for update Fdset use addr: UserInOutPtr, - /// + /// FdSet bit buffer origin: BitVec, } @@ -298,9 +297,9 @@ impl FdSet { self.origin.set(fd, true); let vec: Vec = self.origin.clone().into(); if let Ok(_) = self.addr.write_array(&vec) { - return true; + true } else { - return false; + false } } diff --git a/linux-syscall/test/testselect.c b/linux-syscall/test/testselect.c index 59242ef9f..27717904b 100644 --- a/linux-syscall/test/testselect.c +++ b/linux-syscall/test/testselect.c @@ -31,4 +31,4 @@ main(void) printf("No data within five seconds.\n"); exit(EXIT_SUCCESS); -} \ No newline at end of file +} From 8d3f121aa0cdcb48e7c35b4507ab3ae921598ee2 Mon Sep 17 00:00:00 2001 From: myub <1067852565@qq.com> Date: Wed, 26 Aug 2020 07:16:39 -0700 Subject: [PATCH 5/6] update test for select and poll --- linux-loader/src/main.rs | 16 ++++++++++ linux-syscall/src/file/poll.rs | 6 +--- linux-syscall/test/testpoll.c | 47 ++++++++++++++++++++++++++++ linux-syscall/test/testselect.c | 54 ++++++++++++++++++++++----------- 4 files changed, 101 insertions(+), 22 deletions(-) create mode 100644 linux-syscall/test/testpoll.c diff --git a/linux-loader/src/main.rs b/linux-loader/src/main.rs index 75abed2e3..cb9e934d8 100644 --- a/linux-loader/src/main.rs +++ b/linux-loader/src/main.rs @@ -82,6 +82,12 @@ mod tests { assert_eq!(test("/bin/busybox").await, 0); } + #[should_panic] + #[async_std::test] + async fn test_entry_wrong() { + assert_eq!(test("/bin/busybos").await, 0); + } + #[async_std::test] async fn test_uname() { assert_eq!(test("/bin/busybox uname -a").await, 0); @@ -200,4 +206,14 @@ mod tests { async fn test_shm() { assert_eq!(test("/bin/testshm1").await, 0); } + + #[async_std::test] + async fn test_select() { + assert_eq!(test("/bin/testselect").await, 0); + } + + #[async_std::test] + async fn test_poll() { + assert_eq!(test("/bin/testpoll").await, 0); + } } diff --git a/linux-syscall/src/file/poll.rs b/linux-syscall/src/file/poll.rs index aa6b96bbc..d704b7467 100644 --- a/linux-syscall/src/file/poll.rs +++ b/linux-syscall/src/file/poll.rs @@ -296,11 +296,7 @@ impl FdSet { } self.origin.set(fd, true); let vec: Vec = self.origin.clone().into(); - if let Ok(_) = self.addr.write_array(&vec) { - true - } else { - false - } + self.addr.write_array(&vec).is_ok() } /// Check to see whether `fd` is in original `FdSet` diff --git a/linux-syscall/test/testpoll.c b/linux-syscall/test/testpoll.c new file mode 100644 index 000000000..6f26848fb --- /dev/null +++ b/linux-syscall/test/testpoll.c @@ -0,0 +1,47 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +int main(int argc, char **argv) +{ + int i; + int ret; + int fd; + unsigned char keys_val; + struct pollfd fds[2]; + int pipefd[2]; + struct timespec ts; + + if (pipe(pipefd) == -1) + { + printf("pipe"); + exit(-1); + } + + fds[0].fd = pipefd[0]; + fds[0].events = POLLIN; + fds[1].fd = pipefd[1]; + fds[1].events = POLLOUT; + + ret = poll(fds, 2, 5000); + assert(ret == 1); + assert(fds[1].revents == POLLOUT); + + write(pipefd[1], "test", strlen("test")); + + ts.tv_sec = 5; + ts.tv_nsec = 0; + + ret = ppoll(fds, 2, &ts, NULL); + assert(ret == 2); + assert(fds[0].revents == POLLIN); + + close(pipefd[0]); + close(pipefd[1]); + return 0; +} \ No newline at end of file diff --git a/linux-syscall/test/testselect.c b/linux-syscall/test/testselect.c index 27717904b..8af3531bd 100644 --- a/linux-syscall/test/testselect.c +++ b/linux-syscall/test/testselect.c @@ -1,34 +1,54 @@ #include #include #include +#include #include #include +#include +#include -int -main(void) +int main(void) { - fd_set rfds; + fd_set rfds, wfds; struct timeval tv; + struct timespec ts; int retval; - /* Watch stdin (fd 0) to see when it has input. */ + int pipefd[2]; + FD_ZERO(&rfds); FD_SET(0, &rfds); - - /* Wait up to five seconds. */ - tv.tv_sec = 5; + tv.tv_sec = 0; tv.tv_usec = 0; + assert(select(1, &rfds, NULL, NULL, &tv) == 0); + assert(!FD_ISSET(0, &rfds)); + + FD_ZERO(&wfds); + FD_SET(1, &wfds); + ts.tv_sec = 5; + ts.tv_nsec = 0; + assert(pselect(2, NULL, &wfds, NULL, &ts, NULL) == 1); + assert(FD_ISSET(1, &wfds)); - retval = select(1, &rfds, NULL, NULL, &tv); - /* Don't rely on the value of tv now! */ + if (pipe(pipefd) == -1) + { + exit(-1); + } + write(pipefd[1], "test", strlen("test")); + + FD_ZERO(&rfds); + FD_SET(pipefd[0], &rfds); + FD_ZERO(&wfds); + FD_SET(pipefd[1], &wfds); + tv.tv_sec = 0; + tv.tv_usec = 0; + retval = select(pipefd[0] + 1, &rfds, &wfds, NULL, &tv); + assert(FD_ISSET(pipefd[0], &rfds)); + assert(FD_ISSET(pipefd[1], &wfds)); - if (retval == -1) - perror("select()"); - else if (retval) - printf("Data is available now.\n"); - /* FD_ISSET(0, &rfds) will be true. */ - else - printf("No data within five seconds.\n"); + assert(retval == 2); - exit(EXIT_SUCCESS); + close(pipefd[0]); + close(pipefd[1]); + exit(EXIT_SUCCESS); } From 8335a7e624a91533839d57ebfa6d8435f7ff63b9 Mon Sep 17 00:00:00 2001 From: myub <1067852565@qq.com> Date: Wed, 26 Aug 2020 17:48:01 -0700 Subject: [PATCH 6/6] add timeout support of poll and select --- linux-syscall/src/file/poll.rs | 36 ++++++++++++++++++++++++++++++++- linux-syscall/test/testpoll.c | 7 +++++++ linux-syscall/test/testselect.c | 3 ++- 3 files changed, 44 insertions(+), 2 deletions(-) diff --git a/linux-syscall/src/file/poll.rs b/linux-syscall/src/file/poll.rs index d704b7467..6084fd896 100644 --- a/linux-syscall/src/file/poll.rs +++ b/linux-syscall/src/file/poll.rs @@ -11,6 +11,8 @@ use core::future::Future; use core::mem::size_of; use core::pin::Pin; use core::task::{Context, Poll}; +use core::time::Duration; +use kernel_hal::timer_set; use linux_object::fs::FileDesc; use linux_object::time::*; @@ -30,9 +32,13 @@ impl Syscall<'_> { #[must_use = "future does nothing unless polled/`await`-ed"] struct PollFuture<'a> { polls: &'a mut Vec, + timeout_msecs: usize, + begin_time_ms: usize, syscall: &'a Syscall<'a>, } + let begin_time_ms = TimeVal::now().to_msec(); + impl<'a> Future for PollFuture<'a> { type Output = SysResult; @@ -72,11 +78,33 @@ impl Syscall<'_> { if events > 0 { return Poll::Ready(Ok(events)); } + + if self.timeout_msecs == 0 { + // no timeout, return now; + return Poll::Ready(Ok(0)); + } else { + let waker = cx.waker().clone(); + timer_set( + Duration::from_millis(self.timeout_msecs as u64), + Box::new(move |_| waker.wake()), + ); + } + + let current_time_ms = TimeVal::now().to_msec(); + // infinity check + if self.timeout_msecs < (1 << 31) + && current_time_ms - self.begin_time_ms >= self.timeout_msecs as usize + { + return Poll::Ready(Ok(0)); + } + Poll::Pending } } let future = PollFuture { polls: &mut polls, + timeout_msecs, + begin_time_ms, syscall: self, }; let result = future.await; @@ -200,12 +228,18 @@ impl Syscall<'_> { if self.timeout_msecs == 0 { // no timeout, return now; return Poll::Ready(Ok(0)); + } else { + let waker = cx.waker().clone(); + timer_set( + Duration::from_millis(self.timeout_msecs as u64), + Box::new(move |_| waker.wake()), + ); } let current_time_ms = TimeVal::now().to_msec(); // infinity check if self.timeout_msecs < (1 << 31) - && current_time_ms - self.begin_time_ms > self.timeout_msecs as usize + && current_time_ms - self.begin_time_ms >= self.timeout_msecs as usize { return Poll::Ready(Ok(0)); } diff --git a/linux-syscall/test/testpoll.c b/linux-syscall/test/testpoll.c index 6f26848fb..775967c8e 100644 --- a/linux-syscall/test/testpoll.c +++ b/linux-syscall/test/testpoll.c @@ -17,12 +17,19 @@ int main(int argc, char **argv) int pipefd[2]; struct timespec ts; + // test poll using pipe if (pipe(pipefd) == -1) { printf("pipe"); exit(-1); } + // test time out + fds[0].fd = 0; + fds[0].events = POLLIN; + ret = poll(fds, 1, 1000); + assert(ret == 0); + fds[0].fd = pipefd[0]; fds[0].events = POLLIN; fds[1].fd = pipefd[1]; diff --git a/linux-syscall/test/testselect.c b/linux-syscall/test/testselect.c index 8af3531bd..9fd537bdc 100644 --- a/linux-syscall/test/testselect.c +++ b/linux-syscall/test/testselect.c @@ -16,9 +16,10 @@ int main(void) int pipefd[2]; + // test time out 1s FD_ZERO(&rfds); FD_SET(0, &rfds); - tv.tv_sec = 0; + tv.tv_sec = 1; tv.tv_usec = 0; assert(select(1, &rfds, NULL, NULL, &tv) == 0); assert(!FD_ISSET(0, &rfds));