ssize_t rcode;
fr_bio_fd_t *my = talloc_get_type_abort(bio, fr_bio_fd_t);
- my->info.read_blocked = false;
-
retry:
rcode = read(my->info.socket.fd, buffer, size);
- if (rcode > 0) return rcode;
-
if (rcode == 0) {
/*
* Stream sockets return 0 at EOF. However, we want to distinguish that from the case of datagram
return fr_bio_error(EOF);
}
-#undef flag_blocked
-#define flag_blocked read_blocked
-#include "fd_errno.h"
+#include "fd_read.h"
return fr_bio_error(IO);
}
ssize_t rcode;
fr_bio_fd_t *my = talloc_get_type_abort(bio, fr_bio_fd_t);
- my->info.read_blocked = false;
-
retry:
rcode = read(my->info.socket.fd, buffer, size);
- if (rcode >= 0) return rcode;
-#undef flag_blocked
-#define flag_blocked read_blocked
-#include "fd_errno.h"
+#include "fd_read.h"
return fr_bio_error(IO);
}
socklen_t salen;
struct sockaddr_storage sockaddr;
- my->info.read_blocked = false;
-
retry:
salen = sizeof(sockaddr);
(void) fr_ipaddr_from_sockaddr(&addr->socket.inet.src_ipaddr, &addr->socket.inet.src_port,
&sockaddr, salen);
- return rcode;
}
- if (rcode == 0) return rcode;
-
-#undef flag_blocked
-#define flag_blocked read_blocked
-#include "fd_errno.h"
+#include "fd_read.h"
return fr_bio_error(IO);
}
from.ss_family = AF_UNSPEC;
#endif
- my->info.read_blocked = false;
-
memset(&my->cbuf, 0, sizeof(my->cbuf));
memset(&my->msgh, 0, sizeof(struct msghdr));
(void) fr_ipaddr_from_sockaddr(&addr->socket.inet.src_ipaddr, &addr->socket.inet.src_port,
&from, my->msgh.msg_namelen);
-
- return rcode;
}
- if (rcode == 0) return rcode;
-
-#undef flag_blocked
-#define flag_blocked read_blocked
-#include "fd_errno.h"
+#include "fd_read.h"
return fr_bio_error(IO);
}
ssize_t rcode;
fr_bio_fd_t *my = talloc_get_type_abort(bio, fr_bio_fd_t);
- my->info.read_blocked = false;
-
retry:
rcode = read(my->info.socket.fd, buffer, size);
- if (rcode >= 0) return 0;
+ if (rcode > 0) rcode = 0; /* always return that we read no data */
-#undef flag_blocked
-#define flag_blocked read_blocked
-#include "fd_errno.h"
+#include "fd_read.h"
return fr_bio_error(IO);
}
--- /dev/null
+/*
+ * Common finalization code for the read functions.
+ *
+ * This is in a header file because of "goto retry" in fd_errno.h.
+ *
+ * @todo - do we want the callbacks to notify the _previous_ BIO in the chain? That way the top-level
+ * BIO can notify the application.
+ */
+if (rcode > 0) {
+ /*
+ * We weren't blocked, so we're still not blocked.
+ */
+ if (!my->info.read_blocked) {
+ return rcode;
+ }
+
+ /*
+ * We were blocked. Since we just read data, we're now unblocked.
+ */
+ my->info.read_blocked = false;
+
+ /*
+ * Call the "resume" function when we transition to being unblocked.
+ */
+ if (my->cb.read_resume) my->cb.read_resume((fr_bio_t *) my);
+
+ return rcode;
+}
+
+if (rcode == 0) return rcode;
+
+#undef flag_blocked
+#define flag_blocked read_blocked
+#include "fd_errno.h"