Date: Sun, 12 Oct 2014 13:47:56 +0000 From: bugzilla-noreply@freebsd.org To: freebsd-emulation@FreeBSD.org Subject: [Bug 192842] [patch][linux] linux_ppoll syscall required by linux apps that use pulseaudio (on linux_base-f20) Message-ID: <bug-192842-4075-dbntnqAVY4@https.bugs.freebsd.org/bugzilla/> In-Reply-To: <bug-192842-4075@https.bugs.freebsd.org/bugzilla/> References: <bug-192842-4075@https.bugs.freebsd.org/bugzilla/>
next in thread | previous in thread | raw e-mail | index | archive | help
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=192842 Mateusz Guzik <mjg@FreeBSD.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |mjg@FreeBSD.org --- Comment #6 from Mateusz Guzik <mjg@FreeBSD.org> --- +linux_ppoll(struct thread *td, struct linux_ppoll_args *pargs) +{ + struct l_timespec lts; + struct timeval tv, *tvp, tv0, tv1; + struct poll_args pa; + sigset_t usigmask, *usigmaskp; + l_sigset_t lsigmask; + int error, retval, mss, msns; error and retval? + + /* Get the time */ + if (pargs->timeout_ts != NULL) + { style + error = copyin(pargs->timeout_ts, <s, sizeof(lts)); + if (error != 0) + return (error); + + TIMESPEC_TO_TIMEVAL(&tv, <s); + if (itimerfix(&tv)) + return (EINVAL); + + /* Mark the time before the call */ + microtime(&tv0); + tvp = &tv; + } else + tvp = NULL; + + /* Get the sigmask */ + if (pargs->sigmask != NULL) { + error = copyin(pargs->sigmask, &lsigmask, sizeof(lsigmask)); + if (error) + return (error); + linux_to_bsd_sigset(&lsigmask, &usigmask); + usigmaskp = &usigmask; + } else + usigmaskp = NULL; + + /* Set the sigmask */ + error = kern_sigprocmask (td, SIG_SETMASK, usigmaskp, &td->td_oldsigmask, 0); + if (error) + return (error); + + pa.fds = pargs->fds; + pa.nfds = pargs->nfds; + + /* Linux's ppoll allows NULL timeout which is translated to FreeBSD's INFTIM (-1) */ + if (tvp==NULL) + pa.timeout = INFTIM; + else + { style + mss = tvp->tv_sec * 1000; + msns = tvp->tv_usec / 1000; + + /* + * Handling the multiplication and addition overflow. + * If it happens, assing pa.timeout the INT_MAX value + */ + if (mss/1000 == tvp->tv_sec) { + pa.timeout = mss + msns; + if ( pa.timeout < 0) + pa.timeout = INT_MAX; + } else + pa.timeout = INT_MAX; + } + + /* + * Ensure that the td_oldsigmask is restored by ast() + * when returns to user mode and that the TDP_OLDMASK + * is cleared + */ + td->td_pflags |= TDP_OLDMASK; + thread_lock(td); + td->td_flags |= TDF_ASTPENDING; + thread_unlock(td); Why was not this done immediately after kern_sigprocmask? Also, this would benefit from kern_ppoll helper. Given that pselect has similar code, maybe an additional helper should be introduced. + + /* call sys_poll */ + retval = sys_poll(td, &pa); + + if (retval == 0 && pargs->timeout_ts) { + if (td->td_retval[0]) { + /* + * Compute how much time was left of the timeout, + * by subtracting the current time and the time + * before we started the call, and subtracting + * that result from the user-supplied value. + */ + microtime(&tv1); + timevalsub(&tv1, &tv0); + timevalsub(&tv, &tv1); + if (tv.tv_sec < 0) + timevalclear(&tv); + } else + timevalclear(&tv); + + TIMEVAL_TO_TIMESPEC(&tv, <s); + + error = copyout(<s, pargs->timeout_ts, sizeof(lts)); + if (error) + return (error); + } + return retval; +} + +int -- You are receiving this mail because: You are the assignee for the bug.
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?bug-192842-4075-dbntnqAVY4>