xref: /illumos-gate/usr/src/cmd/mdb/common/mdb/mdb_fdio.c (revision b55a30d7f192ccc3e815772ffcd83bec669ae7a7)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
57f4f06d2Spetede  * Common Development and Distribution License (the "License").
67f4f06d2Spetede  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
217c478bd9Sstevel@tonic-gate /*
22a576ab5bSrab  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
237c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate  */
257c478bd9Sstevel@tonic-gate 
267c478bd9Sstevel@tonic-gate /*
277c478bd9Sstevel@tonic-gate  * File Descriptor I/O Backend
287c478bd9Sstevel@tonic-gate  *
297c478bd9Sstevel@tonic-gate  * Simple backend to pass though io_ops to the corresponding system calls on
307c478bd9Sstevel@tonic-gate  * an underlying fd.  We provide functions to create fdio objects using file
317c478bd9Sstevel@tonic-gate  * descriptors, explicit file names, and path lookups.  We save the complete
327c478bd9Sstevel@tonic-gate  * filename so that mdb_iob_name can be used to report the complete filename
337c478bd9Sstevel@tonic-gate  * of an open macro file in syntax error messages.
347c478bd9Sstevel@tonic-gate  */
357c478bd9Sstevel@tonic-gate 
367c478bd9Sstevel@tonic-gate #include <sys/param.h>
377c478bd9Sstevel@tonic-gate #include <sys/stat.h>
387c478bd9Sstevel@tonic-gate #include <sys/dkio.h>
397c478bd9Sstevel@tonic-gate #include <unistd.h>
407c478bd9Sstevel@tonic-gate #include <string.h>
417c478bd9Sstevel@tonic-gate #include <errno.h>
427c478bd9Sstevel@tonic-gate #include <fcntl.h>
437c478bd9Sstevel@tonic-gate 
447c478bd9Sstevel@tonic-gate #include <mdb/mdb_modapi.h>
457c478bd9Sstevel@tonic-gate #include <mdb/mdb_err.h>
467c478bd9Sstevel@tonic-gate #include <mdb/mdb_io_impl.h>
477c478bd9Sstevel@tonic-gate #include <mdb/mdb.h>
487c478bd9Sstevel@tonic-gate 
497c478bd9Sstevel@tonic-gate typedef struct fd_data {
507c478bd9Sstevel@tonic-gate 	char fd_name[MAXPATHLEN];	/* Save filename for error messages */
517c478bd9Sstevel@tonic-gate 	int fd_fd;			/* File descriptor */
527c478bd9Sstevel@tonic-gate } fd_data_t;
537c478bd9Sstevel@tonic-gate 
547c478bd9Sstevel@tonic-gate static ssize_t
557c478bd9Sstevel@tonic-gate fdio_read(mdb_io_t *io, void *buf, size_t nbytes)
567c478bd9Sstevel@tonic-gate {
577c478bd9Sstevel@tonic-gate 	fd_data_t *fdp = io->io_data;
587c478bd9Sstevel@tonic-gate 
597c478bd9Sstevel@tonic-gate 	if (io->io_next == NULL)
607c478bd9Sstevel@tonic-gate 		return (read(fdp->fd_fd, buf, nbytes));
617c478bd9Sstevel@tonic-gate 
627c478bd9Sstevel@tonic-gate 	return (IOP_READ(io->io_next, buf, nbytes));
637c478bd9Sstevel@tonic-gate }
647c478bd9Sstevel@tonic-gate 
657c478bd9Sstevel@tonic-gate static ssize_t
667c478bd9Sstevel@tonic-gate fdio_write(mdb_io_t *io, const void *buf, size_t nbytes)
677c478bd9Sstevel@tonic-gate {
687c478bd9Sstevel@tonic-gate 	fd_data_t *fdp = io->io_data;
697c478bd9Sstevel@tonic-gate 
707c478bd9Sstevel@tonic-gate 	if (io->io_next == NULL)
717c478bd9Sstevel@tonic-gate 		return (write(fdp->fd_fd, buf, nbytes));
727c478bd9Sstevel@tonic-gate 
737c478bd9Sstevel@tonic-gate 	return (IOP_WRITE(io->io_next, buf, nbytes));
747c478bd9Sstevel@tonic-gate }
757c478bd9Sstevel@tonic-gate 
767c478bd9Sstevel@tonic-gate static off64_t
777c478bd9Sstevel@tonic-gate fdio_seek(mdb_io_t *io, off64_t offset, int whence)
787c478bd9Sstevel@tonic-gate {
797c478bd9Sstevel@tonic-gate 	fd_data_t *fdp = io->io_data;
807c478bd9Sstevel@tonic-gate 
817c478bd9Sstevel@tonic-gate 	if (io->io_next == NULL)
827c478bd9Sstevel@tonic-gate 		return (lseek64(fdp->fd_fd, offset, whence));
837c478bd9Sstevel@tonic-gate 
847c478bd9Sstevel@tonic-gate 	return (IOP_SEEK(io->io_next, offset, whence));
857c478bd9Sstevel@tonic-gate }
867c478bd9Sstevel@tonic-gate 
877c478bd9Sstevel@tonic-gate static int
887c478bd9Sstevel@tonic-gate fdio_ctl(mdb_io_t *io, int req, void *arg)
897c478bd9Sstevel@tonic-gate {
907c478bd9Sstevel@tonic-gate 	fd_data_t *fdp = io->io_data;
917c478bd9Sstevel@tonic-gate 
927c478bd9Sstevel@tonic-gate 	if (io->io_next != NULL)
937c478bd9Sstevel@tonic-gate 		return (IOP_CTL(io->io_next, req, arg));
947c478bd9Sstevel@tonic-gate 
957c478bd9Sstevel@tonic-gate 	if (req == MDB_IOC_GETFD)
967c478bd9Sstevel@tonic-gate 		return (fdp->fd_fd);
977c478bd9Sstevel@tonic-gate 	else
987c478bd9Sstevel@tonic-gate 		return (ioctl(fdp->fd_fd, req, arg));
997c478bd9Sstevel@tonic-gate }
1007c478bd9Sstevel@tonic-gate 
1017c478bd9Sstevel@tonic-gate static void
1027c478bd9Sstevel@tonic-gate fdio_close(mdb_io_t *io)
1037c478bd9Sstevel@tonic-gate {
1047c478bd9Sstevel@tonic-gate 	fd_data_t *fdp = io->io_data;
1057c478bd9Sstevel@tonic-gate 
1067c478bd9Sstevel@tonic-gate 	(void) close(fdp->fd_fd);
1077c478bd9Sstevel@tonic-gate 	mdb_free(fdp, sizeof (fd_data_t));
1087c478bd9Sstevel@tonic-gate }
1097c478bd9Sstevel@tonic-gate 
1107c478bd9Sstevel@tonic-gate static const char *
1117c478bd9Sstevel@tonic-gate fdio_name(mdb_io_t *io)
1127c478bd9Sstevel@tonic-gate {
1137c478bd9Sstevel@tonic-gate 	fd_data_t *fdp = io->io_data;
1147c478bd9Sstevel@tonic-gate 
1157c478bd9Sstevel@tonic-gate 	if (io->io_next == NULL)
1167c478bd9Sstevel@tonic-gate 		return (fdp->fd_name);
1177c478bd9Sstevel@tonic-gate 
1187c478bd9Sstevel@tonic-gate 	return (IOP_NAME(io->io_next));
1197c478bd9Sstevel@tonic-gate }
1207c478bd9Sstevel@tonic-gate 
1217c478bd9Sstevel@tonic-gate mdb_io_t *
1227c478bd9Sstevel@tonic-gate mdb_fdio_create_path(const char *path[], const char *fname,
1237c478bd9Sstevel@tonic-gate     int flags, mode_t mode)
1247c478bd9Sstevel@tonic-gate {
1257c478bd9Sstevel@tonic-gate 	int fd;
1267f4f06d2Spetede 	char buf[MAXPATHLEN];
1277c478bd9Sstevel@tonic-gate 
1287c478bd9Sstevel@tonic-gate 	if (path != NULL && strchr(fname, '/') == NULL) {
1297c478bd9Sstevel@tonic-gate 		int i;
1307c478bd9Sstevel@tonic-gate 
1317c478bd9Sstevel@tonic-gate 		for (fd = -1, i = 0; path[i] != NULL; i++) {
1327c478bd9Sstevel@tonic-gate 			(void) mdb_iob_snprintf(buf, MAXPATHLEN, "%s/%s",
1337c478bd9Sstevel@tonic-gate 			    path[i], fname);
1347c478bd9Sstevel@tonic-gate 
1357c478bd9Sstevel@tonic-gate 			if (access(buf, F_OK) == 0) {
1367c478bd9Sstevel@tonic-gate 				fd = open64(buf, flags, mode);
1377c478bd9Sstevel@tonic-gate 				fname = buf;
1387c478bd9Sstevel@tonic-gate 				break;
1397c478bd9Sstevel@tonic-gate 			}
1407c478bd9Sstevel@tonic-gate 		}
1417c478bd9Sstevel@tonic-gate 
1427c478bd9Sstevel@tonic-gate 		if (fd == -1)
1437c478bd9Sstevel@tonic-gate 			(void) set_errno(ENOENT);
1447c478bd9Sstevel@tonic-gate 	} else
1457c478bd9Sstevel@tonic-gate 		fd = open64(fname, flags, mode);
1467c478bd9Sstevel@tonic-gate 
1477c478bd9Sstevel@tonic-gate 	if (fd >= 0)
1487c478bd9Sstevel@tonic-gate 		return (mdb_fdio_create_named(fd, fname));
1497c478bd9Sstevel@tonic-gate 
1507c478bd9Sstevel@tonic-gate 	return (NULL);
1517c478bd9Sstevel@tonic-gate }
1527c478bd9Sstevel@tonic-gate 
1537c478bd9Sstevel@tonic-gate static const mdb_io_ops_t fdio_file_ops = {
1547c478bd9Sstevel@tonic-gate 	fdio_read,
1557c478bd9Sstevel@tonic-gate 	fdio_write,
1567c478bd9Sstevel@tonic-gate 	fdio_seek,
1577c478bd9Sstevel@tonic-gate 	fdio_ctl,
1587c478bd9Sstevel@tonic-gate 	fdio_close,
1597c478bd9Sstevel@tonic-gate 	fdio_name,
1607c478bd9Sstevel@tonic-gate 	no_io_link,
1617c478bd9Sstevel@tonic-gate 	no_io_unlink,
1627c478bd9Sstevel@tonic-gate 	no_io_setattr,
1637c478bd9Sstevel@tonic-gate 	no_io_suspend,
1647c478bd9Sstevel@tonic-gate 	no_io_resume
1657c478bd9Sstevel@tonic-gate };
1667c478bd9Sstevel@tonic-gate 
167*b55a30d7SToomas Soome /*
168*b55a30d7SToomas Soome  * Read media logical block size. On error, return DEV_BSIZE.
169*b55a30d7SToomas Soome  */
170*b55a30d7SToomas Soome static uint_t
171*b55a30d7SToomas Soome fdio_bdev_info(int fd)
172*b55a30d7SToomas Soome {
173*b55a30d7SToomas Soome 	struct dk_minfo disk_info;
174*b55a30d7SToomas Soome 
175*b55a30d7SToomas Soome 	if ((ioctl(fd, DKIOCGMEDIAINFO, (caddr_t)&disk_info)) == -1)
176*b55a30d7SToomas Soome 		return (DEV_BSIZE);
177*b55a30d7SToomas Soome 
178*b55a30d7SToomas Soome 	return (disk_info.dki_lbsize);
179*b55a30d7SToomas Soome }
180*b55a30d7SToomas Soome 
1817c478bd9Sstevel@tonic-gate /*
1827c478bd9Sstevel@tonic-gate  * In order to read from a block-oriented device, we pick up the seek pointer,
1837c478bd9Sstevel@tonic-gate  * read each containing block, and then copy the desired range of bytes back
184*b55a30d7SToomas Soome  * into the caller's buffer. At the end of the transfer we reset the seek
185*b55a30d7SToomas Soome  * pointer to where the caller thinks it should be.
1867c478bd9Sstevel@tonic-gate  */
1877c478bd9Sstevel@tonic-gate static ssize_t
1887c478bd9Sstevel@tonic-gate fdio_bdev_read(mdb_io_t *io, void *buf, size_t nbytes)
1897c478bd9Sstevel@tonic-gate {
1907c478bd9Sstevel@tonic-gate 	fd_data_t *fdp = io->io_data;
1917c478bd9Sstevel@tonic-gate 	ssize_t resid = nbytes;
192*b55a30d7SToomas Soome 	size_t blksize;
193*b55a30d7SToomas Soome 	uchar_t *blk;
1947c478bd9Sstevel@tonic-gate 	off64_t off;
1957c478bd9Sstevel@tonic-gate 
1967c478bd9Sstevel@tonic-gate 	if (io->io_next != NULL)
1977c478bd9Sstevel@tonic-gate 		return (IOP_READ(io->io_next, buf, nbytes));
1987c478bd9Sstevel@tonic-gate 
1997c478bd9Sstevel@tonic-gate 	if ((off = lseek64(fdp->fd_fd, 0, SEEK_CUR)) == -1)
2007c478bd9Sstevel@tonic-gate 		return (-1); /* errno is set for us */
2017c478bd9Sstevel@tonic-gate 
202*b55a30d7SToomas Soome 	blksize = fdio_bdev_info(fdp->fd_fd);
203*b55a30d7SToomas Soome 	blk = mdb_zalloc(blksize, UM_SLEEP | UM_GC);
2047c478bd9Sstevel@tonic-gate 	while (resid != 0) {
205*b55a30d7SToomas Soome 		off64_t devoff = off & ~(blksize - 1);
206*b55a30d7SToomas Soome 		size_t blkoff = off & (blksize - 1);
207*b55a30d7SToomas Soome 		size_t len = MIN(resid, blksize - blkoff);
2087c478bd9Sstevel@tonic-gate 
209*b55a30d7SToomas Soome 		if (pread64(fdp->fd_fd, blk, blksize, devoff) != blksize)
2107c478bd9Sstevel@tonic-gate 			break; /* errno is set for us, unless EOF */
2117c478bd9Sstevel@tonic-gate 
2127c478bd9Sstevel@tonic-gate 		bcopy(&blk[blkoff], buf, len);
2137c478bd9Sstevel@tonic-gate 		resid -= len;
2147c478bd9Sstevel@tonic-gate 		off += len;
2157c478bd9Sstevel@tonic-gate 		buf = (char *)buf + len;
2167c478bd9Sstevel@tonic-gate 	}
2177c478bd9Sstevel@tonic-gate 
2187c478bd9Sstevel@tonic-gate 	if (resid == nbytes && nbytes != 0)
2197c478bd9Sstevel@tonic-gate 		return (set_errno(EMDB_EOF));
2207c478bd9Sstevel@tonic-gate 
2217c478bd9Sstevel@tonic-gate 	(void) lseek64(fdp->fd_fd, off, SEEK_SET);
2227c478bd9Sstevel@tonic-gate 	return (nbytes - resid);
2237c478bd9Sstevel@tonic-gate }
2247c478bd9Sstevel@tonic-gate 
2257c478bd9Sstevel@tonic-gate /*
2267c478bd9Sstevel@tonic-gate  * To perform a write to a block-oriented device, we use the same basic
2277c478bd9Sstevel@tonic-gate  * algorithm as fdio_bdev_read(), above.  In the inner loop, we read an
2287c478bd9Sstevel@tonic-gate  * entire block, modify it using the data from the caller's buffer, and
2297c478bd9Sstevel@tonic-gate  * then write the entire block back to the device.
2307c478bd9Sstevel@tonic-gate  */
2317c478bd9Sstevel@tonic-gate static ssize_t
2327c478bd9Sstevel@tonic-gate fdio_bdev_write(mdb_io_t *io, const void *buf, size_t nbytes)
2337c478bd9Sstevel@tonic-gate {
2347c478bd9Sstevel@tonic-gate 	fd_data_t *fdp = io->io_data;
2357c478bd9Sstevel@tonic-gate 	ssize_t resid = nbytes;
236*b55a30d7SToomas Soome 	size_t blksize;
237*b55a30d7SToomas Soome 	uchar_t *blk;
2387c478bd9Sstevel@tonic-gate 	off64_t off;
2397c478bd9Sstevel@tonic-gate 
2407c478bd9Sstevel@tonic-gate 	if (io->io_next != NULL)
2417c478bd9Sstevel@tonic-gate 		return (IOP_WRITE(io->io_next, buf, nbytes));
2427c478bd9Sstevel@tonic-gate 
2437c478bd9Sstevel@tonic-gate 	if ((off = lseek64(fdp->fd_fd, 0, SEEK_CUR)) == -1)
2447c478bd9Sstevel@tonic-gate 		return (-1); /* errno is set for us */
2457c478bd9Sstevel@tonic-gate 
246*b55a30d7SToomas Soome 	blksize = fdio_bdev_info(fdp->fd_fd);
247*b55a30d7SToomas Soome 	blk = mdb_zalloc(blksize, UM_SLEEP | UM_GC);
2487c478bd9Sstevel@tonic-gate 	while (resid != 0) {
249*b55a30d7SToomas Soome 		off64_t devoff = off & ~(blksize - 1);
250*b55a30d7SToomas Soome 		size_t blkoff = off & (blksize - 1);
251*b55a30d7SToomas Soome 		size_t len = MIN(resid, blksize - blkoff);
2527c478bd9Sstevel@tonic-gate 
253*b55a30d7SToomas Soome 		if (pread64(fdp->fd_fd, blk, blksize, devoff) != blksize)
2547c478bd9Sstevel@tonic-gate 			break; /* errno is set for us, unless EOF */
2557c478bd9Sstevel@tonic-gate 
2567c478bd9Sstevel@tonic-gate 		bcopy(buf, &blk[blkoff], len);
2577c478bd9Sstevel@tonic-gate 
258*b55a30d7SToomas Soome 		if (pwrite64(fdp->fd_fd, blk, blksize, devoff) != blksize)
2597c478bd9Sstevel@tonic-gate 			break; /* errno is set for us, unless EOF */
2607c478bd9Sstevel@tonic-gate 
2617c478bd9Sstevel@tonic-gate 		resid -= len;
2627c478bd9Sstevel@tonic-gate 		off += len;
2637c478bd9Sstevel@tonic-gate 		buf = (char *)buf + len;
2647c478bd9Sstevel@tonic-gate 	}
2657c478bd9Sstevel@tonic-gate 
2667c478bd9Sstevel@tonic-gate 	if (resid == nbytes && nbytes != 0)
2677c478bd9Sstevel@tonic-gate 		return (set_errno(EMDB_EOF));
2687c478bd9Sstevel@tonic-gate 
2697c478bd9Sstevel@tonic-gate 	(void) lseek64(fdp->fd_fd, off, SEEK_SET);
2707c478bd9Sstevel@tonic-gate 	return (nbytes - resid);
2717c478bd9Sstevel@tonic-gate }
2727c478bd9Sstevel@tonic-gate 
2737c478bd9Sstevel@tonic-gate static const mdb_io_ops_t fdio_bdev_ops = {
2747c478bd9Sstevel@tonic-gate 	fdio_bdev_read,
2757c478bd9Sstevel@tonic-gate 	fdio_bdev_write,
2767c478bd9Sstevel@tonic-gate 	fdio_seek,
2777c478bd9Sstevel@tonic-gate 	fdio_ctl,
2787c478bd9Sstevel@tonic-gate 	fdio_close,
2797c478bd9Sstevel@tonic-gate 	fdio_name,
2807c478bd9Sstevel@tonic-gate 	no_io_link,
2817c478bd9Sstevel@tonic-gate 	no_io_unlink,
2827c478bd9Sstevel@tonic-gate 	no_io_setattr,
2837c478bd9Sstevel@tonic-gate 	no_io_suspend,
2847c478bd9Sstevel@tonic-gate 	no_io_resume
2857c478bd9Sstevel@tonic-gate };
2867c478bd9Sstevel@tonic-gate 
2877c478bd9Sstevel@tonic-gate mdb_io_t *
2887c478bd9Sstevel@tonic-gate mdb_fdio_create(int fd)
2897c478bd9Sstevel@tonic-gate {
2907c478bd9Sstevel@tonic-gate 	mdb_io_t *io = mdb_alloc(sizeof (mdb_io_t), UM_SLEEP);
2917c478bd9Sstevel@tonic-gate 	fd_data_t *fdp = mdb_alloc(sizeof (fd_data_t), UM_SLEEP);
2927c478bd9Sstevel@tonic-gate 
2937c478bd9Sstevel@tonic-gate 	struct dk_cinfo info;
2947c478bd9Sstevel@tonic-gate 	struct stat64 st;
2957c478bd9Sstevel@tonic-gate 
2967c478bd9Sstevel@tonic-gate 	switch (fd) {
2977c478bd9Sstevel@tonic-gate 	case STDIN_FILENO:
2987c478bd9Sstevel@tonic-gate 		(void) strcpy(fdp->fd_name, "(stdin)");
2997c478bd9Sstevel@tonic-gate 		break;
3007c478bd9Sstevel@tonic-gate 	case STDOUT_FILENO:
3017c478bd9Sstevel@tonic-gate 		(void) strcpy(fdp->fd_name, "(stdout)");
3027c478bd9Sstevel@tonic-gate 		break;
3037c478bd9Sstevel@tonic-gate 	case STDERR_FILENO:
3047c478bd9Sstevel@tonic-gate 		(void) strcpy(fdp->fd_name, "(stderr)");
3057c478bd9Sstevel@tonic-gate 		break;
3067c478bd9Sstevel@tonic-gate 	default:
3077c478bd9Sstevel@tonic-gate 		(void) mdb_iob_snprintf(fdp->fd_name, MAXPATHLEN, "fd %d", fd);
3087c478bd9Sstevel@tonic-gate 	}
3097c478bd9Sstevel@tonic-gate 
3107c478bd9Sstevel@tonic-gate 	fdp->fd_fd = fd;
3117c478bd9Sstevel@tonic-gate 
3127c478bd9Sstevel@tonic-gate 	/*
3137c478bd9Sstevel@tonic-gate 	 * We determine if something is a raw block-oriented disk device by
3147c478bd9Sstevel@tonic-gate 	 * testing to see if it is a character device that supports DKIOCINFO.
3157c478bd9Sstevel@tonic-gate 	 * If we are operating on a disk in raw mode, we must do our own
3167c478bd9Sstevel@tonic-gate 	 * block-oriented i/o; otherwise we can just use read() and write().
3177c478bd9Sstevel@tonic-gate 	 */
3187c478bd9Sstevel@tonic-gate 	if (fstat64(fd, &st) == 0 && S_ISCHR(st.st_mode) &&
3197c478bd9Sstevel@tonic-gate 	    ioctl(fd, DKIOCINFO, &info) == 0)
3207c478bd9Sstevel@tonic-gate 		io->io_ops = &fdio_bdev_ops;
3217c478bd9Sstevel@tonic-gate 	else
3227c478bd9Sstevel@tonic-gate 		io->io_ops = &fdio_file_ops;
3237c478bd9Sstevel@tonic-gate 
3247c478bd9Sstevel@tonic-gate 	io->io_data = fdp;
3257c478bd9Sstevel@tonic-gate 	io->io_next = NULL;
3267c478bd9Sstevel@tonic-gate 	io->io_refcnt = 0;
3277c478bd9Sstevel@tonic-gate 
3287c478bd9Sstevel@tonic-gate 	return (io);
3297c478bd9Sstevel@tonic-gate }
3307c478bd9Sstevel@tonic-gate 
3317c478bd9Sstevel@tonic-gate mdb_io_t *
3327c478bd9Sstevel@tonic-gate mdb_fdio_create_named(int fd, const char *name)
3337c478bd9Sstevel@tonic-gate {
3347c478bd9Sstevel@tonic-gate 	mdb_io_t *io = mdb_fdio_create(fd);
3357c478bd9Sstevel@tonic-gate 	fd_data_t *fdp = io->io_data;
3367c478bd9Sstevel@tonic-gate 
3377c478bd9Sstevel@tonic-gate 	(void) strncpy(fdp->fd_name, name, MAXPATHLEN);
3387c478bd9Sstevel@tonic-gate 	fdp->fd_name[MAXPATHLEN - 1] = '\0';
3397c478bd9Sstevel@tonic-gate 
3407c478bd9Sstevel@tonic-gate 	return (io);
3417c478bd9Sstevel@tonic-gate }
342a576ab5bSrab 
343a576ab5bSrab int
344a576ab5bSrab mdb_fdio_fileno(mdb_io_t *io)
345a576ab5bSrab {
346a576ab5bSrab 	fd_data_t *fdp = io->io_data;
347a576ab5bSrab 	return (fdp->fd_fd);
348a576ab5bSrab }
349