diff --git a/src/io.c b/src/io.c index 9734c9bee53887c7de265b2e287be813fd67b7e5..19820e8fa9c2f5fa28727a7db0b0f60cf7fb28c1 100644 --- a/src/io.c +++ b/src/io.c @@ -234,7 +234,7 @@ static int do_read(struct abstract_read **r, UINT32 length, UINT8 *buffer) case EWOULDBLOCK: /* aka EAGAIN */ return 0; case EPIPE: - werror("io.c: read() returned EPIPE! Treating it as EOF.\n"); + wwrite("io.c: read() returned EPIPE! Treating it as EOF.\n"); return A_EOF; default: werror("io.c: do_read: read() failed (errno %d), %s\n", @@ -358,7 +358,7 @@ static void listen_callback(struct lsh_fd *fd) res = FD_CALLBACK(self->callback, conn); if (LSH_ACTIONP(res)) { - werror("Strange: Accepted a connection, " + wwrite("Strange: Accepted a connection, " "but failed before writing anything.\n"); close_fd(fd, (LSH_FAILUREP(res) ? CLOSE_PROTOCOL_FAILURE @@ -375,7 +375,7 @@ static void connect_callback(struct lsh_fd *fd) if (LSH_ACTIONP(res)) { - werror("Strange: Connected, " + wwrite("Strange: Connected, " "but failed before writing anything.\n"); } else @@ -535,6 +535,70 @@ get_inaddr(struct sockaddr_in * addr, return 1; } +/* For fd:s in blocking mode. */ +int write_raw(int fd, UINT32 length, UINT8 *data) +{ + while(length) + { + int written = write(fd, data, length); + + if (written < 0) + switch(errno) + { + case EINTR: + case EAGAIN: + continue; + default: + return 0; + } + + length -= written; + data += written; + } + return 1; +} + +int write_raw_with_poll(int fd, UINT32 length, UINT8 *data) +{ + while(length) + { + struct pollfd pfd; + int res; + int written; + + pfd.fd = fd; + pfd.events = POLLOUT; + + res = poll(&pfd, 1, -1); + + if (res < 0) + switch(errno) + { + case EINTR: + case EAGAIN: + continue; + default: + return 0; + } + + written = write(fd, data, length); + + if (written < 0) + switch(errno) + { + case EINTR: + case EAGAIN: + continue; + default: + return 0; + } + + length -= written; + data += written; + } + return 1; +} + void io_set_nonblocking(int fd) { if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0) diff --git a/src/io.h b/src/io.h index b739d24e097d1961673474645094a8d405ece5f0..dcc3e66b8e6f52eba9c86f2ae7de2a844e90ceb3 100644 --- a/src/io.h +++ b/src/io.h @@ -159,6 +159,9 @@ int get_inaddr(struct sockaddr_in * addr, const char * service, const char * protocol); +int write_raw(int fd, UINT32 length, UINT8 *data); +int write_raw_with_poll(int fd, UINT32 length, UINT8 *data); + void io_set_nonblocking(int fd); void io_set_close_on_exec(int fd); void io_init_fd(int fd);