Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F140180929
D1104.id2326.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
4 KB
Referenced Files
None
Subscribers
None
D1104.id2326.diff
View Options
Index: sys/kern/sys_generic.c
===================================================================
--- sys/kern/sys_generic.c
+++ sys/kern/sys_generic.c
@@ -97,6 +97,8 @@
u_int);
static int pollscan(struct thread *, struct pollfd *, u_int);
static int pollrescan(struct thread *);
+static int kern_poll(struct thread *, struct pollfd *, u_int,
+ sbintime_t, sbintime_t);
static int selscan(struct thread *, fd_mask **, fd_mask **, int);
static int selrescan(struct thread *, fd_mask **, fd_mask **);
static void selfdalloc(struct thread *, void *);
@@ -1301,30 +1303,12 @@
struct thread *td;
struct poll_args *uap;
{
- struct pollfd *bits;
- struct pollfd smallbits[32];
sbintime_t asbt, precision, rsbt;
- u_int nfds;
- int error;
- size_t ni;
- nfds = uap->nfds;
- if (nfds > maxfilesperproc && nfds > FD_SETSIZE)
- return (EINVAL);
- ni = nfds * sizeof(struct pollfd);
- if (ni > sizeof(smallbits))
- bits = malloc(ni, M_TEMP, M_WAITOK);
- else
- bits = smallbits;
- error = copyin(uap->fds, bits, ni);
- if (error)
- goto done;
precision = 0;
if (uap->timeout != INFTIM) {
- if (uap->timeout < 0) {
- error = EINVAL;
- goto done;
- }
+ if (uap->timeout < 0)
+ return (EINVAL);
if (uap->timeout == 0)
asbt = 0;
else {
@@ -1337,13 +1321,37 @@
}
} else
asbt = -1;
+
+ return (kern_poll(td, uap->fds, uap->nfds, asbt, precision));
+}
+
+static int
+kern_poll(struct thread *td, struct pollfd *fds, u_int nfds,
+ sbintime_t sbt, sbintime_t prec)
+{
+ struct pollfd *bits;
+ struct pollfd smallbits[32];
+ int error;
+ size_t ni;
+
+ if (nfds > maxfilesperproc && nfds > FD_SETSIZE)
+ return (EINVAL);
+ ni = nfds * sizeof(struct pollfd);
+ if (ni > sizeof(smallbits))
+ bits = malloc(ni, M_TEMP, M_WAITOK);
+ else
+ bits = smallbits;
+ error = copyin(fds, bits, ni);
+ if (error)
+ goto done;
+
seltdinit(td);
/* Iterate until the timeout expires or descriptors become ready. */
for (;;) {
error = pollscan(td, bits, nfds);
if (error || td->td_retval[0] != 0)
break;
- error = seltdwait(td, asbt, precision);
+ error = seltdwait(td, sbt, prec);
if (error)
break;
error = pollrescan(td);
@@ -1359,7 +1367,7 @@
if (error == EWOULDBLOCK)
error = 0;
if (error == 0) {
- error = pollout(td, bits, uap->fds, nfds);
+ error = pollout(td, bits, fds, nfds);
if (error)
goto out;
}
@@ -1369,6 +1377,59 @@
return (error);
}
+int
+kern_ppoll(struct thread *td, struct pollfd *fds, u_int nfds,
+ struct timespec *tsp, sigset_t *uset)
+{
+ struct timespec ts;
+ sbintime_t sbt, precision, tmp;
+ time_t over;
+ int error;
+
+ precision = 0;
+ if (tsp != NULL) {
+ if (tsp->tv_sec < 0)
+ return (EINVAL);
+ if (tsp->tv_nsec < 0 || tsp->tv_nsec >= 1000000000)
+ return (EINVAL);
+ if (tsp->tv_sec == 0 && tsp->tv_nsec == 0)
+ sbt = 0;
+ else {
+ ts = *tsp;
+ if (ts.tv_sec > INT32_MAX / 2) {
+ over = ts.tv_sec - INT32_MAX / 2;
+ ts.tv_sec -= over;
+ } else
+ over = 0;
+ tmp = tstosbt(ts);
+ precision = tmp;
+ precision >>= tc_precexp;
+ if (TIMESEL(&sbt, tmp))
+ sbt += tc_tick_sbt;
+ sbt += tmp;
+ }
+ } else
+ sbt = -1;
+
+ if (uset != NULL) {
+ error = kern_sigprocmask(td, SIG_SETMASK, uset,
+ &td->td_oldsigmask, 0);
+ if (error != 0)
+ return (error);
+ td->td_pflags |= TDP_OLDMASK;
+ /*
+ * Make sure that ast() is called on return to
+ * usermode and TDP_OLDMASK is cleared, restoring old
+ * sigmask.
+ */
+ thread_lock(td);
+ td->td_flags |= TDF_ASTPENDING;
+ thread_unlock(td);
+ }
+
+ return (kern_poll(td, fds, nfds, sbt, precision));
+}
+
static int
pollrescan(struct thread *td)
{
Index: sys/sys/syscallsubr.h
===================================================================
--- sys/sys/syscallsubr.h
+++ sys/sys/syscallsubr.h
@@ -46,6 +46,7 @@
struct mbuf;
struct msghdr;
struct msqid_ds;
+struct pollfd;
struct ogetdirentries_args;
struct rlimit;
struct rusage;
@@ -169,6 +170,8 @@
int name, u_long flags);
int kern_pipe(struct thread *td, int fildes[2]);
int kern_pipe2(struct thread *td, int fildes[2], int flags);
+int kern_ppoll(struct thread *td, struct pollfd *fds, u_int nfds,
+ struct timespec *tsp, sigset_t *uset);
int kern_posix_fadvise(struct thread *td, int fd, off_t offset, off_t len,
int advice);
int kern_posix_fallocate(struct thread *td, int fd, off_t offset,
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, Dec 22, 4:28 AM (4 h, 53 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
27135293
Default Alt Text
D1104.id2326.diff (4 KB)
Attached To
Mode
D1104: Split up sys_poll() into a sys_ and kern_ counterparts, add kern_ppoll() version needed by an upcoming Linuxulator change.
Attached
Detach File
Event Timeline
Log In to Comment