Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F137149144
D1133.id2383.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
10 KB
Referenced Files
None
Subscribers
None
D1133.id2383.diff
View Options
Index: head/lib/libc/sys/Makefile.inc
===================================================================
--- head/lib/libc/sys/Makefile.inc
+++ head/lib/libc/sys/Makefile.inc
@@ -356,6 +356,7 @@
pdfork.2 pdkill.2 \
pdfork.2 pdwait4.2
MLINKS+=pipe.2 pipe2.2
+MLINKS+=poll.2 ppoll.2
MLINKS+=read.2 pread.2 \
read.2 preadv.2 \
read.2 readv.2
Index: head/lib/libc/sys/Symbol.map
===================================================================
--- head/lib/libc/sys/Symbol.map
+++ head/lib/libc/sys/Symbol.map
@@ -399,6 +399,10 @@
wait6;
};
+FBSD_1.4 {
+ ppoll;
+};
+
FBSDprivate_1.0 {
___acl_aclcheck_fd;
__sys___acl_aclcheck_fd;
@@ -821,6 +825,8 @@
__sys_pipe;
_poll;
__sys_poll;
+ _ppoll;
+ __sys_ppoll;
_preadv;
__sys_preadv;
_procctl;
Index: head/lib/libc/sys/poll.2
===================================================================
--- head/lib/libc/sys/poll.2
+++ head/lib/libc/sys/poll.2
@@ -28,7 +28,7 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd July 8, 2002
+.Dd November 13, 2014
.Dt POLL 2
.Os
.Sh NAME
@@ -40,6 +40,13 @@
.In poll.h
.Ft int
.Fn poll "struct pollfd fds[]" "nfds_t nfds" "int timeout"
+.Ft int
+.Fo ppoll
+.Fa "struct pollfd fds[]"
+.Fa "nfds_t nfds"
+.Fa "const struct timespec * restrict timeout"
+.Fa "const sigset_t * restrict newsigmask"
+.Fc
.Sh DESCRIPTION
The
.Fn poll
@@ -139,6 +146,47 @@
is zero, then
.Fn poll
will return without blocking.
+.Pp
+The
+.Fn ppoll
+system call, unlike
+.Fn poll ,
+is used to safely wait until either a set of file descriptors becomes
+ready or until a signal is caught.
+The
+.Fa fds
+and
+.Fa nfds
+arguments are identical to the analogous arguments of
+.Fn poll .
+The
+.Fa timeout
+argument in
+.Fn ppoll
+points to a
+.Vt "const struct timespec"
+which is defined in
+.In sys/timespec.h
+(shown below) rather than the
+.Vt "int timeout"
+used by
+.Fn poll .
+A null pointer may be passed to indicate that
+.Fn ppoll
+should wait indefinitely.
+Finally,
+.Fa newsigmask
+specifies a signal mask which is set while waiting for input.
+When
+.Fn ppoll
+returns, the original signal mask is restored.
+.Pp
+.Bd -literal
+struct timespec {
+ time_t tv_sec; /* seconds */
+ long tv_nsec; /* and nanoseconds */
+};
+.Ed
.Sh RETURN VALUES
The
.Fn poll
@@ -185,17 +233,26 @@
A signal was delivered before the time limit expired and
before any of the selected events occurred.
.It Bq Er EINVAL
-The specified time limit is negative.
+The specified time limit is invalid. One of its components is negative or too large.
.El
.Sh SEE ALSO
.Xr accept 2 ,
.Xr connect 2 ,
.Xr kqueue 2 ,
+.Xr pselect 2 ,
.Xr read 2 ,
.Xr recv 2 ,
.Xr select 2 ,
.Xr send 2 ,
.Xr write 2
+.Sh STANDARDS
+The
+.Fn poll
+function conforms to
+.St -p1003.1-2001 .
+The
+.Fn ppoll
+is not specified by POSIX.
.Sh HISTORY
The
.Fn poll
@@ -203,6 +260,10 @@
.At V .
This manual page and the core of the implementation was taken from
.Nx .
+The
+.Fn ppoll
+function first appeared in
+.Fx 11.0
.Sh BUGS
The distinction between some of the fields in the
.Fa events
Index: head/sys/compat/freebsd32/freebsd32_misc.c
===================================================================
--- head/sys/compat/freebsd32/freebsd32_misc.c
+++ head/sys/compat/freebsd32/freebsd32_misc.c
@@ -2991,3 +2991,31 @@
}
return (kern_fcntl_freebsd(td, uap->fd, uap->cmd, tmp));
}
+
+int
+freebsd32_ppoll(struct thread *td, struct freebsd32_ppoll_args *uap)
+{
+ struct timespec32 ts32;
+ struct timespec ts, *tsp;
+ sigset_t set, *ssp;
+ int error;
+
+ if (uap->ts != NULL) {
+ error = copyin(uap->ts, &ts32, sizeof(ts32));
+ if (error != 0)
+ return (error);
+ CP(ts32, ts, tv_sec);
+ CP(ts32, ts, tv_nsec);
+ tsp = &ts;
+ } else
+ tsp = NULL;
+ if (uap->set != NULL) {
+ error = copyin(uap->set, &set, sizeof(set));
+ if (error != 0)
+ return (error);
+ ssp = &set;
+ } else
+ ssp = NULL;
+
+ return (kern_poll(td, uap->fds, uap->nfds, tsp, ssp));
+}
Index: head/sys/compat/freebsd32/syscalls.master
===================================================================
--- head/sys/compat/freebsd32/syscalls.master
+++ head/sys/compat/freebsd32/syscalls.master
@@ -1066,3 +1066,6 @@
uint32_t id1, uint32_t id2, int com, \
void *data); }
#endif
+545 AUE_POLL STD { int freebsd32_ppoll(struct pollfd *fds, \
+ u_int nfds, const struct timespec32 *ts, \
+ const sigset_t *set); }
Index: head/sys/kern/sys_generic.c
===================================================================
--- head/sys/kern/sys_generic.c
+++ head/sys/kern/sys_generic.c
@@ -1289,26 +1289,60 @@
return (0);
}
-#ifndef _SYS_SYSPROTO_H_
-struct poll_args {
- struct pollfd *fds;
- u_int nfds;
- int timeout;
-};
-#endif
int
-sys_poll(td, uap)
- struct thread *td;
- struct poll_args *uap;
+sys_poll(struct thread *td, struct poll_args *uap)
+{
+ struct timespec ts, *tsp;
+
+ if (uap->timeout != INFTIM) {
+ if (uap->timeout < 0)
+ return (EINVAL);
+ ts.tv_sec = uap->timeout / 1000;
+ ts.tv_nsec = (uap->timeout % 1000) * 1000000;
+ tsp = &ts;
+ } else
+ tsp = NULL;
+
+ return (kern_poll(td, uap->fds, uap->nfds, tsp, NULL));
+}
+
+int
+kern_poll(struct thread *td, struct pollfd *fds, u_int nfds,
+ struct timespec *tsp, sigset_t *uset)
{
struct pollfd *bits;
struct pollfd smallbits[32];
- sbintime_t asbt, precision, rsbt;
- u_int nfds;
+ sbintime_t sbt, precision, tmp;
+ time_t over;
+ struct timespec ts;
int error;
size_t ni;
- nfds = uap->nfds;
+ 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 (nfds > maxfilesperproc && nfds > FD_SETSIZE)
return (EINVAL);
ni = nfds * sizeof(struct pollfd);
@@ -1316,34 +1350,33 @@
bits = malloc(ni, M_TEMP, M_WAITOK);
else
bits = smallbits;
- error = copyin(uap->fds, bits, ni);
+ error = copyin(fds, bits, ni);
if (error)
goto done;
- precision = 0;
- if (uap->timeout != INFTIM) {
- if (uap->timeout < 0) {
- error = EINVAL;
+
+ if (uset != NULL) {
+ error = kern_sigprocmask(td, SIG_SETMASK, uset,
+ &td->td_oldsigmask, 0);
+ if (error)
goto done;
- }
- if (uap->timeout == 0)
- asbt = 0;
- else {
- rsbt = SBT_1MS * uap->timeout;
- precision = rsbt;
- precision >>= tc_precexp;
- if (TIMESEL(&asbt, rsbt))
- asbt += tc_tick_sbt;
- asbt += rsbt;
- }
- } else
- asbt = -1;
+ 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);
+ }
+
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, precision);
if (error)
break;
error = pollrescan(td);
@@ -1359,7 +1392,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 +1402,35 @@
return (error);
}
+int
+sys_ppoll(struct thread *td, struct ppoll_args *uap)
+{
+ struct timespec ts, *tsp;
+ sigset_t set, *ssp;
+ int error;
+
+ if (uap->ts != NULL) {
+ error = copyin(uap->ts, &ts, sizeof(ts));
+ if (error)
+ return (error);
+ tsp = &ts;
+ } else
+ tsp = NULL;
+ if (uap->set != NULL) {
+ error = copyin(uap->set, &set, sizeof(set));
+ if (error)
+ return (error);
+ ssp = &set;
+ } else
+ ssp = NULL;
+ /*
+ * fds is still a pointer to user space. kern_poll() will
+ * take care of copyin that array to the kernel space.
+ */
+
+ return (kern_poll(td, uap->fds, uap->nfds, tsp, ssp));
+}
+
static int
pollrescan(struct thread *td)
{
Index: head/sys/kern/syscalls.master
===================================================================
--- head/sys/kern/syscalls.master
+++ head/sys/kern/syscalls.master
@@ -980,5 +980,8 @@
543 AUE_NULL NOSTD { int aio_mlock(struct aiocb *aiocbp); }
544 AUE_NULL STD { int procctl(idtype_t idtype, id_t id, \
int com, void *data); }
+545 AUE_POLL STD { int ppoll(struct pollfd *fds, u_int nfds, \
+ const struct timespec *ts, \
+ const sigset_t *set); }
; Please copy any additions and changes to the following compatability tables:
; sys/compat/freebsd32/syscalls.master
Index: head/sys/sys/poll.h
===================================================================
--- head/sys/sys/poll.h
+++ head/sys/sys/poll.h
@@ -95,8 +95,26 @@
#ifndef _KERNEL
+#if __BSD_VISIBLE
+#include <sys/_types.h>
+
+#include <sys/_sigset.h>
+#include <sys/timespec.h>
+
+#ifndef _SIGSET_T_DECLARED
+#define _SIGSET_T_DECLARED
+typedef __sigset_t sigset_t;
+#endif
+
+#endif
+
__BEGIN_DECLS
int poll(struct pollfd _pfd[], nfds_t _nfds, int _timeout);
+#if __BSD_VISIBLE
+int ppoll(struct pollfd _pfd[], nfds_t _nfds,
+ const struct timespec *__restrict _timeout,
+ const sigset_t *__restrict _newsigmask);
+#endif
__END_DECLS
#endif /* !_KERNEL */
Index: head/sys/sys/syscallsubr.h
===================================================================
--- head/sys/sys/syscallsubr.h
+++ head/sys/sys/syscallsubr.h
@@ -46,6 +46,7 @@
struct mbuf;
struct msghdr;
struct msqid_ds;
+struct pollfd;
struct ogetdirentries_args;
struct rlimit;
struct rusage;
@@ -164,6 +165,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_poll(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
Sat, Nov 22, 6:52 AM (12 h, 18 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
25928690
Default Alt Text
D1133.id2383.diff (10 KB)
Attached To
Mode
D1133: Implement ppoll() function.
Attached
Detach File
Event Timeline
Log In to Comment