summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/os/streamio.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/uts/common/os/streamio.c')
-rw-r--r--usr/src/uts/common/os/streamio.c54
1 files changed, 52 insertions, 2 deletions
diff --git a/usr/src/uts/common/os/streamio.c b/usr/src/uts/common/os/streamio.c
index 102c803f5f..3a5c1ecd19 100644
--- a/usr/src/uts/common/os/streamio.c
+++ b/usr/src/uts/common/os/streamio.c
@@ -25,7 +25,7 @@
/*
* Copyright (c) 1988, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright 2017 Joyent, Inc.
- * Copyright 2019 OmniOS Community Edition (OmniOSce) Association.
+ * Copyright 2020 OmniOS Community Edition (OmniOSce) Association.
*/
#include <sys/types.h>
@@ -78,6 +78,7 @@
#include <sys/policy.h>
#include <sys/dld.h>
#include <sys/zone.h>
+#include <sys/ptms.h>
#include <c2/audit.h>
/*
@@ -231,6 +232,50 @@ push_mod(queue_t *qp, dev_t *devp, struct stdata *stp, const char *name,
return (0);
}
+static int
+xpg4_fixup(queue_t *qp, dev_t *devp, struct stdata *stp, cred_t *crp)
+{
+ static const char *ptsmods[] = {
+ "ptem", "ldterm", "ttcompat"
+ };
+ dev_t dummydev = *devp;
+ struct strioctl strioc;
+ zoneid_t zoneid;
+ int32_t rval;
+ uint_t i;
+
+ /*
+ * Push modules required for the slave PTY to have terminal
+ * semantics out of the box; this is required by XPG4v2.
+ * These three modules are flagged as single-instance so that
+ * the system will never end up with duplicate copies pushed
+ * onto a stream.
+ */
+
+ zoneid = crgetzoneid(crp);
+ for (i = 0; i < ARRAY_SIZE(ptsmods); i++) {
+ int error;
+
+ error = push_mod(qp, &dummydev, stp, ptsmods[i], 0,
+ crp, zoneid);
+ if (error != 0)
+ return (error);
+ }
+
+ /*
+ * Send PTSSTTY down the stream
+ */
+
+ strioc.ic_cmd = PTSSTTY;
+ strioc.ic_timout = 0;
+ strioc.ic_len = 0;
+ strioc.ic_dp = NULL;
+
+ (void) strdoioctl(stp, &strioc, FNATIVE, K_TO_K, crp, &rval);
+
+ return (0);
+}
+
/*
* Open a stream device.
*/
@@ -549,10 +594,15 @@ retryap:
opendone:
+ if (error == 0 &&
+ (stp->sd_flag & (STRISTTY|STRXPG4TTY)) == (STRISTTY|STRXPG4TTY)) {
+ error = xpg4_fixup(qp, devp, stp, crp);
+ }
+
/*
* let specfs know that open failed part way through
*/
- if (error) {
+ if (error != 0) {
mutex_enter(&stp->sd_lock);
stp->sd_flag |= STREOPENFAIL;
mutex_exit(&stp->sd_lock);