diff options
Diffstat (limited to 'usr/src/uts/common/os/streamio.c')
-rw-r--r-- | usr/src/uts/common/os/streamio.c | 54 |
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); |