diff --git a/lib/libc/sys/ioctl.2 b/lib/libc/sys/ioctl.2 index 5de5116cfaf8..3d2d76a22356 100644 --- a/lib/libc/sys/ioctl.2 +++ b/lib/libc/sys/ioctl.2 @@ -1,4 +1,4 @@ -.\" $NetBSD: ioctl.2,v 1.18 2004/05/13 10:20:58 wiz Exp $ +.\" $NetBSD: ioctl.2,v 1.19 2004/11/06 02:03:20 wrstuden Exp $ .\" .\" Copyright (c) 1980, 1991, 1993 .\" The Regents of the University of California. All rights reserved. @@ -89,6 +89,26 @@ These include: .Bl -tag -width "xxxxxx" .It Dv FIONREAD "int" Get the number of bytes that are immediately available for reading. +.It Dv FIONWRITE "int" +Get the number of bytes in the descriptor's send queue. +These bytes are data which has been written to the descriptor but +which are being held by the kernel for further processing. +The nature of the required processing depends on the underlying device. +For tty devices, these bytes are typically queued for delivery +to the tty hardware. +For TCP sockets, these bytes have not yet been acknolwedged by the +other side of the connection. +For files, this operation always returns zero as files do not have +send queues. +.It Dv FIONSPACE "int" +Get the free space in the descriptor's send queue. +This value is the size of the send queue minus the number of bytes +being held in the queue. +Note: while this value represents the number of bytes that may be +added to the queue, other resource limitations may cause a write +not larger than the send queue's space to be blocked. +One such limitation would be a lack of network buffers for a write +to a network connection. .It Dv FIONBIO "int" Set non-blocking I/O mode if the argument is non-zero. In non-blocking mode, diff --git a/sys/kern/sys_pipe.c b/sys/kern/sys_pipe.c index 69a4e7cbbc0b..2bbd3e47e339 100644 --- a/sys/kern/sys_pipe.c +++ b/sys/kern/sys_pipe.c @@ -1,4 +1,4 @@ -/* $NetBSD: sys_pipe.c,v 1.58 2004/07/17 20:50:08 mycroft Exp $ */ +/* $NetBSD: sys_pipe.c,v 1.59 2004/11/06 02:03:20 wrstuden Exp $ */ /*- * Copyright (c) 2003 The NetBSD Foundation, Inc. @@ -83,7 +83,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: sys_pipe.c,v 1.58 2004/07/17 20:50:08 mycroft Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sys_pipe.c,v 1.59 2004/11/06 02:03:20 wrstuden Exp $"); #include #include @@ -1141,6 +1141,38 @@ pipe_ioctl(fp, cmd, data, p) PIPE_UNLOCK(pipe); return (0); + case FIONWRITE: + /* Look at other side */ + pipe = pipe->pipe_peer; + PIPE_LOCK(pipe); +#ifndef PIPE_NODIRECT + if (pipe->pipe_state & PIPE_DIRECTW) + *(int *)data = pipe->pipe_map.cnt; + else +#endif + *(int *)data = pipe->pipe_buffer.cnt; + PIPE_UNLOCK(pipe); + return (0); + + case FIONSPACE: + /* Look at other side */ + pipe = pipe->pipe_peer; + PIPE_LOCK(pipe); +#ifndef PIPE_NODIRECT + /* + * If we're in direct-mode, we don't really have a + * send queue, and any other write will block. Thus + * zero seems like the best answer. + */ + if (pipe->pipe_state & PIPE_DIRECTW) + *(int *)data = 0; + else +#endif + *(int *)data = pipe->pipe_buffer.size - + pipe->pipe_buffer.cnt; + PIPE_UNLOCK(pipe); + return (0); + case TIOCSPGRP: case FIOSETOWN: return fsetown(p, &pipe->pipe_pgid, cmd, data); diff --git a/sys/kern/sys_socket.c b/sys/kern/sys_socket.c index 099e0ef2bfef..fd063a216ab0 100644 --- a/sys/kern/sys_socket.c +++ b/sys/kern/sys_socket.c @@ -1,4 +1,4 @@ -/* $NetBSD: sys_socket.c,v 1.40 2004/05/22 22:52:13 jonathan Exp $ */ +/* $NetBSD: sys_socket.c,v 1.41 2004/11/06 02:03:20 wrstuden Exp $ */ /* * Copyright (c) 1982, 1986, 1990, 1993 @@ -32,7 +32,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: sys_socket.c,v 1.40 2004/05/22 22:52:13 jonathan Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sys_socket.c,v 1.41 2004/11/06 02:03:20 wrstuden Exp $"); #include #include @@ -116,6 +116,24 @@ soo_ioctl(fp, cmd, data, p) *(int *)data = so->so_rcv.sb_cc; return (0); + case FIONWRITE: + *(int *)data = so->so_snd.sb_cc; + return (0); + + case FIONSPACE: + /* + * See the comment around sbspace()'s definition + * in sys/socketvar.h in face of counts about maximum + * to understand the following test. We detect overflow + * and return zero. + */ + if ((so->snd.sb_hiwat < so->snd.sb_cc) + || (so->snd.sb_mbmax < so->snd.sb_mbcnt)) + *(int *)data = 0; + else + *(int *)data = sbspace(so->so_snd); + return (0); + case SIOCSPGRP: case FIOSETOWN: case TIOCSPGRP: diff --git a/sys/kern/tty.c b/sys/kern/tty.c index 3984b5cc1376..8d76c031f47e 100644 --- a/sys/kern/tty.c +++ b/sys/kern/tty.c @@ -1,4 +1,4 @@ -/* $NetBSD: tty.c,v 1.169 2004/10/15 07:15:39 thorpej Exp $ */ +/* $NetBSD: tty.c,v 1.170 2004/11/06 02:03:20 wrstuden Exp $ */ /*- * Copyright (c) 1982, 1986, 1990, 1991, 1993 @@ -37,7 +37,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: tty.c,v 1.169 2004/10/15 07:15:39 thorpej Exp $"); +__KERNEL_RCSID(0, "$NetBSD: tty.c,v 1.170 2004/11/06 02:03:20 wrstuden Exp $"); #include #include @@ -880,6 +880,20 @@ ttioctl(struct tty *tp, u_long cmd, caddr_t data, int flag, struct proc *p) TTY_UNLOCK(tp); splx(s); break; + case FIONWRITE: /* get # bytes to written & unsent */ + s = spltty(); + TTY_LOCK(tp); + *(int *)data = tp->t_outq.c_cc; + TTY_UNLOCK(tp); + splx(s); + break; + case FIONSPACE: /* get # bytes to written & unsent */ + s = spltty(); + TTY_LOCK(tp); + *(int *)data = tp->t_outq.c_cn - tp->t_outq.c_cc; + TTY_UNLOCK(tp); + splx(s); + break; case TIOCEXCL: /* set exclusive use of tty */ s = spltty(); TTY_LOCK(tp); diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c index 35678b1a7302..32365b9fd599 100644 --- a/sys/kern/vfs_vnops.c +++ b/sys/kern/vfs_vnops.c @@ -1,4 +1,4 @@ -/* $NetBSD: vfs_vnops.c,v 1.80 2004/05/31 09:02:51 yamt Exp $ */ +/* $NetBSD: vfs_vnops.c,v 1.81 2004/11/06 02:03:20 wrstuden Exp $ */ /* * Copyright (c) 1982, 1986, 1989, 1993 @@ -37,7 +37,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: vfs_vnops.c,v 1.80 2004/05/31 09:02:51 yamt Exp $"); +__KERNEL_RCSID(0, "$NetBSD: vfs_vnops.c,v 1.81 2004/11/06 02:03:20 wrstuden Exp $"); #include "fs_union.h" @@ -692,6 +692,15 @@ vn_ioctl(fp, com, data, p) *(int *)data = vattr.va_size - fp->f_offset; return (0); } + if ((com == FIONWRITE) || (comm == FIONSPACE)) { + /* + * Files don't have send queues, so there never + * are any bytes in them, nor is there any + * open space in them. + */ + *(int *)data = 0; + return (0); + } if (com == FIOGETBMAP) { daddr_t *block; diff --git a/sys/sys/filio.h b/sys/sys/filio.h index e9f478fa9248..aa64f167ea4a 100644 --- a/sys/sys/filio.h +++ b/sys/sys/filio.h @@ -1,4 +1,4 @@ -/* $NetBSD: filio.h,v 1.8 2003/08/07 16:34:04 agc Exp $ */ +/* $NetBSD: filio.h,v 1.9 2004/11/06 02:03:20 wrstuden Exp $ */ /*- * Copyright (c) 1982, 1986, 1990, 1993, 1994 @@ -51,6 +51,10 @@ #define FIOGETOWN _IOR('f', 123, int) /* get owner */ #define OFIOGETBMAP _IOWR('f', 122, uint32_t) /* get underlying block no. */ #define FIOGETBMAP _IOWR('f', 122, daddr_t) /* get underlying block no. */ +#define FIONWRITE _IOR('f', 121, int) /* get # bytes outstanding + * in send queue. */ +#define FIONSPACE _IOR('f', 120, int) /* get space in send queue. */ + /* Ugly symbol for compatibility with other operating systems */ #define FIBMAP FIOGETBMAP