summaryrefslogtreecommitdiffstats
path: root/sys/kern/sys_generic.c
diff options
context:
space:
mode:
authordavide <davide@FreeBSD.org>2013-06-28 21:00:08 +0000
committerdavide <davide@FreeBSD.org>2013-06-28 21:00:08 +0000
commit0dd1d9c578ddc35507ac2072c5062f5d57c53147 (patch)
treee1591b3e71dfbd12dfea7bc7669be4a10541da31 /sys/kern/sys_generic.c
parenta0c5d96b0afd2c5fdf7e4ffe2c4c54b832a5dbf2 (diff)
downloadFreeBSD-src-0dd1d9c578ddc35507ac2072c5062f5d57c53147.zip
FreeBSD-src-0dd1d9c578ddc35507ac2072c5062f5d57c53147.tar.gz
- Trim an unused and bogus Makefile for mount_smbfs.
- Reconnect with some minor modifications, in particular now selsocket() internals are adapted to use sbintime units after recent'ish calloutng switch.
Diffstat (limited to 'sys/kern/sys_generic.c')
-rw-r--r--sys/kern/sys_generic.c55
1 files changed, 55 insertions, 0 deletions
diff --git a/sys/kern/sys_generic.c b/sys/kern/sys_generic.c
index 45b9327..a12773b 100644
--- a/sys/kern/sys_generic.c
+++ b/sys/kern/sys_generic.c
@@ -1498,6 +1498,61 @@ sys_openbsd_poll(td, uap)
}
/*
+ * XXX This was created specifically to support netncp and netsmb. This
+ * allows the caller to specify a socket to wait for events on. It returns
+ * 0 if any events matched and an error otherwise. There is no way to
+ * determine which events fired.
+ */
+int
+selsocket(struct socket *so, int events, struct timeval *tvp, struct thread *td)
+{
+ struct timeval rtv;
+ sbintime_t asbt, precision, rsbt;
+ int error;
+
+ if (tvp != NULL) {
+ rtv = *tvp;
+ if (rtv.tv_sec < 0 || rtv.tv_usec < 0 ||
+ rtv.tv_usec >= 1000000)
+ return (EINVAL);
+ if (!timevalisset(&rtv))
+ asbt = 0;
+ else if (rtv.tv_sec <= INT32_MAX) {
+ rsbt = tvtosbt(rtv);
+ precision = rsbt;
+ precision >>= tc_precexp;
+ if (TIMESEL(&asbt, rsbt))
+ asbt += tc_tick_sbt;
+ if (asbt <= INT64_MAX - rsbt)
+ asbt += rsbt;
+ else
+ asbt = -1;
+ } else
+ asbt = -1;
+ } else
+ asbt = -1;
+ seltdinit(td);
+ /*
+ * Iterate until the timeout expires or the socket becomes ready.
+ */
+ for (;;) {
+ selfdalloc(td, NULL);
+ error = sopoll(so, events, NULL, td);
+ /* error here is actually the ready events. */
+ if (error)
+ return (0);
+ error = seltdwait(td, asbt, precision);
+ if (error)
+ break;
+ }
+ seltdclear(td);
+ /* XXX Duplicates ncp/smb behavior. */
+ if (error == ERESTART)
+ error = 0;
+ return (error);
+}
+
+/*
* Preallocate two selfds associated with 'cookie'. Some fo_poll routines
* have two select sets, one for read and another for write.
*/
OpenPOWER on IntegriCloud