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, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 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. 13 * 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] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright (c) 1997-2001 by Sun Microsystems, Inc. 24 * All rights reserved. 25 */ 26 27 /* 28 * Log I/O Backend 29 * 30 * This backend provides the ability to form a T in an iob's output routine. 31 * We use this capability to provide interactive session logging. We create 32 * a log i/o and give it a pointer to another i/o backend representing the 33 * log file, and then stack this on top of the existing stdio i/o backend. 34 * As each write occurs, the log i/o writes to the log file, and also passes 35 * the write request along to io->io_next. 36 */ 37 38 #include <mdb/mdb_modapi.h> 39 #include <mdb/mdb_err.h> 40 #include <mdb/mdb_io_impl.h> 41 #include <mdb/mdb.h> 42 43 static ssize_t 44 logio_read(mdb_io_t *io, void *buf, size_t nbytes) 45 { 46 mdb_io_t *logio = io->io_data; 47 ssize_t rbytes; 48 49 if (io->io_next != NULL) { 50 rbytes = IOP_READ(io->io_next, buf, nbytes); 51 52 if (rbytes > 0) { 53 (void) IOP_WRITE(logio, mdb.m_prompt, mdb.m_promptlen); 54 (void) IOP_WRITE(logio, buf, rbytes); 55 } 56 57 return (rbytes); 58 } 59 60 return (-1); 61 } 62 63 static ssize_t 64 logio_write(mdb_io_t *io, const void *buf, size_t nbytes) 65 { 66 mdb_io_t *logio = io->io_data; 67 ssize_t wbytes; 68 69 if (io->io_next != NULL) { 70 wbytes = IOP_WRITE(io->io_next, buf, nbytes); 71 72 if (wbytes > 0) 73 (void) IOP_WRITE(logio, buf, wbytes); 74 75 return (wbytes); 76 } 77 78 return (-1); 79 } 80 81 static void 82 logio_close(mdb_io_t *io) 83 { 84 mdb_io_rele(io->io_data); 85 } 86 87 static const char * 88 logio_name(mdb_io_t *io) 89 { 90 if (io->io_next != NULL) 91 return (IOP_NAME(io->io_next)); 92 93 return ("(log)"); 94 } 95 96 static const mdb_io_ops_t logio_ops = { 97 .io_read = logio_read, 98 .io_write = logio_write, 99 .io_seek = no_io_seek, 100 .io_ctl = no_io_ctl, 101 .io_close = logio_close, 102 .io_name = logio_name, 103 .io_link = no_io_link, 104 .io_unlink = no_io_unlink, 105 .io_setattr = no_io_setattr, 106 .io_suspend = no_io_suspend, 107 .io_resume = no_io_resume 108 }; 109 110 mdb_io_t * 111 mdb_logio_create(mdb_io_t *logio) 112 { 113 mdb_io_t *io = mdb_alloc(sizeof (mdb_io_t), UM_SLEEP); 114 115 io->io_ops = &logio_ops; 116 io->io_data = mdb_io_hold(logio); 117 io->io_next = NULL; 118 io->io_refcnt = 0; 119 120 return (io); 121 } 122