return 0;
}
+static int do_poll(struct pollfd *fds)
+{
+ int ret;
+
+ do {
+ ret = rs_poll(fds, 1, poll_timeout);
+ } while (ret < 0 && (errno == EAGAIN || errno == EWOULDBLOCK));
+
+ return ret;
+}
+
static int send_xfer(int rs, int size)
{
struct pollfd fds;
for (offset = 0; offset < size; ) {
if (use_async) {
- ret = rs_poll(&fds, 1, -1);
+ ret = do_poll(&fds);
if (ret != 1)
return ret;
}
for (offset = 0; offset < size; ) {
if (use_async) {
- ret = rs_poll(&fds, 1, -1);
+ ret = do_poll(&fds);
if (ret != 1)
return ret;
}
fds.fd = lrs;
fds.events = POLLIN;
- ret = rs_poll(&fds, 1, -1);
+ ret = do_poll(&fds);
if (ret != 1) {
perror("rpoll");
goto close;
ret = rs_connect(rs, res->ai_addr, res->ai_addrlen);
if (ret && (errno != EINPROGRESS)) {
perror("rconnect");
- rs_close(rs);
- rs = ret;
+ goto err;
}
if (errno == EINPROGRESS) {
fds.fd = rs;
fds.events = POLLOUT;
- do {
- ret = rs_poll(&fds, 1, -1);
- } while (!ret);
+ ret = do_poll(&fds);
+ if (ret != 1) {
+ perror("rpoll");
+ goto err;
+ }
}
free:
freeaddrinfo(res);
return rs;
+err:
+ freeaddrinfo(res);
+ rs_close(rs);
+ return -1;
}
static int run(void)
break;
case 'a':
use_async = 1;
+ flags |= MSG_DONTWAIT;
break;
case 'b':
flags &= ~MSG_DONTWAIT;
.P
n | nonblocking - uses non-blocking calls
.P
+p | poll - poll on asynchronous operations until complete
+.P
v | verify - verifies data transfers
.SH "NOTES"
Basic usage is to start rstream on a server system, then run