diff --git a/src/io.c b/src/io.c index b43b140bf675497c735ea4e377f36880532fa6b4..5f0e58429c6cded8795d66166ad57c753f421d60 100644 --- a/src/io.c +++ b/src/io.c @@ -450,7 +450,31 @@ static void init_file(struct io_backend *b, struct lsh_fd *f, int fd) f->next = b->files; b->files = f; } - + +/* Blocking read from a file descriptor (i.e. don't use the backend). + * The fd should *not* be in non-blocking mode. */ + +int blocking_read(int fd, struct read_handler *handler) +{ + struct fd_read r = + { { STACK_HEADER, do_read }, fd }; + + while (1) + { + int res = READ_HANDLER(handler, + &r.super); + + assert(!(res & (LSH_HOLD | LSH_KILL_OTHERS))); + + if (res & (LSH_CLOSE | LSH_DIE)) + { + close(fd); + return res; + } + if (res & LSH_FAIL) + werror("blocking_read: Ignoring error %d\n", res); + } +} /* * Fill in ADDR from HOST, SERVICE and PROTOCOL. * Supplying a null pointer for HOST means use INADDR_ANY. diff --git a/src/io.h b/src/io.h index dcc3e66b8e6f52eba9c86f2ae7de2a844e90ceb3..1343c03a54eb632c75ab7e7eb58880056971649c 100644 --- a/src/io.h +++ b/src/io.h @@ -154,6 +154,8 @@ void init_backend(struct io_backend *b); int io_iter(struct io_backend *b); void io_run(struct io_backend *b); +int blocking_read(int fd, struct read_handler *r); + int get_inaddr(struct sockaddr_in * addr, const char * host, const char * service,