Subject: FIONWRITE proposal
To: None <tech-kern@netbsd.org>
From: Bill Studenmund <wrstuden@netbsd.org>
List: tech-kern
Date: 10/13/2004 16:11:12
--GpGaEY17fSl8rd50
Content-Type: multipart/mixed; boundary="HG+GLK89HZ1zG0kk"
Content-Disposition: inline


--HG+GLK89HZ1zG0kk
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

I'd like to propose a new ioctl, to be called FIONWRITE.

This ioctl is like FIONREAD, except instead of looking at the read queue,=
=20
it looks at how many bytes are in the write queue.

The semantic for the value is that it returns the number of bytes written=
=20
to the file descriptor that have not been "sent". If someone can come up=20
with a better description, I'm all ears. :-)

I want this call because I have an application which needs to do
scheduling flow control in userland. I can't just depend on a non-blocking
socket as the protocol I'm using deals with requests (protocol blocks or
PDUs, etc.). So once you start sending a request, you have to finish it.
For some things, I'd like to be able to make a decision about sending
before I commit to sending the specific PDU.

Thus this ioctl.

Thoughts?

Take care,

Bill

--HG+GLK89HZ1zG0kk
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="FIONWRITE.diffs"
Content-Transfer-Encoding: quoted-printable

? diffies
? lib/cvslog
? sys/cvslog
Index: lib/libc/sys/ioctl.2
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /cvsroot/src/lib/libc/sys/ioctl.2,v
retrieving revision 1.18
diff -u -r1.18 ioctl.2
--- lib/libc/sys/ioctl.2	13 May 2004 10:20:58 -0000	1.18
+++ lib/libc/sys/ioctl.2	13 Oct 2004 20:44:42 -0000
@@ -89,6 +89,9 @@
 .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 written to the descriptor which have
+not been sent.
 .It Dv FIONBIO "int"
 Set non-blocking I/O mode if the argument is non-zero.
 In non-blocking mode,
Index: sys/kern/sys_pipe.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /cvsroot/src/sys/kern/sys_pipe.c,v
retrieving revision 1.58
diff -u -r1.58 sys_pipe.c
--- sys/kern/sys_pipe.c	17 Jul 2004 20:50:08 -0000	1.58
+++ sys/kern/sys_pipe.c	13 Oct 2004 20:44:57 -0000
@@ -1141,6 +1141,19 @@
 		PIPE_UNLOCK(pipe);
 		return (0);
=20
+	case FIONWRITE:
+		/* Look at other side */
+		pipe =3D pipe->pipe_peer;
+		PIPE_LOCK(pipe);
+#ifndef PIPE_NODIRECT
+		if (pipe->pipe_state & PIPE_DIRECTW)
+			*(int *)data =3D pipe->pipe_map.cnt;
+		else
+#endif
+			*(int *)data =3D pipe->pipe_buffer.cnt;
+		PIPE_UNLOCK(pipe);
+		return (0);
+
 	case TIOCSPGRP:
 	case FIOSETOWN:
 		return fsetown(p, &pipe->pipe_pgid, cmd, data);
Index: sys/kern/sys_socket.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /cvsroot/src/sys/kern/sys_socket.c,v
retrieving revision 1.40
diff -u -r1.40 sys_socket.c
--- sys/kern/sys_socket.c	22 May 2004 22:52:13 -0000	1.40
+++ sys/kern/sys_socket.c	13 Oct 2004 20:44:57 -0000
@@ -116,6 +116,10 @@
 		*(int *)data =3D so->so_rcv.sb_cc;
 		return (0);
=20
+	case FIONWRITE:
+		*(int *)data =3D so->so_snd.sb_cc;
+		return (0);
+
 	case SIOCSPGRP:
 	case FIOSETOWN:
 	case TIOCSPGRP:
Index: sys/kern/tty.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /cvsroot/src/sys/kern/tty.c,v
retrieving revision 1.168
diff -u -r1.168 tty.c
--- sys/kern/tty.c	25 May 2004 04:30:32 -0000	1.168
+++ sys/kern/tty.c	13 Oct 2004 20:44:57 -0000
@@ -880,6 +880,13 @@
 		TTY_UNLOCK(tp);
 		splx(s);
 		break;
+	case FIONWRITE:			/* get # bytes to written & unsent */
+		s =3D spltty();
+		TTY_LOCK(tp);
+		*(int *)data =3D tp->t_outq.c_cc;
+		TTY_UNLOCK(tp);
+		splx(s);
+		break;
 	case TIOCEXCL:			/* set exclusive use of tty */
 		s =3D spltty();
 		TTY_LOCK(tp);
Index: sys/kern/vfs_vnops.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /cvsroot/src/sys/kern/vfs_vnops.c,v
retrieving revision 1.80
diff -u -r1.80 vfs_vnops.c
--- sys/kern/vfs_vnops.c	31 May 2004 09:02:51 -0000	1.80
+++ sys/kern/vfs_vnops.c	13 Oct 2004 20:44:58 -0000
@@ -692,6 +692,14 @@
 			*(int *)data =3D vattr.va_size - fp->f_offset;
 			return (0);
 		}
+		if (com =3D=3D FIONWRITE) {
+			/*
+			 * Files don't have the semantic of unsent bytes,
+			 * so say all written bytes are "sent".
+			 */
+			*(int *)data =3D 0;
+			return (0);
+		}
 		if (com =3D=3D FIOGETBMAP) {
 			daddr_t *block;
=20
Index: sys/sys/filio.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /cvsroot/src/sys/sys/filio.h,v
retrieving revision 1.8
diff -u -r1.8 filio.h
--- sys/sys/filio.h	7 Aug 2003 16:34:04 -0000	1.8
+++ sys/sys/filio.h	13 Oct 2004 20:44:58 -0000
@@ -51,6 +51,9 @@
 #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 # written bytes
+						 * still outstanding for send */
+
=20
 /* Ugly symbol for compatibility with other operating systems */
 #define	FIBMAP		FIOGETBMAP

--HG+GLK89HZ1zG0kk--

--GpGaEY17fSl8rd50
Content-Type: application/pgp-signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.3 (NetBSD)

iD8DBQFBbbYQWz+3JHUci9cRAvJKAJ9Hm14gM5uQ7Q7RiuiYMRp2J7Tc0gCfemQe
5TuEhpCChptHB9a/8bC4AuA=
=upwJ
-----END PGP SIGNATURE-----

--GpGaEY17fSl8rd50--