diff options
author | andre <andre@FreeBSD.org> | 2007-01-22 14:50:28 +0000 |
---|---|---|
committer | andre <andre@FreeBSD.org> | 2007-01-22 14:50:28 +0000 |
commit | 4a22f82e6c50a7bc72683c16a7b8ea6a6d5624e4 (patch) | |
tree | 009f291772a96599f4355c88f4107f582f4c3661 /sys | |
parent | 3530b41545d66416a3c151e414ce5b1e7b3da0e6 (diff) | |
download | FreeBSD-src-4a22f82e6c50a7bc72683c16a7b8ea6a6d5624e4.zip FreeBSD-src-4a22f82e6c50a7bc72683c16a7b8ea6a6d5624e4.tar.gz |
Unbreak writes of 0 bytes. Zero byte writes happen when only ancillary
control data but no payload data is passed.
Change m_uiotombuf() to return at least one empty mbuf if the requested
length was zero. Add comment to sosend_dgram and sosend_generic().
Diagnoses by: jhb
Regression test by: rwatson
Pointy hat to. andre
Diffstat (limited to 'sys')
-rw-r--r-- | sys/kern/uipc_mbuf.c | 7 | ||||
-rw-r--r-- | sys/kern/uipc_socket.c | 10 |
2 files changed, 15 insertions, 2 deletions
diff --git a/sys/kern/uipc_mbuf.c b/sys/kern/uipc_mbuf.c index 4161ac8..e9ff7b0 100644 --- a/sys/kern/uipc_mbuf.c +++ b/sys/kern/uipc_mbuf.c @@ -1643,8 +1643,11 @@ m_uiotombuf(struct uio *uio, int how, int len, int align, int flags) if (align >= MHLEN) return (NULL); - /* Give us all or nothing. */ - m = m_getm2(NULL, total + align, how, MT_DATA, flags); + /* + * Give us the full allocation or nothing. + * If len is zero return the smallest empty mbuf. + */ + m = m_getm2(NULL, max(total + align, 1), how, MT_DATA, flags); if (m == NULL) return (NULL); m->m_data += align; diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c index a87d04f..d1ce038 100644 --- a/sys/kern/uipc_socket.c +++ b/sys/kern/uipc_socket.c @@ -1055,6 +1055,11 @@ sosend_dgram(so, addr, uio, top, control, flags, td) if (error) goto out; #else + /* + * Copy the data from userland into a mbuf chain. + * If no data is to be copied in, a single empty mbuf + * is returned. + */ top = m_uiotombuf(uio, M_WAITOK, space, max_hdr, (M_PKTHDR | ((flags & MSG_EOR) ? M_EOR : 0))); if (top == NULL) { @@ -1230,6 +1235,11 @@ restart: goto release; } #else + /* + * Copy the data from userland into a mbuf + * chain. If no data is to be copied in, + * a single empty mbuf is returned. + */ top = m_uiotombuf(uio, M_WAITOK, space, (atomic ? max_hdr : 0), (atomic ? M_PKTHDR : 0) | |