Lines 65-70
__FBSDID("$FreeBSD$");
Link Here
|
65 |
#include <sys/vnode.h> |
65 |
#include <sys/vnode.h> |
66 |
#include <sys/wait.h> |
66 |
#include <sys/wait.h> |
67 |
#include <sys/cpuset.h> |
67 |
#include <sys/cpuset.h> |
|
|
68 |
#include <sys/poll.h> |
68 |
|
69 |
|
69 |
#include <security/mac/mac_framework.h> |
70 |
#include <security/mac/mac_framework.h> |
70 |
|
71 |
|
Lines 567-572
select_out:
Link Here
|
567 |
} |
568 |
} |
568 |
|
569 |
|
569 |
int |
570 |
int |
|
|
571 |
linux_ppoll(struct thread *td, struct linux_ppoll_args *pargs) |
572 |
{ |
573 |
struct l_timespec lts; |
574 |
struct timeval tv, *tvp, tv0, tv1; |
575 |
struct poll_args pa; |
576 |
sigset_t usigmask, *usigmaskp; |
577 |
l_sigset_t lsigmask; |
578 |
int error, retval, mss, msns; |
579 |
|
580 |
/* Get the time */ |
581 |
if (pargs->timeout_ts != NULL) |
582 |
{ |
583 |
error = copyin(pargs->timeout_ts, <s, sizeof(lts)); |
584 |
if (error != 0) |
585 |
return (error); |
586 |
|
587 |
TIMESPEC_TO_TIMEVAL(&tv, <s); |
588 |
if (itimerfix(&tv)) |
589 |
return (EINVAL); |
590 |
|
591 |
/* Mark the time before the call */ |
592 |
microtime(&tv0); |
593 |
tvp = &tv; |
594 |
} else |
595 |
tvp = NULL; |
596 |
|
597 |
/* Get the sigmask */ |
598 |
if (pargs->sigmask != NULL) { |
599 |
error = copyin(pargs->sigmask, &lsigmask, sizeof(lsigmask)); |
600 |
if (error) |
601 |
return (error); |
602 |
linux_to_bsd_sigset(&lsigmask, &usigmask); |
603 |
usigmaskp = &usigmask; |
604 |
} else |
605 |
usigmaskp = NULL; |
606 |
|
607 |
/* Set the sigmask */ |
608 |
error = kern_sigprocmask (td, SIG_SETMASK, usigmaskp, &td->td_oldsigmask, 0); |
609 |
if (error) |
610 |
return (error); |
611 |
|
612 |
pa.fds = pargs->fds; |
613 |
pa.nfds = pargs->nfds; |
614 |
|
615 |
/* Linux's ppoll allows NULL timeout which is translated to FreeBSD's INFTIM (-1) */ |
616 |
if (tvp==NULL) |
617 |
pa.timeout = INFTIM; |
618 |
else |
619 |
{ |
620 |
mss = tvp->tv_sec * 1000; |
621 |
msns = tvp->tv_usec / 1000; |
622 |
|
623 |
/* |
624 |
* Handling the multiplication and addition overflow. |
625 |
* If it happens, assing pa.timeout the INT_MAX value |
626 |
*/ |
627 |
if (mss/1000 == tvp->tv_sec) { |
628 |
pa.timeout = mss + msns; |
629 |
if ( pa.timeout < 0) |
630 |
pa.timeout = INT_MAX; |
631 |
} else |
632 |
pa.timeout = INT_MAX; |
633 |
} |
634 |
|
635 |
/* |
636 |
* Ensure that the td_oldsigmask is restored by ast() |
637 |
* when returns to user mode and that the TDP_OLDMASK |
638 |
* is cleared |
639 |
*/ |
640 |
td->td_pflags |= TDP_OLDMASK; |
641 |
thread_lock(td); |
642 |
td->td_flags |= TDF_ASTPENDING; |
643 |
thread_unlock(td); |
644 |
|
645 |
/* call sys_poll */ |
646 |
retval = sys_poll(td, &pa); |
647 |
|
648 |
if (retval == 0 && pargs->timeout_ts) { |
649 |
if (td->td_retval[0]) { |
650 |
/* |
651 |
* Compute how much time was left of the timeout, |
652 |
* by subtracting the current time and the time |
653 |
* before we started the call, and subtracting |
654 |
* that result from the user-supplied value. |
655 |
*/ |
656 |
microtime(&tv1); |
657 |
timevalsub(&tv1, &tv0); |
658 |
timevalsub(&tv, &tv1); |
659 |
if (tv.tv_sec < 0) |
660 |
timevalclear(&tv); |
661 |
} else |
662 |
timevalclear(&tv); |
663 |
|
664 |
TIMEVAL_TO_TIMESPEC(&tv, <s); |
665 |
|
666 |
error = copyout(<s, pargs->timeout_ts, sizeof(lts)); |
667 |
if (error) |
668 |
return (error); |
669 |
} |
670 |
return retval; |
671 |
} |
672 |
|
673 |
int |
570 |
linux_mremap(struct thread *td, struct linux_mremap_args *args) |
674 |
linux_mremap(struct thread *td, struct linux_mremap_args *args) |
571 |
{ |
675 |
{ |
572 |
struct munmap_args /* { |
676 |
struct munmap_args /* { |