summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBryan Cantrill <bryan@joyent.com>2014-05-07 07:25:58 +0000
committerBryan Cantrill <bryan@joyent.com>2014-05-07 07:25:58 +0000
commit06f5aa053f25bcef3d424c79eaeee748c3d29b9d (patch)
tree0ed0fb50f274780e762000a57c2b587bcef757f2
parentbc64171bf6edb0a45ff6b5dff70f344218c2fd38 (diff)
downloadillumos-joyent-06f5aa053f25bcef3d424c79eaeee748c3d29b9d.tar.gz
OS-2987 lx brand needs to support pselect6()
-rw-r--r--usr/src/lib/brand/lx/lx_brand/common/lx_brand.c7
-rw-r--r--usr/src/lib/brand/lx/lx_brand/common/poll_select.c7
-rw-r--r--usr/src/lib/brand/lx/lx_brand/common/signal.c108
-rw-r--r--usr/src/lib/brand/lx/lx_brand/sys/lx_syscall.h7
4 files changed, 122 insertions, 7 deletions
diff --git a/usr/src/lib/brand/lx/lx_brand/common/lx_brand.c b/usr/src/lib/brand/lx/lx_brand/common/lx_brand.c
index 64a6fcebd0..7758ec867a 100644
--- a/usr/src/lib/brand/lx/lx_brand/common/lx_brand.c
+++ b/usr/src/lib/brand/lx/lx_brand/common/lx_brand.c
@@ -22,7 +22,10 @@
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
- * Copyright 2014 Joyent, Inc. All rights reserved.
+ */
+
+/*
+ * Copyright (c) 2014, Joyent, Inc. All rights reserved.
*/
#include <sys/types.h>
@@ -1224,7 +1227,7 @@ static struct lx_sysent sysents[] = {
{"readlinkat", lx_readlinkat, 0, 4}, /* 305 */
{"fchmodat", lx_fchmodat, 0, 4}, /* 306 */
{"faccessat", lx_faccessat, 0, 4}, /* 307 */
- {"pselect6", NULL, NOSYS_NULL, 0}, /* 308 */
+ {"pselect6", lx_pselect6, EBP_HAS_ARG6, 6}, /* 308 */
{"ppoll", NULL, NOSYS_NULL, 0}, /* 309 */
{"unshare", NULL, NOSYS_NULL, 0}, /* 310 */
{"set_robust_list", NULL, NOSYS_NULL, 0}, /* 311 */
diff --git a/usr/src/lib/brand/lx/lx_brand/common/poll_select.c b/usr/src/lib/brand/lx/lx_brand/common/poll_select.c
index 5eba21c652..7d7ee9f0aa 100644
--- a/usr/src/lib/brand/lx/lx_brand/common/poll_select.c
+++ b/usr/src/lib/brand/lx/lx_brand/common/poll_select.c
@@ -24,7 +24,9 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
+/*
+ * Copyright (c) 2014, Joyent, Inc. All rights reserved.
+ */
#include <assert.h>
#include <unistd.h>
@@ -61,8 +63,7 @@ lx_select(uintptr_t p1, uintptr_t p2, uintptr_t p3, uintptr_t p4,
int r;
hrtime_t start = NULL, end;
- lx_debug("\tselect(%d, 0x%p, x%p, 0x%p. 0x%p, 0x%p)",
- nfds, rfdsp, wfdsp, efdsp, tvp);
+ lx_debug("\tselect(%d, 0x%p, 0x%p, 0x%p, 0x%p)", p1, p2, p3, p4, p5);
if (nfds > 0) {
if (p2 != NULL) {
diff --git a/usr/src/lib/brand/lx/lx_brand/common/signal.c b/usr/src/lib/brand/lx/lx_brand/common/signal.c
index b6fea626b7..1b7c6f90fb 100644
--- a/usr/src/lib/brand/lx/lx_brand/common/signal.c
+++ b/usr/src/lib/brand/lx/lx_brand/common/signal.c
@@ -24,7 +24,9 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
+/*
+ * Copyright (c) 2014, Joyent, Inc. All rights reserved.
+ */
#include <sys/types.h>
#include <sys/param.h>
@@ -49,6 +51,9 @@
#include <libintl.h>
#include <ieeefp.h>
+extern int pselect_large_fdset(int nfds, fd_set *in0, fd_set *out0, fd_set *ex0,
+ const timespec_t *tsp, const sigset_t *sp);
+
/*
* Delivering signals to a Linux process is complicated by differences in
* signal numbering, stack structure and contents, and the action taken when a
@@ -1712,3 +1717,104 @@ lx_siginit(void)
lx_debug("interposition handler setup for SIGPWR");
return (0);
}
+
+/*
+ * This code stongly resemebles lx_select(), but is here to be able to take
+ * advantage of the Linux signal helper routines.
+ */
+int
+lx_pselect6(uintptr_t p1, uintptr_t p2, uintptr_t p3, uintptr_t p4,
+ uintptr_t p5, uintptr_t p6)
+{
+ int nfds = (int)p1;
+ fd_set *rfdsp = NULL;
+ fd_set *wfdsp = NULL;
+ fd_set *efdsp = NULL;
+ timespec_t ts, *tsp = NULL;
+ int fd_set_len = howmany(nfds, 8);
+ int r;
+ sigset_t sigset, *sp = NULL;
+
+ lx_debug("\tpselect6(%d, 0x%p, 0x%p, 0x%p, 0x%p, 0x%p)",
+ p1, p2, p3, p4, p4, p6);
+
+ if (nfds > 0) {
+ if (p2 != NULL) {
+ rfdsp = SAFE_ALLOCA(fd_set_len);
+ if (rfdsp == NULL)
+ return (-ENOMEM);
+ if (uucopy((void *)p2, rfdsp, fd_set_len) != 0)
+ return (-errno);
+ }
+ if (p3 != NULL) {
+ wfdsp = SAFE_ALLOCA(fd_set_len);
+ if (wfdsp == NULL)
+ return (-ENOMEM);
+ if (uucopy((void *)p3, wfdsp, fd_set_len) != 0)
+ return (-errno);
+ }
+ if (p4 != NULL) {
+ efdsp = SAFE_ALLOCA(fd_set_len);
+ if (efdsp == NULL)
+ return (-ENOMEM);
+ if (uucopy((void *)p4, efdsp, fd_set_len) != 0)
+ return (-errno);
+ }
+ }
+
+ if (p5 != NULL) {
+ if (uucopy((void *)p5, &ts, sizeof (ts)) != 0)
+ return (-errno);
+
+ tsp = &ts;
+ }
+
+ if (p6 != NULL) {
+ /*
+ * To force the number of arguments to be no more than six,
+ * Linux bundles both the sigset and the size into a structure
+ * that becomes the sixth argument.
+ */
+ struct {
+ lx_sigset_t *addr;
+ size_t size;
+ } lx_sigset;
+
+ if (uucopy((void *)p6, &lx_sigset, sizeof (lx_sigset)) != 0)
+ return (-errno);
+
+ /*
+ * Yes, that's right: Linux forces a size to be passed only
+ * so it can check that it's the size of a sigset_t.
+ */
+ if (lx_sigset.size != sizeof (lx_sigset_t))
+ return (-EINVAL);
+
+ if ((r = ltos_sigset(lx_sigset.addr, &sigset)) != 0)
+ return (r);
+
+ sp = &sigset;
+ }
+
+ if (nfds >= FD_SETSIZE)
+ r = pselect_large_fdset(nfds, rfdsp, wfdsp, efdsp, tsp, sp);
+ else
+ r = pselect(nfds, rfdsp, wfdsp, efdsp, tsp, sp);
+
+ if (r < 0)
+ return (-errno);
+
+ /*
+ * For pselect6(), we don't honor the strange Linux select() semantics
+ * with respect to the timestruc parameter because glibc ignores it
+ * anyway -- just copy out the fd pointers and return.
+ */
+ if ((rfdsp != NULL) && (uucopy(rfdsp, (void *)p2, fd_set_len) != 0))
+ return (-errno);
+ if ((wfdsp != NULL) && (uucopy(wfdsp, (void *)p3, fd_set_len) != 0))
+ return (-errno);
+ if ((efdsp != NULL) && (uucopy(efdsp, (void *)p4, fd_set_len) != 0))
+ return (-errno);
+
+ return (r);
+}
diff --git a/usr/src/lib/brand/lx/lx_brand/sys/lx_syscall.h b/usr/src/lib/brand/lx/lx_brand/sys/lx_syscall.h
index a6e061c42d..574d8eab6d 100644
--- a/usr/src/lib/brand/lx/lx_brand/sys/lx_syscall.h
+++ b/usr/src/lib/brand/lx/lx_brand/sys/lx_syscall.h
@@ -22,7 +22,10 @@
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
- * Copyright 2014 Joyent, Inc. All rights reserved.
+ */
+
+/*
+ * Copyright (c) 2014, Joyent, Inc. All rights reserved.
*/
#ifndef _SYS_LX_SYSCALL_H
@@ -80,6 +83,8 @@ extern int lx_pwrite64(uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t);
extern int lx_socketcall(uintptr_t, uintptr_t);
extern int lx_select(uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t);
+extern int lx_pselect6(uintptr_t, uintptr_t, uintptr_t, uintptr_t,
+ uintptr_t, uintptr_t);
extern int lx_poll(uintptr_t, uintptr_t, uintptr_t);
extern int lx_oldgetrlimit(uintptr_t, uintptr_t);
extern int lx_getrlimit(uintptr_t, uintptr_t);