diff options
author | Ken Raeburn <raeburn@mit.edu> | 2009-01-15 00:59:27 +0000 |
---|---|---|
committer | Ken Raeburn <raeburn@mit.edu> | 2009-01-15 00:59:27 +0000 |
commit | c3fd8c6bb3d78fe4b4f70afcd2df62f83d187e66 (patch) | |
tree | f362314e858f67b9cabc8433d02dbd73c27b0526 /src/lib/krb5/os/net_write.c | |
parent | 97af03eeb1b4ba7a982d066d8e3dbdc211892083 (diff) | |
download | krb5-c3fd8c6bb3d78fe4b4f70afcd2df62f83d187e66.tar.gz krb5-c3fd8c6bb3d78fe4b4f70afcd2df62f83d187e66.tar.xz krb5-c3fd8c6bb3d78fe4b4f70afcd2df62f83d187e66.zip |
Add new routine krb5int_net_writev using scatter-gather source.
Use it from krb5_net_write to ensure testing and reduce duplication.
Use it from krb5_write_message to avoid Nagle+DelayedAck problem.
ticket: 6339
git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@21749 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src/lib/krb5/os/net_write.c')
-rw-r--r-- | src/lib/krb5/os/net_write.c | 51 |
1 files changed, 36 insertions, 15 deletions
diff --git a/src/lib/krb5/os/net_write.c b/src/lib/krb5/os/net_write.c index e4981543aa..35765fb387 100644 --- a/src/lib/krb5/os/net_write.c +++ b/src/lib/krb5/os/net_write.c @@ -1,7 +1,7 @@ /* * lib/krb5/os/net_write.c * - * Copyright 1987, 1988, 1990 by the Massachusetts Institute of Technology. + * Copyright 1987, 1988, 1990, 2009 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may @@ -26,6 +26,7 @@ */ #include "k5-int.h" +#include "os-proto.h" /* * krb5_net_write() writes "len" bytes from "buf" to the file @@ -37,25 +38,45 @@ */ int -krb5_net_write(krb5_context context, int fd, register const char *buf, int len) +krb5_net_write(krb5_context context, int fd, const char *buf, int len) { - int cc; - register int wrlen = len; - do { - cc = SOCKET_WRITE((SOCKET)fd, buf, wrlen); + sg_buf sg; + SG_SET(&sg, buf, len); + return krb5int_net_writev(context, fd, &sg, 1); +} + +int +krb5int_net_writev(krb5_context context, int fd, sg_buf *sgp, int nsg) +{ + int cc, len = 0; + SOCKET_WRITEV_TEMP tmp; + + while (nsg > 0) { + /* Skip any empty data blocks. */ + if (SG_LEN(sgp) == 0) { + sgp++, nsg--; + continue; + } + cc = SOCKET_WRITEV((SOCKET)fd, sgp, nsg, tmp); if (cc < 0) { if (SOCKET_ERRNO == SOCKET_EINTR) continue; - /* XXX this interface sucks! */ - errno = SOCKET_ERRNO; - - return(cc); + /* XXX this interface sucks! */ + errno = SOCKET_ERRNO; + return -1; } - else { - buf += cc; - wrlen -= cc; + len += cc; + while (cc > 0) { + if ((unsigned)cc < SG_LEN(sgp)) { + SG_ADVANCE(sgp, (unsigned)cc); + cc = 0; + } else { + cc -= SG_LEN(sgp); + sgp++, nsg--; + assert(nsg > 0 || cc == 0); + } } - } while (wrlen > 0); - return(len); + } + return len; } |