aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--dpip/dpip.c86
1 files changed, 35 insertions, 51 deletions
diff --git a/dpip/dpip.c b/dpip/dpip.c
index de0a6989..b8392940 100644
--- a/dpip/dpip.c
+++ b/dpip/dpip.c
@@ -259,85 +259,69 @@ Dsh *a_Dpip_dsh_new(int fd_in, int fd_out, int flush_sz)
}
/*
- * Streamed write to socket
- * Return: 0 on success, 1 on error.
+ * Return value: 1..DataSize sent, -1 eagain, or -3 on big Error
*/
-int a_Dpip_dsh_write(Dsh *dsh, int flush, const char *Data, int DataSize)
+static int Dpip_dsh_write(Dsh *dsh, int nb, const char *Data, int DataSize)
{
- int blocking, old_flags, st, sent = 0, ret = 1;
-
- /* append to buf */
- dStr_append_l(dsh->wrbuf, Data, DataSize);
-
- if (!flush || dsh->wrbuf->len == 0)
- return 0;
-
- blocking = !(dsh->mode & DPIP_NONBLOCK);
- if (!blocking) {
- /* set BLOCKING temporarily... */
- old_flags = fcntl(dsh->fd_in, F_GETFL);
- fcntl(dsh->fd_in, F_SETFL, old_flags & ~O_NONBLOCK);
+ int req_mode, old_flags, st, ret = -3, sent = 0;
+
+ req_mode = (nb) ? DPIP_NONBLOCK : 0;
+ if ((dsh->mode & DPIP_NONBLOCK) != req_mode) {
+ /* change mode temporarily... */
+ old_flags = fcntl(dsh->fd_out, F_GETFL);
+ fcntl(dsh->fd_out, F_SETFL,
+ (nb) ? O_NONBLOCK | old_flags : old_flags & ~O_NONBLOCK);
}
while (1) {
- st = write(dsh->fd_out, dsh->wrbuf->str + sent, dsh->wrbuf->len - sent);
+ st = write(dsh->fd_out, Data + sent, DataSize - sent);
if (st < 0) {
if (errno == EINTR) {
continue;
+ } else if (errno == EAGAIN) {
+ dsh->status = DPIP_EAGAIN;
+ ret = -1;
+ break;
} else {
+ MSG_ERR("[Dpip_dsh_write] %s\n", dStrerror(errno));
dsh->status = DPIP_ERROR;
break;
}
} else {
sent += st;
- if (sent == dsh->wrbuf->len) {
- dStr_truncate(dsh->wrbuf, 0);
- ret = 0;
+ if (nb || sent == DataSize) {
+ ret = sent;
break;
}
}
}
- if (!blocking) {
- /* restore nonblocking mode */
- fcntl(dsh->fd_in, F_SETFL, old_flags);
+ if ((dsh->mode & DPIP_NONBLOCK) != req_mode) {
+ /* restore old mode */
+ fcntl(dsh->fd_out, F_SETFL, old_flags);
}
return ret;
}
/*
- * Return value: 1..DataSize sent, -1 eagain, or -3 on big Error
+ * Streamed write to socket
+ * Return: 0 on success, 1 on error.
*/
-static int Dpip_dsh_trywrite(Dsh *dsh, const char *Data, int DataSize)
+int a_Dpip_dsh_write(Dsh *dsh, int flush, const char *Data, int DataSize)
{
- int blocking, old_flags, st, ret = -3;
+ int ret = 1;
- blocking = !(dsh->mode & DPIP_NONBLOCK);
- if (blocking) {
- /* set NONBLOCKING temporarily... */
- old_flags = fcntl(dsh->fd_in, F_GETFL);
- fcntl(dsh->fd_in, F_SETFL, O_NONBLOCK | old_flags);
- }
+ /* append to buf */
+ dStr_append_l(dsh->wrbuf, Data, DataSize);
- do {
- st = write(dsh->fd_out, Data, DataSize);
- } while (st < 0 && errno == EINTR);
- if (st < 0) {
- if (errno == EAGAIN) {
- dsh->status = DPIP_EAGAIN;
- ret = -1;
- } else {
- MSG_ERR("[Dpip_dsh_trywrite] %s\n", dStrerror(errno));
- dsh->status = DPIP_ERROR;
- }
- } else {
- ret = st;
- }
+ if (!flush || dsh->wrbuf->len == 0)
+ return 0;
- if (blocking) {
- /* restore blocking mode */
- fcntl(dsh->fd_in, F_SETFL, old_flags);
+ ret = Dpip_dsh_write(dsh, 0, dsh->wrbuf->str, dsh->wrbuf->len);
+ if (ret == dsh->wrbuf->len) {
+ dStr_truncate(dsh->wrbuf, 0);
+ ret = 0;
}
return ret;
@@ -354,7 +338,7 @@ int a_Dpip_dsh_tryflush(Dsh *dsh)
if (dsh->wrbuf->len == 0) {
st = 0;
} else {
- st = Dpip_dsh_trywrite(dsh, dsh->wrbuf->str, dsh->wrbuf->len);
+ st = Dpip_dsh_write(dsh, 1, dsh->wrbuf->str, dsh->wrbuf->len);
if (st > 0) {
/* update internal buffer */
dStr_erase(dsh->wrbuf, 0, st);
@@ -370,7 +354,7 @@ int a_Dpip_dsh_trywrite(Dsh *dsh, const char *Data, int DataSize)
{
int st;
- if ((st = Dpip_dsh_trywrite(dsh, Data, DataSize)) > 0) {
+ if ((st = Dpip_dsh_write(dsh, 1, Data, DataSize)) > 0) {
/* update internal buffer */
if (st < DataSize)
dStr_append_l(dsh->wrbuf, Data + st, DataSize - st);