4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #include <mdb/mdb_modapi.h>
28 #include <mdb/mdb_ks.h>
30 #include <sys/types.h>
31 #include <sys/strsubr.h>
34 typedef struct pt_flags
{
39 static const struct pt_flags pf
[] = {
40 { "PTLOCK", "Master/slave pair is locked" },
41 { "PTMOPEN", "Master side is open" },
42 { "PTSOPEN", "Slave side is open" },
43 { "PTSTTY", "Slave side is tty" },
48 pt_parse_flag(const ptflags_t ftable
[], const char *arg
, uint32_t *flag
)
52 for (i
= 0; ftable
[i
].pt_name
!= NULL
; i
++) {
53 if (strcasecmp(arg
, ftable
[i
].pt_name
) == 0) {
63 pt_flag_usage(const ptflags_t ftable
[])
67 for (i
= 0; ftable
[i
].pt_name
!= NULL
; i
++)
68 mdb_printf("%12s %s\n",
69 ftable
[i
].pt_name
, ftable
[i
].pt_descr
);
75 ptms_pr_qinfo(char *buf
, size_t nbytes
, struct pt_ttys
*pt
, char *peername
,
76 queue_t
*peerq
, char *procname
)
78 (void) mdb_snprintf(buf
, nbytes
,
79 "pts/%d:%s: %p\nprocess: %d(%s)",
80 pt
->pt_minor
, peername
, peerq
, pt
->pt_pid
, procname
);
84 ptms(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
86 const int PT_FLGDELT
= (int)(sizeof (uintptr_t) * 2 + 5);
89 char c
[MAXCOMLEN
+ 1];
90 const char *flag
= NULL
, *not_flag
= NULL
;
92 uint_t verbose
= FALSE
;
93 uint32_t mask
= 0, not_mask
= 0;
95 if (!(flags
& DCMD_ADDRSPEC
))
96 return (mdb_walk_dcmd("ptms", "ptms", argc
, argv
));
98 if (mdb_getopts(argc
, argv
,
99 'v', MDB_OPT_SETBITS
, TRUE
, &verbose
,
100 'f', MDB_OPT_STR
, &flag
,
101 'F', MDB_OPT_STR
, ¬_flag
, NULL
) != argc
)
104 if (DCMD_HDRSPEC(flags
) && flag
== NULL
&& not_flag
== NULL
) {
105 (void) mdb_printf("%?-s %s %s %?-s %?-s %3s %-6s %s\n",
106 "ADDR", "PTY", "FL", "MASTERQ", "SLAVEQ",
107 "ZID", "PID", "PROC");
110 if (flag
!= NULL
&& pt_parse_flag(pf
, flag
, &mask
) == -1) {
111 mdb_warn("unrecognized pty flag '%s'\n", flag
);
116 if (not_flag
!= NULL
&& pt_parse_flag(pf
, not_flag
, ¬_mask
) == -1) {
117 mdb_warn("unrecognized queue flag '%s'\n", flag
);
122 if (mdb_vread(&pt
, sizeof (pt
), addr
) == -1) {
123 mdb_warn("failed to read pty structure");
127 if (mask
!= 0 && !(pt
.pt_state
& mask
))
130 if (not_mask
!= 0 && (pt
.pt_state
& not_mask
))
134 * Options are specified for filtering, so If any option is specified on
135 * the command line, just print address and exit.
137 if (flag
!= NULL
|| not_flag
!= NULL
) {
138 mdb_printf("%0?p\n", addr
);
142 if (pt
.pt_pid
!= 0) {
143 if (mdb_pid2proc(pt
.pt_pid
, &p
) == (uintptr_t)NULL
)
144 (void) strcpy(c
, "<defunct>");
146 (void) strcpy(c
, p
.p_user
.u_comm
);
148 (void) strcpy(c
, "<unknown>");
150 (void) mdb_printf("%0?p %3d %2x %0?p %0?p %3d %6d %s\n",
151 addr
, pt
.pt_minor
, pt
.pt_state
, pt
.ptm_rdq
, pt
.pts_rdq
,
152 pt
.pt_zoneid
, pt
.pt_pid
, c
);
157 for (i
= 0; pf
[i
].pt_name
!= NULL
; i
++) {
158 if (!(pt
.pt_state
& (1 << i
)))
161 mdb_printf("%*s|\n%*s+--> ",
162 PT_FLGDELT
, "", PT_FLGDELT
, "");
165 mdb_printf("%*s ", PT_FLGDELT
, "");
167 mdb_printf("%-12s %s\n",
168 pf
[i
].pt_name
, pf
[i
].pt_descr
);
176 ptms_qinfo(const queue_t
*q
, char *buf
, size_t nbytes
, int ismaster
)
178 char c
[MAXCOMLEN
+ 1];
182 (void) mdb_vread(&pt
, sizeof (pt
), (uintptr_t)q
->q_ptr
);
184 if (pt
.pt_pid
!= 0) {
185 if (mdb_pid2proc(pt
.pt_pid
, &p
) == (uintptr_t)NULL
)
186 (void) strcpy(c
, "<defunct>");
188 (void) strcpy(c
, p
.p_user
.u_comm
);
190 (void) strcpy(c
, "<unknown>");
193 ptms_pr_qinfo(buf
, nbytes
, &pt
, "slave", pt
.pts_rdq
, c
);
195 ptms_pr_qinfo(buf
, nbytes
, &pt
, "master", pt
.ptm_rdq
, c
);
199 ptm_qinfo(const queue_t
*q
, char *buf
, size_t nbytes
)
201 ptms_qinfo(q
, buf
, nbytes
, 1);
205 pts_qinfo(const queue_t
*q
, char *buf
, size_t nbytes
)
207 ptms_qinfo(q
, buf
, nbytes
, 0);
211 ptms_walk_init(mdb_walk_state_t
*wsp
)
215 if (wsp
->walk_addr
!= (uintptr_t)NULL
) {
216 mdb_warn("ptms supports only global walks");
220 if (mdb_readvar(&wsp
->walk_addr
, "ptms_slots") == -1) {
221 mdb_warn("failed to read 'ptms_slots'");
225 if (mdb_readvar(&nslots
, "ptms_nslots") == -1) {
226 mdb_warn("failed to read 'ptms_nslots'");
231 * We remember the pointer value at the end of the array. When
232 * the walk gets there, we're done.
234 wsp
->walk_arg
= (((struct pt_ttys
**)wsp
->walk_addr
) + (nslots
- 1));
235 wsp
->walk_data
= mdb_alloc(sizeof (struct pt_ttys
), UM_SLEEP
);
241 ptms_walk_step(mdb_walk_state_t
*wsp
)
246 if (wsp
->walk_addr
> (uintptr_t)wsp
->walk_arg
)
249 if (mdb_vread(&ptr
, sizeof (struct pt_ttys
*), wsp
->walk_addr
) !=
250 (sizeof (struct pt_ttys
*))) {
251 mdb_warn("failed to read pt_ttys* at %p", wsp
->walk_addr
);
255 if (ptr
== (uintptr_t)NULL
) {
256 wsp
->walk_addr
+= sizeof (uintptr_t);
260 if (mdb_vread(wsp
->walk_data
, sizeof (struct pt_ttys
), ptr
) !=
261 sizeof (struct pt_ttys
)) {
262 mdb_warn("failed to read pt_ttys at %p", ptr
);
266 status
= wsp
->walk_callback(ptr
, wsp
->walk_data
, wsp
->walk_cbdata
);
267 wsp
->walk_addr
+= sizeof (uintptr_t);
273 ptms_walk_fini(mdb_walk_state_t
*wsp
)
275 mdb_free(wsp
->walk_data
, sizeof (struct pt_ttys
));
278 static const mdb_dcmd_t dcmds
[] = {
279 { "ptms", "?[-v] [-f flag] [-F flag]",
280 "print pseudo-terminal information", ptms
},
281 { "pty", "?[-v] [-f flag] [-F flag]",
282 "print pseudo-terminal information (alias of ::ptms", ptms
},
286 static const mdb_walker_t walkers
[] = {
287 { "ptms", "walk list of pseudo-tty's",
288 ptms_walk_init
, ptms_walk_step
, ptms_walk_fini
},
289 { "pty", "walk list of pseudo-tty's (alias of ::walk ptms)",
290 ptms_walk_init
, ptms_walk_step
, ptms_walk_fini
},
294 static const mdb_qops_t ptm_qops
= {
295 ptm_qinfo
, mdb_qrnext_default
, mdb_qwnext_default
298 static const mdb_qops_t pts_qops
= {
299 pts_qinfo
, mdb_qrnext_default
, mdb_qwnext_default
302 static const mdb_modinfo_t modinfo
= {
303 MDB_API_VERSION
, dcmds
, walkers
306 const mdb_modinfo_t
*
311 if (mdb_lookup_by_obj("ptm", "ptmwint", &sym
) == 0)
312 mdb_qops_install(&ptm_qops
, (uintptr_t)sym
.st_value
);
313 if (mdb_lookup_by_obj("pts", "ptswint", &sym
) == 0)
314 mdb_qops_install(&pts_qops
, (uintptr_t)sym
.st_value
);
324 if (mdb_lookup_by_obj("ptm", "ptmwint", &sym
) == 0)
325 mdb_qops_remove(&ptm_qops
, (uintptr_t)sym
.st_value
);
326 if (mdb_lookup_by_obj("pts", "ptswint", &sym
) == 0)
327 mdb_qops_remove(&pts_qops
, (uintptr_t)sym
.st_value
);