diff --git a/CHANGELOG b/CHANGELOG index 4876c42a..02ec9030 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -6,6 +6,10 @@ HISTORY ++ New features: + 2011-07-21: Simon Goldschmidt + * sockets.c, opt.h: (bug #30185): added LWIP_FIONREAD_LINUXMODE that makes + ioctl/FIONREAD return the size of the next pending datagram. + 2011-06-26: Simon Goldschmidt (patch by Cameron Gutman) * tcp.c, tcp_out.c: bug #33604: added some more asserts to check that pcb->state != LISTEN diff --git a/src/api/sockets.c b/src/api/sockets.c index 9af71c4e..ba68e726 100644 --- a/src/api/sockets.c +++ b/src/api/sockets.c @@ -2330,13 +2330,38 @@ lwip_ioctl(int s, long cmd, void *argp) } switch (cmd) { -#if LWIP_SO_RCVBUF +#if LWIP_SO_RCVBUF || LWIP_FIONREAD_LINUXMODE case FIONREAD: if (!argp) { sock_set_errno(sock, EINVAL); return -1; } +#if LWIP_FIONREAD_LINUXMODE + if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_TCP) { + struct pbuf *p; + if (sock->lastdata) { + p = ((struct netbuf *)sock->lastdata)->p; + } else { + struct netbuf *rxbuf; + err_t err; + if (sock->rcvevent <= 0) { + *((u16_t*)argp) = 0; + } else { + err = netconn_recv(sock->conn, &rxbuf); + if (err != ERR_OK) { + *((u16_t*)argp) = 0; + } else { + sock->lastdata = rxbuf; + *((u16_t*)argp) = rxbuf->p->tot_len; + } + } + } + return 0; + } +#endif /* LWIP_FIONREAD_LINUXMODE */ +#if LWIP_SO_RCVBUF + /* we come here if either LWIP_FIONREAD_LINUXMODE==0 or this is a TCP socket */ SYS_ARCH_GET(sock->conn->recv_avail, recv_avail); if (recv_avail < 0) { recv_avail = 0; @@ -2358,7 +2383,10 @@ lwip_ioctl(int s, long cmd, void *argp) LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_ioctl(%d, FIONREAD, %p) = %"U16_F"\n", s, argp, *((u16_t*)argp))); sock_set_errno(sock, 0); return 0; +#else /* LWIP_SO_RCVBUF */ + break; #endif /* LWIP_SO_RCVBUF */ +#endif /* LWIP_SO_RCVBUF || LWIP_FIONREAD_LINUXMODE */ case FIONBIO: val = 0; @@ -2371,10 +2399,11 @@ lwip_ioctl(int s, long cmd, void *argp) return 0; default: - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_ioctl(%d, UNIMPL: 0x%lx, %p)\n", s, cmd, argp)); - sock_set_errno(sock, ENOSYS); /* not yet implemented */ - return -1; + break; } /* switch (cmd) */ + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_ioctl(%d, UNIMPL: 0x%lx, %p)\n", s, cmd, argp)); + sock_set_errno(sock, ENOSYS); /* not yet implemented */ + return -1; } /** A minimal implementation of fcntl. diff --git a/src/include/lwip/opt.h b/src/include/lwip/opt.h index a8243b6a..911b6251 100644 --- a/src/include/lwip/opt.h +++ b/src/include/lwip/opt.h @@ -1443,6 +1443,18 @@ #define SO_REUSE_RXTOALL 0 #endif +/** + * LWIP_FIONREAD_LINUXMODE==0 (default): ioctl/FIONREAD returns the amount of + * pending data in the network buffer. This is the way windows does it. It's + * the default for lwIP since it is smaller. + * LWIP_FIONREAD_LINUXMODE==1: ioctl/FIONREAD returns the size of the next + * pending datagram in bytes. This is the way linux does it. This code is only + * here for compatibility. + */ +#ifndef LWIP_FIONREAD_LINUXMODE +#define LWIP_FIONREAD_LINUXMODE 0 +#endif + /* ---------------------------------------- ---------- Statistics options ----------