summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/os
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/uts/common/os')
-rw-r--r--usr/src/uts/common/os/streamio.c25
-rw-r--r--usr/src/uts/common/os/strsubr.c18
2 files changed, 40 insertions, 3 deletions
diff --git a/usr/src/uts/common/os/streamio.c b/usr/src/uts/common/os/streamio.c
index 21ec25b5b3..8ec67ea76a 100644
--- a/usr/src/uts/common/os/streamio.c
+++ b/usr/src/uts/common/os/streamio.c
@@ -25,6 +25,7 @@
/*
* Copyright (c) 1988, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright 2017 Joyent, Inc.
+ * Copyright 2018 OmniOS Community Edition (OmniOSce) Association.
*/
#include <sys/types.h>
@@ -3821,6 +3822,30 @@ strioctl(struct vnode *vp, int cmd, intptr_t arg, int flag, int copyflag,
TRACE_2(TR_FAC_STREAMS_FR, TR_I_PUSH,
"I_PUSH:fp %p stp %p", fp, stp);
+ /*
+ * If the module is flagged as single-instance, then check
+ * to see if the module is already pushed. If it is, return
+ * as if the push was successful.
+ */
+ if (fp->f_qflag & _QSINGLE_INSTANCE) {
+ queue_t *q;
+
+ claimstr(stp->sd_wrq);
+ for (q = stp->sd_wrq->q_next; q; q = q->q_next) {
+ if (q->q_flag & QREADR) {
+ q = NULL;
+ break;
+ }
+ if (strcmp(mname, Q2NAME(q)) == 0)
+ break;
+ }
+ releasestr(stp->sd_wrq);
+ if (q != NULL) {
+ fmodsw_rele(fp);
+ return (0);
+ }
+ }
+
if (error = strstartplumb(stp, flag, cmd)) {
fmodsw_rele(fp);
return (error);
diff --git a/usr/src/uts/common/os/strsubr.c b/usr/src/uts/common/os/strsubr.c
index 0d0d290fcc..959e5576f0 100644
--- a/usr/src/uts/common/os/strsubr.c
+++ b/usr/src/uts/common/os/strsubr.c
@@ -27,6 +27,7 @@
* Use is subject to license terms.
* Copyright (c) 2016 by Delphix. All rights reserved.
* Copyright 2018 Joyent, Inc.
+ * Copyright 2018 OmniOS Community Edition (OmniOSce) Association.
*/
#include <sys/types.h>
@@ -951,7 +952,7 @@ str_sendsig(vnode_t *vp, int event, uchar_t band, int error)
*/
static void
dosendsig(proc_t *proc, int events, int sevent, k_siginfo_t *info,
- uchar_t band, int error)
+ uchar_t band, int error)
{
ASSERT(MUTEX_HELD(&proc->p_lock));
@@ -2351,7 +2352,7 @@ mux_rmvedge(stdata_t *upstp, int muxid, str_stack_t *ss)
*/
int
devflg_to_qflag(struct streamtab *stp, uint32_t devflag, uint32_t *qflagp,
- uint32_t *sqtypep)
+ uint32_t *sqtypep)
{
uint32_t qflag = 0;
uint32_t sqtype = 0;
@@ -2465,6 +2466,17 @@ devflg_to_qflag(struct streamtab *stp, uint32_t devflag, uint32_t *qflagp,
qflag |= _QDIRECT;
}
+ /*
+ * Private flag used to indicate that a streams module should only
+ * be pushed once. The TTY streams modules have this flag since if
+ * libc believes itself to be an xpg4 process then it will
+ * automatically and unconditionally push them when a PTS device is
+ * opened. If an application is not aware of this then without this
+ * flag we would end up with duplicate modules.
+ */
+ if (devflag & _D_SINGLE_INSTANCE)
+ qflag |= _QSINGLE_INSTANCE;
+
*qflagp = qflag;
*sqtypep = sqtype;
return (0);
@@ -8088,7 +8100,7 @@ strflushrq(vnode_t *vp, int flag)
void
strsetrputhooks(vnode_t *vp, uint_t flags,
- msgfunc_t protofunc, msgfunc_t miscfunc)
+ msgfunc_t protofunc, msgfunc_t miscfunc)
{
struct stdata *stp = vp->v_stream;