summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--pttbbs/common/sys/vbuf.c20
-rw-r--r--pttbbs/include/cmsys.h6
2 files changed, 14 insertions, 12 deletions
diff --git a/pttbbs/common/sys/vbuf.c b/pttbbs/common/sys/vbuf.c
index bbde24a7..4135af71 100644
--- a/pttbbs/common/sys/vbuf.c
+++ b/pttbbs/common/sys/vbuf.c
@@ -319,6 +319,8 @@ vbuf_putblk(VBUF *v, const void *p, size_t sz)
}
/* read/write callbacks */
+// XXX warning: the return value of these callbacks are a little differnet:
+// 0 means 'can continue (EAGAIN)', and -1 means EOF or error.
static ssize_t
vbuf_rw_write(struct iovec iov[2], void *ctx)
@@ -327,8 +329,8 @@ vbuf_rw_write(struct iovec iov[2], void *ctx)
ssize_t ret;
while ( (ret = writev(fd, iov, iov[1].iov_len ? 2 : 1)) < 0 &&
(errno == EINTR));
- if (ret < 0 && errno == EAGAIN)
- ret = 0;
+ if (ret <= 0)
+ ret = (errno == EAGAIN) ? 0 : -1;
return ret;
}
@@ -339,8 +341,8 @@ vbuf_rw_read(struct iovec iov[2], void *ctx)
ssize_t ret;
while ( (ret = readv(fd, iov, iov[1].iov_len ? 2 : 1)) < 0 &&
(errno == EINTR));
- if (ret < 0 && errno == EAGAIN)
- ret = 0;
+ if (ret <= 0)
+ ret = (errno == EAGAIN) ? 0 : -1;
return ret;
}
@@ -351,8 +353,9 @@ vbuf_rw_send(struct iovec iov[2], void *ctx)
ssize_t ret;
while ( (ret = send(fdflag[0], iov[0].iov_base, iov[0].iov_len, fdflag[1])) < 0 &&
(errno == EINTR));
- if (ret < 0 && errno == EAGAIN)
- ret = 0;
+ // TODO also send for iov[1]
+ if (ret <= 0)
+ ret = (errno == EAGAIN) ? 0 : -1;
return ret;
}
@@ -363,8 +366,9 @@ vbuf_rw_recv(struct iovec iov[2], void *ctx)
ssize_t ret;
while ( (ret = recv(fdflag[0], iov[0].iov_base, iov[0].iov_len, fdflag[1])) < 0 &&
(errno == EINTR));
- if (ret < 0 && errno == EAGAIN)
- ret = 0;
+ // TODO also try reading from iov[1] with MSG_DONTWAIT
+ if (ret <= 0)
+ ret = (errno == EAGAIN) ? 0 : -1;
return ret;
}
diff --git a/pttbbs/include/cmsys.h b/pttbbs/include/cmsys.h
index 248201ab..02c2af48 100644
--- a/pttbbs/include/cmsys.h
+++ b/pttbbs/include/cmsys.h
@@ -227,14 +227,12 @@ extern ssize_t vbuf_write(VBUF *v, int fd, ssize_t sz); // write from vbuf to fd
extern ssize_t vbuf_send (VBUF *v, int fd, ssize_t sz, int flags);
extern ssize_t vbuf_recv (VBUF *v, int fd, ssize_t sz, int flags);
-// write from vbuf to writer
+// write from vbuf to writer (writer should return -1 for EOF/error, 0 for EAGAIN)
extern ssize_t vbuf_general_write(VBUF *v, ssize_t sz, void *ctx,
ssize_t (writer)(struct iovec[2], void *ctx));
- // ssize_t (writer)(const void *p[2], size_t len[2], void *ctx));
-// read from reader to vbuf
+// read from reader to vbuf (reader should return -1 for EOF/error, 0 for EAGAIN)
extern ssize_t vbuf_general_read (VBUF *v, ssize_t sz, void *ctx,
ssize_t (reader)(struct iovec[2], void *ctx));
- // ssize_t (reader)(void *p[2], size_t len[2], void *ctx));
/* telnet.c */
struct TelnetCallback {