summaryrefslogtreecommitdiffstats
path: root/src/lib/krb5/os/net_write.c
diff options
context:
space:
mode:
authorKen Raeburn <raeburn@mit.edu>2009-01-15 00:59:27 +0000
committerKen Raeburn <raeburn@mit.edu>2009-01-15 00:59:27 +0000
commitc3fd8c6bb3d78fe4b4f70afcd2df62f83d187e66 (patch)
treef362314e858f67b9cabc8433d02dbd73c27b0526 /src/lib/krb5/os/net_write.c
parent97af03eeb1b4ba7a982d066d8e3dbdc211892083 (diff)
downloadkrb5-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.c51
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;
}