summaryrefslogtreecommitdiffstats
path: root/adb/transport.c
diff options
context:
space:
mode:
Diffstat (limited to 'adb/transport.c')
-rw-r--r--adb/transport.c82
1 files changed, 54 insertions, 28 deletions
diff --git a/adb/transport.c b/adb/transport.c
index c76f1a5..831b6fc 100644
--- a/adb/transport.c
+++ b/adb/transport.c
@@ -584,17 +584,36 @@ static void transport_registration_func(int _fd, unsigned ev, void *data)
return;
}
+ /* don't create transport threads for inaccessible devices */
+ if (t->connection_state != CS_NOPERM) {
/* initial references are the two threads */
- t->ref_count = 2;
+ t->ref_count = 2;
- if(adb_socketpair(s)) {
- fatal_errno("cannot open transport socketpair");
- }
+ if(adb_socketpair(s)) {
+ fatal_errno("cannot open transport socketpair");
+ }
+
+ D("transport: %p (%d,%d) starting\n", t, s[0], s[1]);
+
+ t->transport_socket = s[0];
+ t->fd = s[1];
- D("transport: %p (%d,%d) starting\n", t, s[0], s[1]);
+ D("transport: %p install %d\n", t, t->transport_socket );
+ fdevent_install(&(t->transport_fde),
+ t->transport_socket,
+ transport_socket_events,
+ t);
+
+ fdevent_set(&(t->transport_fde), FDE_READ);
+
+ if(adb_thread_create(&input_thread_ptr, input_thread, t)){
+ fatal_errno("cannot create input thread");
+ }
- t->transport_socket = s[0];
- t->fd = s[1];
+ if(adb_thread_create(&output_thread_ptr, output_thread, t)){
+ fatal_errno("cannot create output thread");
+ }
+ }
/* put us on the master device list */
adb_mutex_lock(&transport_lock);
@@ -604,22 +623,6 @@ static void transport_registration_func(int _fd, unsigned ev, void *data)
t->prev->next = t;
adb_mutex_unlock(&transport_lock);
- D("transport: %p install %d\n", t, t->transport_socket );
- fdevent_install(&(t->transport_fde),
- t->transport_socket,
- transport_socket_events,
- t);
-
- fdevent_set(&(t->transport_fde), FDE_READ);
-
- if(adb_thread_create(&input_thread_ptr, input_thread, t)){
- fatal_errno("cannot create input thread");
- }
-
- if(adb_thread_create(&output_thread_ptr, output_thread, t)){
- fatal_errno("cannot create output thread");
- }
-
t->disconnects.next = t->disconnects.prev = &t->disconnects;
update_transports();
@@ -717,6 +720,8 @@ retry:
adb_mutex_lock(&transport_lock);
for (t = transport_list.next; t != &transport_list; t = t->next) {
+ if (t->connection_state == CS_NOPERM) continue;
+
/* check for matching serial number */
if (serial) {
if (t->serial && !strcmp(serial, t->serial)) {
@@ -763,6 +768,11 @@ retry:
*error_out = "device offline";
result = NULL;
}
+ if (result && result->connection_state == CS_NOPERM) {
+ if (error_out)
+ *error_out = "no permissions for device";
+ result = NULL;
+ }
/* check for required connection state */
if (result && state != CS_ANY && result->connection_state != state) {
@@ -793,6 +803,7 @@ static const char *statename(atransport *t)
case CS_DEVICE: return "device";
case CS_HOST: return "host";
case CS_RECOVERY: return "recovery";
+ case CS_NOPERM: return "no permissions";
default: return "unknown";
}
}
@@ -807,9 +818,10 @@ int list_transports(char *buf, size_t bufsize)
/* XXX OVERRUN PROBLEMS XXX */
adb_mutex_lock(&transport_lock);
for(t = transport_list.next; t != &transport_list; t = t->next) {
- len = snprintf(p, end - p, "%s\t%s\n",
- t->serial ? t->serial : "",
- statename(t));
+ const char* serial = t->serial;
+ if (!serial || !serial[0])
+ serial = "????????????";
+ len = snprintf(p, end - p, "%s\t%s\n", serial, statename(t));
if (p + len >= end) {
/* discard last line if buffer is too short */
@@ -854,18 +866,32 @@ void register_socket_transport(int s, const char *serial, int port)
register_transport(t);
}
-void register_usb_transport(usb_handle *usb, const char *serial)
+void register_usb_transport(usb_handle *usb, const char *serial, unsigned writeable)
{
atransport *t = calloc(1, sizeof(atransport));
D("transport: %p init'ing for usb_handle %p (sn='%s')\n", t, usb,
serial ? serial : "");
- init_usb_transport(t, usb);
+ init_usb_transport(t, usb, (writeable ? CS_OFFLINE : CS_NOPERM));
if(serial) {
t->serial = strdup(serial);
}
register_transport(t);
}
+/* this should only be used for transports with connection_state == CS_NOPERM */
+void unregister_usb_transport(usb_handle *usb)
+{
+ atransport *t;
+ adb_mutex_lock(&transport_lock);
+ for(t = transport_list.next; t != &transport_list; t = t->next) {
+ if (t->usb == usb && t->connection_state == CS_NOPERM) {
+ t->next->prev = t->prev;
+ t->prev->next = t->next;
+ break;
+ }
+ }
+ adb_mutex_unlock(&transport_lock);
+}
#undef TRACE_TAG
#define TRACE_TAG TRACE_RWX