diff options
-rw-r--r-- | dpip/dpip.c | 86 |
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); |