1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright (c) 1988, 2010, Oracle and/or its affiliates. All rights reserved. 23 */ 24 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 25 /* All Rights Reserved */ 26 27 28 #ifndef _SYS_PTMS_H 29 #define _SYS_PTMS_H 30 31 #ifdef __cplusplus 32 extern "C" { 33 #endif 34 35 #ifdef _KERNEL 36 37 /* 38 * Structures and definitions supporting the pseudo-terminal drivers. This 39 * structure is private and should not be used by any applications. 40 */ 41 struct pt_ttys { 42 queue_t *ptm_rdq; /* manager's read queue pointer */ 43 queue_t *pts_rdq; /* subsidiary's read queue pointer */ 44 mblk_t *pt_nullmsg; /* 0-bytes message block for pts close */ 45 pid_t pt_pid; /* process id (for debugging) */ 46 minor_t pt_minor; /* Minor number of this pty */ 47 int pt_refcnt; /* reference count for ptm_rdq/pts_rdq uses */ 48 ushort_t pt_state; /* state of manager/subsidiary pair */ 49 kcondvar_t pt_cv; /* condition variable for exclusive access */ 50 kmutex_t pt_lock; /* Per-element lock */ 51 zoneid_t pt_zoneid; /* Zone membership for this pty */ 52 uid_t pt_ruid; /* Real owner of pty */ 53 gid_t pt_rgid; /* Real group owner of pty */ 54 }; 55 56 /* 57 * pt_state values 58 */ 59 #define PTLOCK 0x01 /* manager/subsidiary pair is locked */ 60 #define PTMOPEN 0x02 /* manager side is open */ 61 #define PTSOPEN 0x04 /* subsidiary side is open */ 62 #define PTSTTY 0x08 /* subsidiary side is tty */ 63 64 /* 65 * Multi-threading primitives. 66 * Values of pt_refcnt: -1 if a writer is accessing the struct 67 * 0 if no one is reading or writing 68 * > 0 equals to the number of readers accessing the struct 69 */ 70 #define PT_ENTER_READ(p) { \ 71 mutex_enter(&(p)->pt_lock); \ 72 while ((p)->pt_refcnt < 0) \ 73 cv_wait(&((p)->pt_cv), &(p)->pt_lock); \ 74 (p)->pt_refcnt++; \ 75 mutex_exit(&(p)->pt_lock); \ 76 } 77 78 #define PT_ENTER_WRITE(p) { \ 79 mutex_enter(&(p)->pt_lock); \ 80 while ((p)->pt_refcnt != 0) \ 81 cv_wait(&((p)->pt_cv), &(p)->pt_lock); \ 82 (p)->pt_refcnt = -1; \ 83 mutex_exit(&(p)->pt_lock); \ 84 } 85 86 #define PT_EXIT_READ(p) { \ 87 mutex_enter(&(p)->pt_lock); \ 88 ASSERT((p)->pt_refcnt > 0); \ 89 if ((--((p)->pt_refcnt)) == 0) \ 90 cv_broadcast(&(p)->pt_cv); \ 91 mutex_exit(&(p)->pt_lock); \ 92 } 93 94 #define PT_EXIT_WRITE(p) { \ 95 mutex_enter(&(p)->pt_lock); \ 96 ASSERT((p)->pt_refcnt == -1); \ 97 (p)->pt_refcnt = 0; \ 98 cv_broadcast(&(p)->pt_cv); \ 99 mutex_exit(&(p)->pt_lock); \ 100 } 101 102 /* 103 * ptms_lock and pt_cnt are defined in ptms_conf.c 104 */ 105 extern kmutex_t ptms_lock; 106 extern dev_info_t *pts_dip; /* private copy of devinfo ptr */ 107 108 extern void ptms_init(void); 109 extern struct pt_ttys *pt_ttys_alloc(void); 110 extern void ptms_close(struct pt_ttys *, uint_t); 111 extern struct pt_ttys *ptms_minor2ptty(minor_t); 112 extern int ptms_attach_subsidiary(void); 113 extern int ptms_minor_valid(minor_t ptmin, uid_t *uid, gid_t *gid); 114 extern int ptms_minor_exists(minor_t ptmin); 115 extern void ptms_set_owner(minor_t ptmin, uid_t uid, gid_t gid); 116 extern major_t ptms_subsidiary_attached(void); 117 118 #ifdef DEBUG 119 extern void ptms_log(char *, uint_t); 120 extern void ptms_logp(char *, uintptr_t); 121 #define DDBG(a, b) ptms_log(a, b) 122 #define DDBGP(a, b) ptms_logp(a, b) 123 #else 124 #define DDBG(a, b) 125 #define DDBGP(a, b) 126 #endif 127 128 #endif /* _KERNEL */ 129 130 typedef struct pt_own { 131 uid_t pto_ruid; 132 gid_t pto_rgid; 133 } pt_own_t; 134 135 /* 136 * IOCTL COMMANDS 137 * 138 * ISPTM 139 * Determines whether the file descriptor is that of an open 140 * manager device. Return code of zero indicates that the file 141 * descriptor represents a manager device. 142 * 143 * UNLKPT 144 * Unlocks the manager and subsidiary devices. It returns 0 on 145 * success. On failure, the errno is set to EINVAL indicating 146 * that the manager device is not open. 147 * 148 * ZONEPT 149 * Sets the zoneid of the pair of manager and subsidiary devices. 150 * It returns 0 upon success. Used to force a pty 'into' a zone 151 * upon zone entry. 152 * 153 * PT_OWNER 154 * Sets uid and gid for subsidiary device. It returns 0 on 155 * success. 156 */ 157 #define ISPTM (('P'<<8)|1) /* query for manager */ 158 #define UNLKPT (('P'<<8)|2) /* unlock manager/subsidiary pair */ 159 #define PTSSTTY (('P'<<8)|3) /* set tty flag */ 160 #define ZONEPT (('P'<<8)|4) /* set zone of manager/subsidiary pair */ 161 #define OWNERPT (('P'<<8)|5) /* set owner/group for subsidiary */ 162 163 #ifdef __cplusplus 164 } 165 #endif 166 167 #endif /* _SYS_PTMS_H */ 168