409c409
< int fd = open(p->tun_clone_device.c_str(), O_RDWR);
---
> int fd = open(p->tun_clone_device.c_str(), O_RDWR | O_NONBLOCK);
441,443c441,447
< ssize_t ret = read(tap, buffer, buflen);
< if (ret < 0)
< panic("Failed to read from tap device.\n");
---
> ssize_t ret;
> while ((ret = read(tap, buffer, buflen))) {
> if (ret < 0) {
> if (errno == EAGAIN)
> break;
> panic("Failed to read from tap device.\n");
> }
445c449,450
< sendSimulated(buffer, ret);
---
> sendSimulated(buffer, ret);
> }
451,452c456,473
< if (write(tap, data, len) != len)
< panic("Failed to write data to tap device.\n");
---
> int n;
> pollfd pfd[1];
> pfd->fd = tap;
> pfd->events = POLLOUT;
>
> // `tap` is a nonblock fd. Here we try to write until success, and use
> // poll to make a blocking wait.
> while ((n = write(tap, data, len)) != len) {
> if (errno != EAGAIN)
> panic("Failed to write data to tap device.\n");
> pfd->revents = 0;
> int ret = poll(pfd, 1, -1);
> // timeout is set to inf, we shouldn't get 0 in any case.
> assert(ret != 0);
> if (ret == -1 || (ret == 1 && (pfd->revents & POLLERR))) {
> panic("Failed when polling to write data to tap device.\n");
> }
> }