aboutsummaryrefslogtreecommitdiffstats
path: root/android/android-device.c
diff options
context:
space:
mode:
Diffstat (limited to 'android/android-device.c')
-rw-r--r--android/android-device.c74
1 files changed, 51 insertions, 23 deletions
diff --git a/android/android-device.c b/android/android-device.c
index 37af0c6..498e304 100644
--- a/android/android-device.c
+++ b/android/android-device.c
@@ -581,35 +581,60 @@ _android_dev_socket_recv(AndroidDevSocket* ads, char* buf, int bufsize)
return -1;
}
- iolooper_add_read(_ads_io_looper(ads), ads->fd);
- do {
- int res = socket_recv(ads->fd, buf + recvd, bufsize - recvd);
- if (res == 0) {
- /* Disconnection. */
- errno = ECONNRESET;
- recvd = -1;
- break;
+ /* XXX: This is a hack that implements a blocked line read on an async
+ * event socket! Redo this ASAP! */
+ if (ads->type == ADS_TYPE_EVENT) {
+ AndroidEventSocket* adsevent = (AndroidEventSocket*)ads;
+ asyncLineReader_init(&adsevent->alr, buf, bufsize, adsevent->io);
+ /* Default EOL for the line reader was '\n'. */
+ asyncLineReader_setEOL(&adsevent->alr, '\0');
+ AsyncStatus status = ASYNC_NEED_MORE;
+
+ while (status == ASYNC_NEED_MORE) {
+ status = asyncLineReader_read(&adsevent->alr);
+ if (status == ASYNC_COMPLETE) {
+ recvd = adsevent->alr.pos;
+ break;
+ } else if (status == ASYNC_ERROR) {
+ if (errno == ENOMEM) {
+ recvd = adsevent->alr.pos;
+ } else {
+ recvd = -1;
+ }
+ break;
+ }
}
-
- if (res < 0) {
- if (errno == EINTR) {
- /* loop on EINTR */
- continue;
+ } else {
+ iolooper_add_read(_ads_io_looper(ads), ads->fd);
+ do {
+ int res = socket_recv(ads->fd, buf + recvd, bufsize - recvd);
+ if (res == 0) {
+ /* Disconnection. */
+ errno = ECONNRESET;
+ recvd = -1;
+ break;
}
- if (errno == EWOULDBLOCK || errno == EAGAIN) {
- res = iolooper_wait_absolute(_ads_io_looper(ads), ads->deadline);
- if (res > 0) {
- /* Ready to read. */
+ if (res < 0) {
+ if (errno == EINTR) {
+ /* loop on EINTR */
continue;
}
+
+ if (errno == EWOULDBLOCK || errno == EAGAIN) {
+ res = iolooper_wait_absolute(_ads_io_looper(ads), ads->deadline);
+ if (res > 0) {
+ /* Ready to read. */
+ continue;
+ }
+ }
+ recvd = -1;
+ break;
}
- recvd = -1;
- break;
- }
- recvd += res;
- } while (recvd < bufsize);
- iolooper_del_read(_ads_io_looper(ads), ads->fd);
+ recvd += res;
+ } while (recvd < bufsize);
+ iolooper_del_read(_ads_io_looper(ads), ads->fd);
+ }
/* In case of an I/O failure we have to invoke failure callback. Note that we
* report I/O failures only on registered sockets. */
@@ -1108,6 +1133,7 @@ _on_event_socket_io(void* opaque, int fd, unsigned events)
/* Continue reading data. */
status = asyncLineReader_read(&adsevent->alr);
if (status == ASYNC_COMPLETE) {
+ errno = 0;
_on_event_received(adsevent);
} else if (status == ASYNC_ERROR) {
D("I/O failure while reading from channel '%s'@%d: %s",
@@ -1153,6 +1179,7 @@ _on_event_socket_io(void* opaque, int fd, unsigned events)
return;
} else if (sent == to_send->data_remaining) {
/* All data is sent. */
+ errno = 0;
adsevent->send_pending = to_send->next;
_async_send_buffer_complete(to_send, ATR_SUCCESS);
} else {
@@ -1182,6 +1209,7 @@ _on_event_socket_connected(AndroidEventSocket* adsevent, int failure)
/* Complete event socket connection by identifying it as "event" socket with
* the application. */
res = _android_dev_socket_register(ads);
+
if (res) {
const int save_error = errno;
_android_event_socket_disconnect(adsevent);