@@ -39,14 +39,16 @@ pub fn write(fd: usize, buffer: &[u8]) -> Result<usize, SyscallError> {
39
39
. get_handle ( fd)
40
40
. ok_or ( SyscallError :: EBADFD ) ?;
41
41
42
- if handle
43
- . flags
44
- . intersects ( OpenFlags :: O_WRONLY | OpenFlags :: O_RDWR )
45
- {
46
- Ok ( handle. write ( buffer) ?)
47
- } else {
48
- Err ( SyscallError :: EACCES )
49
- }
42
+ // FIXME(heck for xeyes): fnctl should update the open flags!
43
+ //
44
+ // if handle
45
+ // .flags
46
+ // .intersects(OpenFlags::O_WRONLY | OpenFlags::O_RDWR)
47
+ // {
48
+ Ok ( handle. write ( buffer) ?)
49
+ // } else {
50
+ // Err(SyscallError::EACCES)
51
+ // }
50
52
}
51
53
52
54
#[ syscall]
@@ -528,25 +530,8 @@ pub fn link(src_path: &Path, dest_path: &Path) -> Result<usize, SyscallError> {
528
530
Ok ( 0 )
529
531
}
530
532
531
- #[ syscall]
532
- pub fn poll (
533
- fds : & mut [ PollFd ] ,
534
- // TODO: Use the provided timeout.
535
- _timeout : & TimeSpec ,
536
- sigmask : usize ,
537
- ) -> Result < usize , SyscallError > {
538
- if fds. len ( ) == 0 {
539
- // nothing to do.
540
- return Ok ( 0x00 ) ;
541
- }
542
-
533
+ fn do_poll ( fds : & mut [ PollFd ] , timeout : Option < & TimeSpec > ) -> Result < usize , SyscallError > {
543
534
let current_task = scheduler:: get_scheduler ( ) . current_task ( ) ;
544
- let signals = current_task. signals ( ) ;
545
-
546
- let mut old_mask = 0 ;
547
-
548
- // Update the signal mask.
549
- signals. set_mask ( SigProcMask :: Set , Some ( sigmask as u64 ) , Some ( & mut old_mask) ) ;
550
535
551
536
let mut poll_table = PollTable :: default ( ) ;
552
537
let mut n = 0 ;
@@ -570,7 +555,7 @@ pub fn poll(
570
555
571
556
let ready: PollEventFlags = handle. inode ( ) . poll ( None ) ?. into ( ) ;
572
557
573
- if ready . contains ( fd. events ) {
558
+ if ! ( ready & fd. events ) . is_empty ( ) {
574
559
// The registered event is ready; increment the number of ready events
575
560
// and update revents mask for this event.
576
561
fd. revents = ready & fd. events ;
@@ -589,6 +574,56 @@ pub fn poll(
589
574
return Ok ( n) ;
590
575
}
591
576
577
+ // Start the timer if timeout specified, if not, we can block indefinitely.
578
+ if let Some ( timeout) = timeout {
579
+ // If the timeout is zero, then we have to return without blocking.
580
+ if timeout. tv_nsec == 0 && timeout. tv_sec == 0 {
581
+ return Ok ( 0 ) ;
582
+ }
583
+ }
584
+
585
+ crate :: unwind:: unwind_stack_trace ( ) ;
586
+
587
+ ' search: loop {
588
+ // Wait till one of the file descriptor to be ready.
589
+ scheduler:: get_scheduler ( ) . inner . await_io ( ) ?;
590
+
591
+ for ( handle, index) in refds. iter ( ) {
592
+ let pollfd = & mut fds[ * index] ;
593
+ let ready: PollEventFlags = handle. inode ( ) . poll ( None ) ?. into ( ) ;
594
+
595
+ if !( ready & pollfd. events ) . is_empty ( ) {
596
+ pollfd. revents = ready & pollfd. events ;
597
+ break ' search Ok ( 1 ) ;
598
+ }
599
+ }
600
+ }
601
+ }
602
+
603
+ #[ syscall]
604
+ pub fn poll ( fds : & mut [ PollFd ] , timeout : usize , sigmask : usize ) -> Result < usize , SyscallError > {
605
+ // Nothing to poll on.
606
+ if fds. len ( ) == 0 {
607
+ return Ok ( 0 ) ;
608
+ }
609
+
610
+ // The timeout can be NULL.
611
+ let timeout = if timeout != 0x00 {
612
+ Some ( crate :: utils:: validate_ptr ( timeout as * const TimeSpec ) . ok_or ( SyscallError :: EINVAL ) ?)
613
+ } else {
614
+ None
615
+ } ;
616
+
617
+ let current_task = scheduler:: get_scheduler ( ) . current_task ( ) ;
618
+ let signals = current_task. signals ( ) ;
619
+
620
+ let mut old_mask = 0 ;
621
+
622
+ // Update the signal mask.
623
+ signals. set_mask ( SigProcMask :: Set , Some ( sigmask as u64 ) , Some ( & mut old_mask) ) ;
624
+
625
+ let n = do_poll ( fds, timeout) ?;
626
+
592
627
// Restore the orignal signal mask.
593
628
signals. set_mask ( SigProcMask :: Set , Some ( old_mask) , None ) ;
594
629
Ok ( n)
0 commit comments