Merge change 2903
* changes:
completed implementation of "trigger" for init
diff --git a/adb/Android.mk b/adb/Android.mk
index 9725478..f3eaa6e 100644
--- a/adb/Android.mk
+++ b/adb/Android.mk
@@ -53,7 +53,7 @@
$(USB_SRCS) \
shlist.c \
utils.c \
- usb_vendors.c \
+ usb_vendors.c
ifneq ($(USE_SYSDEPS_WIN32),)
@@ -76,7 +76,9 @@
$(call dist-for-goals,droid,$(LOCAL_BUILT_MODULE))
ifeq ($(HOST_OS),windows)
-$(LOCAL_INSTALLED_MODULE): $(HOST_OUT_EXECUTABLES)/AdbWinApi.dll
+$(LOCAL_INSTALLED_MODULE): \
+ $(HOST_OUT_EXECUTABLES)/AdbWinApi.dll \
+ $(HOST_OUT_EXECUTABLES)/AdbWinUsbApi.dll
endif
@@ -91,9 +93,9 @@
# build adbd for the Linux simulator build
# so we can use it to test the adb USB gadget driver on x86
-ifeq ($(HOST_OS),linux)
- BUILD_ADBD := true
-endif
+#ifeq ($(HOST_OS),linux)
+# BUILD_ADBD := true
+#endif
ifeq ($(BUILD_ADBD),true)
@@ -113,7 +115,7 @@
remount_service.c \
usb_linux_client.c \
log_service.c \
- utils.c \
+ utils.c
LOCAL_CFLAGS := -O2 -g -DADB_HOST=0 -Wall -Wno-unused-parameter
LOCAL_CFLAGS += -D_XOPEN_SOURCE -D_GNU_SOURCE
diff --git a/adb/adb.c b/adb/adb.c
index 956df54..283ebce 100644
--- a/adb/adb.c
+++ b/adb/adb.c
@@ -30,6 +30,8 @@
#if !ADB_HOST
#include <private/android_filesystem_config.h>
+#include <linux/capability.h>
+#include <linux/prctl.h>
#else
#include "usb_vendors.h"
#endif
@@ -830,6 +832,7 @@
{
#if !ADB_HOST
int secure = 0;
+ int port;
char value[PROPERTY_VALUE_MAX];
#endif
@@ -848,7 +851,7 @@
HOST = 1;
usb_vendors_init();
usb_init();
- local_init();
+ local_init(ADB_LOCAL_TRANSPORT_PORT);
if(install_listener("tcp:5037", "*smartsocket*", NULL)) {
exit(1);
@@ -879,6 +882,11 @@
/* don't listen on port 5037 if we are running in secure mode */
/* don't run as root if we are running in secure mode */
if (secure) {
+ struct __user_cap_header_struct header;
+ struct __user_cap_data_struct cap;
+
+ prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0);
+
/* add extra groups:
** AID_ADB to access the USB driver
** AID_LOG to read system logs (adb logcat)
@@ -896,6 +904,13 @@
setgid(AID_SHELL);
setuid(AID_SHELL);
+ /* set CAP_SYS_BOOT capability, so "adb reboot" will succeed */
+ header.version = _LINUX_CAPABILITY_VERSION;
+ header.pid = 0;
+ cap.effective = cap.permitted = (1 << CAP_SYS_BOOT);
+ cap.inheritable = 0;
+ capset(&header, &cap);
+
D("Local port 5037 disabled\n");
} else {
if(install_listener("tcp:5037", "*smartsocket*", NULL)) {
@@ -904,14 +919,19 @@
}
/* for the device, start the usb transport if the
- ** android usb device exists, otherwise start the
- ** network transport.
+ ** android usb device exists and "service.adb.tcp"
+ ** is not set, otherwise start the network transport.
*/
- if(access("/dev/android_adb", F_OK) == 0 ||
- access("/dev/android", F_OK) == 0) {
+ property_get("service.adb.tcp.port", value, "0");
+ if (sscanf(value, "%d", &port) == 1 && port > 0) {
+ // listen on TCP port specified by service.adb.tcp.port property
+ local_init(port);
+ } else if (access("/dev/android_adb", F_OK) == 0) {
+ // listen on USB
usb_init();
} else {
- local_init();
+ // listen on default port
+ local_init(ADB_LOCAL_TRANSPORT_PORT);
}
init_jdwp();
#endif
@@ -992,6 +1012,43 @@
return 0;
}
+ // add a new TCP transport
+ if (!strncmp(service, "connect:", 8)) {
+ char buffer[4096];
+ int port, fd;
+ char* host = service + 8;
+ char* portstr = strchr(host, ':');
+
+ if (!portstr) {
+ snprintf(buffer, sizeof(buffer), "unable to parse %s as <host>:<port>\n", host);
+ goto done;
+ }
+ // zero terminate host by overwriting the ':'
+ *portstr++ = 0;
+ if (sscanf(portstr, "%d", &port) == 0) {
+ snprintf(buffer, sizeof(buffer), "bad port number %s\n", portstr);
+ goto done;
+ }
+
+ fd = socket_network_client(host, port, SOCK_STREAM);
+ if (fd < 0) {
+ snprintf(buffer, sizeof(buffer), "unable to connect to %s:%d\n", host, port);
+ goto done;
+ }
+
+ D("client: connected on remote on fd %d\n", fd);
+ close_on_exec(fd);
+ disable_tcp_nagle(fd);
+ snprintf(buf, sizeof buf, "%s:%d", host, port);
+ register_socket_transport(fd, buf, port, 0);
+ snprintf(buffer, sizeof(buffer), "connected to %s:%d\n", host, port);
+
+done:
+ snprintf(buf, sizeof(buf), "OKAY%04x%s",(unsigned)strlen(buffer),buffer);
+ writex(reply_fd, buf, strlen(buf));
+ return 0;
+ }
+
// returns our value for ADB_SERVER_VERSION
if (!strcmp(service, "version")) {
char version[12];
diff --git a/adb/adb.h b/adb/adb.h
index 95610a7..713666f 100644
--- a/adb/adb.h
+++ b/adb/adb.h
@@ -33,7 +33,7 @@
#define ADB_VERSION_MAJOR 1 // Used for help/version information
#define ADB_VERSION_MINOR 0 // Used for help/version information
-#define ADB_SERVER_VERSION 21 // Increment this when we want to force users to start a new adb server
+#define ADB_SERVER_VERSION 25 // Increment this when we want to force users to start a new adb server
typedef struct amessage amessage;
typedef struct apacket apacket;
@@ -262,15 +262,18 @@
void kick_transport( atransport* t );
/* initialize a transport object's func pointers and state */
-int init_socket_transport(atransport *t, int s, int port);
-void init_usb_transport(atransport *t, usb_handle *usb);
+int init_socket_transport(atransport *t, int s, int port, int local);
+void init_usb_transport(atransport *t, usb_handle *usb, int state);
/* for MacOS X cleanup */
void close_usb_devices();
/* cause new transports to be init'd and added to the list */
-void register_socket_transport(int s, const char *serial, int port);
-void register_usb_transport(usb_handle *h, const char *serial);
+void register_socket_transport(int s, const char *serial, int port, int local);
+void register_usb_transport(usb_handle *h, const char *serial, unsigned writeable);
+
+/* this should only be used for transports with connection_state == CS_NOPERM */
+void unregister_usb_transport(usb_handle *usb);
int service_to_fd(const char *name);
#if ADB_HOST
@@ -357,7 +360,7 @@
#define ADB_PROTOCOL 0x1
-void local_init();
+void local_init(int port);
int local_connect(int port);
/* usb host/client interface */
@@ -384,7 +387,7 @@
#define CS_DEVICE 2
#define CS_HOST 3
#define CS_RECOVERY 4
-#define CS_ERROR 5
+#define CS_NOPERM 5 /* Insufficient permissions to communicate with the device */
extern int HOST;
diff --git a/adb/commandline.c b/adb/commandline.c
index 548d362..411bb82 100644
--- a/adb/commandline.c
+++ b/adb/commandline.c
@@ -96,7 +96,8 @@
" -e - directs command to the only running emulator.\n"
" returns an error if more than one emulator is running.\n"
" -s <serial number> - directs command to the USB device or emulator with\n"
- " the given serial number\n"
+ " the given serial number. Overrides ANDROID_SERIAL\n"
+ " envivornment variable.\n"
" -p <product name or path> - simple product name like 'sooner', or\n"
" a relative/absolute path to a product\n"
" out directory like 'out/target/product/sooner'.\n"
@@ -104,6 +105,7 @@
" environment variable is used, which must\n"
" be an absolute path.\n"
" devices - list all connected devices\n"
+ " connect <host>:<port> - connect to a device via TCP/IP"
"\n"
"device commands:\n"
" adb push <local> <remote> - copy file/dir to device\n"
@@ -147,7 +149,10 @@
" adb get-serialno - prints: <serial-number>\n"
" adb status-window - continuously print device status for a specified device\n"
" adb remount - remounts the /system partition on the device read-write\n"
- " adb root - restarts adb with root permissions\n"
+ " adb reboot [bootloader|recovery] - reboots the device, optionally into the bootloader or recovery program\n"
+ " adb root - restarts the adbd daemon with root permissions\n"
+ " adb usb - restarts the adbd daemon listening on USB"
+ " adb tcpip <port> - restarts the adbd daemon listening on TCP on the specified port"
"\n"
"networking:\n"
" adb ppp <tty> [parameters] - Run PPP over USB.\n"
@@ -766,6 +771,8 @@
}
// TODO: also try TARGET_PRODUCT/TARGET_DEVICE as a hint
+ serial = getenv("ANDROID_SERIAL");
+
/* modifiers and flags */
while(argc > 0) {
if(!strcmp(argv[0],"nodaemon")) {
@@ -846,6 +853,22 @@
}
}
+ if(!strcmp(argv[0], "connect")) {
+ char *tmp;
+ if (argc != 2) {
+ fprintf(stderr, "Usage: adb connect <host>:<port>\n");
+ return 1;
+ }
+ snprintf(buf, sizeof buf, "host:%s:%s", argv[0], argv[1]);
+ tmp = adb_query(buf);
+ if(tmp) {
+ printf("%s\n", tmp);
+ return 0;
+ } else {
+ return 1;
+ }
+ }
+
if (!strcmp(argv[0], "emu")) {
return adb_send_emulator_command(argc, argv);
}
@@ -904,19 +927,15 @@
return 0;
}
- if(!strcmp(argv[0], "remount")) {
- int fd = adb_connect("remount:");
- if(fd >= 0) {
- read_and_dump(fd);
- adb_close(fd);
- return 0;
- }
- fprintf(stderr,"error: %s\n", adb_error());
- return 1;
- }
-
- if(!strcmp(argv[0], "root")) {
- int fd = adb_connect("root:");
+ if(!strcmp(argv[0], "remount") || !strcmp(argv[0], "reboot")
+ || !strcmp(argv[0], "tcpip") || !strcmp(argv[0], "usb")
+ || !strcmp(argv[0], "root")) {
+ char command[100];
+ if (argc > 1)
+ snprintf(command, sizeof(command), "%s:%s", argv[0], argv[1]);
+ else
+ snprintf(command, sizeof(command), "%s:", argv[0]);
+ int fd = adb_connect(command);
if(fd >= 0) {
read_and_dump(fd);
adb_close(fd);
diff --git a/adb/get_my_path_darwin.c b/adb/get_my_path_darwin.c
index 00dfee4..6125cb4 100644
--- a/adb/get_my_path_darwin.c
+++ b/adb/get_my_path_darwin.c
@@ -14,7 +14,6 @@
* limitations under the License.
*/
-#include <utils/executablepath.h>
#import <Carbon/Carbon.h>
#include <unistd.h>
diff --git a/adb/services.c b/adb/services.c
index 78d092b..2864ac9 100644
--- a/adb/services.c
+++ b/adb/services.c
@@ -33,6 +33,7 @@
# endif
#else
#include <sys/poll.h>
+#include <sys/reboot.h>
#endif
typedef struct stinfo stinfo;
@@ -119,6 +120,7 @@
if (strcmp(value, "1") != 0) {
snprintf(buf, sizeof(buf), "adbd cannot run as root in production builds\n");
writex(fd, buf, strlen(buf));
+ adb_close(fd);
return;
}
@@ -133,6 +135,59 @@
}
}
+void restart_tcp_service(int fd, void *cookie)
+{
+ char buf[100];
+ char value[PROPERTY_VALUE_MAX];
+ int port = (int)cookie;
+
+ if (port <= 0) {
+ snprintf(buf, sizeof(buf), "invalid port\n");
+ writex(fd, buf, strlen(buf));
+ adb_close(fd);
+ return;
+ }
+
+ snprintf(value, sizeof(value), "%d", port);
+ property_set("service.adb.tcp.port", value);
+ snprintf(buf, sizeof(buf), "restarting in TCP mode port: %d\n", port);
+ writex(fd, buf, strlen(buf));
+ adb_close(fd);
+
+ // quit, and init will restart us in TCP mode
+ sleep(1);
+ exit(1);
+}
+
+void restart_usb_service(int fd, void *cookie)
+{
+ char buf[100];
+
+ property_set("service.adb.tcp.port", "0");
+ snprintf(buf, sizeof(buf), "restarting in USB mode\n");
+ writex(fd, buf, strlen(buf));
+ adb_close(fd);
+
+ // quit, and init will restart us in USB mode
+ sleep(1);
+ exit(1);
+}
+
+void reboot_service(int fd, void *arg)
+{
+ char buf[100];
+ int ret;
+
+ sync();
+ ret = __reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,
+ LINUX_REBOOT_CMD_RESTART2, (char *)arg);
+ if (ret < 0) {
+ snprintf(buf, sizeof(buf), "reboot failed: %s\n", strerror(errno));
+ writex(fd, buf, strlen(buf));
+ }
+ adb_close(fd);
+}
+
#endif
#if 0
@@ -399,8 +454,21 @@
ret = create_service_thread(file_sync_service, NULL);
} else if(!strncmp(name, "remount:", 8)) {
ret = create_service_thread(remount_service, NULL);
+ } else if(!strncmp(name, "reboot:", 7)) {
+ const char* arg = name + 7;
+ if (*name == 0)
+ arg = NULL;
+ ret = create_service_thread(reboot_service, (void *)arg);
} else if(!strncmp(name, "root:", 5)) {
ret = create_service_thread(restart_root_service, NULL);
+ } else if(!strncmp(name, "tcpip:", 6)) {
+ int port;
+ if (sscanf(name + 6, "%d", &port) == 0) {
+ port = 0;
+ }
+ ret = create_service_thread(restart_tcp_service, (void *)port);
+ } else if(!strncmp(name, "usb:", 4)) {
+ ret = create_service_thread(restart_usb_service, NULL);
#endif
#if 0
} else if(!strncmp(name, "echo:", 5)){
diff --git a/adb/transport.c b/adb/transport.c
index c76f1a5..617dabf 100644
--- a/adb/transport.c
+++ b/adb/transport.c
@@ -584,18 +584,37 @@
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 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");
+ }
}
- D("transport: %p (%d,%d) starting\n", t, s[0], s[1]);
-
- t->transport_socket = s[0];
- t->fd = s[1];
-
/* put us on the master device list */
adb_mutex_lock(&transport_lock);
t->next = &transport_list;
@@ -604,22 +623,6 @@
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,12 @@
adb_mutex_lock(&transport_lock);
for (t = transport_list.next; t != &transport_list; t = t->next) {
+ if (t->connection_state == CS_NOPERM) {
+ if (error_out)
+ *error_out = "insufficient permissions for device";
+ continue;
+ }
+
/* check for matching serial number */
if (serial) {
if (t->serial && !strcmp(serial, t->serial)) {
@@ -763,7 +772,6 @@
*error_out = "device offline";
result = NULL;
}
-
/* check for required connection state */
if (result && state != CS_ANY && result->connection_state != state) {
if (error_out)
@@ -793,6 +801,7 @@
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 +816,10 @@
/* 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 */
@@ -839,11 +849,11 @@
}
#endif // ADB_HOST
-void register_socket_transport(int s, const char *serial, int port)
+void register_socket_transport(int s, const char *serial, int port, int local)
{
atransport *t = calloc(1, sizeof(atransport));
D("transport: %p init'ing for socket %d, on port %d\n", t, s, port);
- if ( init_socket_transport(t, s, port) < 0 ) {
+ if ( init_socket_transport(t, s, port, local) < 0 ) {
adb_close(s);
free(t);
return;
@@ -854,18 +864,32 @@
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
diff --git a/adb/transport_local.c b/adb/transport_local.c
index be01f29..c528d1f 100644
--- a/adb/transport_local.c
+++ b/adb/transport_local.c
@@ -122,7 +122,7 @@
close_on_exec(fd);
disable_tcp_nagle(fd);
snprintf(buf, sizeof buf, "%s%d", LOCAL_CLIENT_PREFIX, port - 1);
- register_socket_transport(fd, buf, port);
+ register_socket_transport(fd, buf, port, 1);
return 0;
}
return -1;
@@ -147,17 +147,18 @@
return 0;
}
-static void *server_socket_thread(void *x)
+static void *server_socket_thread(void * arg)
{
int serverfd, fd;
struct sockaddr addr;
socklen_t alen;
+ int port = (int)arg;
D("transport: server_socket_thread() starting\n");
serverfd = -1;
for(;;) {
if(serverfd == -1) {
- serverfd = socket_inaddr_any_server(ADB_LOCAL_TRANSPORT_PORT, SOCK_STREAM);
+ serverfd = socket_inaddr_any_server(port, SOCK_STREAM);
if(serverfd < 0) {
D("server: cannot bind socket yet\n");
adb_sleep_ms(1000);
@@ -167,20 +168,20 @@
}
alen = sizeof(addr);
- D("server: trying to get new connection from %d\n", ADB_LOCAL_TRANSPORT_PORT);
+ D("server: trying to get new connection from %d\n", port);
fd = adb_socket_accept(serverfd, &addr, &alen);
if(fd >= 0) {
D("server: new connection on fd %d\n", fd);
close_on_exec(fd);
disable_tcp_nagle(fd);
- register_socket_transport(fd,"host",ADB_LOCAL_TRANSPORT_PORT);
+ register_socket_transport(fd, "host", port, 1);
}
}
D("transport: server_socket_thread() exiting\n");
return 0;
}
-void local_init(void)
+void local_init(int port)
{
adb_thread_t thr;
void* (*func)(void *);
@@ -193,7 +194,7 @@
D("transport: local %s init\n", HOST ? "client" : "server");
- if(adb_thread_create(&thr, func, 0)) {
+ if(adb_thread_create(&thr, func, (void *)port)) {
fatal_errno("cannot create local socket %s thread",
HOST ? "client" : "server");
}
@@ -225,7 +226,7 @@
adb_close(t->fd);
}
-int init_socket_transport(atransport *t, int s, int port)
+int init_socket_transport(atransport *t, int s, int port, int local)
{
int fail = 0;
@@ -239,7 +240,7 @@
t->type = kTransportLocal;
#if ADB_HOST
- if (HOST) {
+ if (HOST && local) {
adb_mutex_lock( &local_transports_lock );
{
int index = (port - ADB_LOCAL_TRANSPORT_PORT)/2;
diff --git a/adb/transport_usb.c b/adb/transport_usb.c
index 3737c5c..2584163 100644
--- a/adb/transport_usb.c
+++ b/adb/transport_usb.c
@@ -110,7 +110,7 @@
usb_kick(t->usb);
}
-void init_usb_transport(atransport *t, usb_handle *h)
+void init_usb_transport(atransport *t, usb_handle *h, int state)
{
D("transport: usb\n");
t->close = remote_close;
@@ -118,7 +118,7 @@
t->read_from_remote = remote_read;
t->write_to_remote = remote_write;
t->sync_token = 1;
- t->connection_state = CS_OFFLINE;
+ t->connection_state = state;
t->type = kTransportUsb;
t->usb = h;
diff --git a/adb/usb_linux.c b/adb/usb_linux.c
index 537122d..863af1d 100644
--- a/adb/usb_linux.c
+++ b/adb/usb_linux.c
@@ -57,6 +57,7 @@
unsigned char ep_out;
unsigned zero_mask;
+ unsigned writeable;
struct usbdevfs_urb urb_in;
struct usbdevfs_urb urb_out;
@@ -115,7 +116,7 @@
}
static void register_device(const char *dev_name, unsigned char ep_in, unsigned char ep_out,
- int ifc, const char *serial, unsigned zero_mask);
+ int ifc, int serial_index, unsigned zero_mask);
static inline int badname(const char *name)
{
@@ -125,19 +126,18 @@
return 0;
}
-static int find_usb_device(const char *base,
- void (*register_device_callback) (const char *, unsigned char, unsigned char, int, const char *, unsigned))
+static void find_usb_device(const char *base,
+ void (*register_device_callback)
+ (const char *, unsigned char, unsigned char, int, int, unsigned))
{
char busname[32], devname[32];
unsigned char local_ep_in, local_ep_out;
DIR *busdir , *devdir ;
struct dirent *de;
int fd ;
- int found_device = 0;
- char serial[256];
busdir = opendir(base);
- if(busdir == 0) return 0;
+ if(busdir == 0) return;
while((de = readdir(busdir)) != 0) {
if(badname(de->d_name)) continue;
@@ -168,7 +168,7 @@
}
// DBGX("[ scanning %s ]\n", devname);
- if((fd = unix_open(devname, O_RDWR)) < 0) {
+ if((fd = unix_open(devname, O_RDONLY)) < 0) {
continue;
}
@@ -263,67 +263,13 @@
local_ep_out = ep1->bEndpointAddress;
}
- // read the device's serial number
- serial[0] = 0;
- memset(serial, 0, sizeof(serial));
- if (device->iSerialNumber) {
- struct usbdevfs_ctrltransfer ctrl;
- __u16 buffer[128];
- __u16 languages[128];
- int i, result;
- int languageCount = 0;
-
- memset(languages, 0, sizeof(languages));
- memset(&ctrl, 0, sizeof(ctrl));
-
- // read list of supported languages
- ctrl.bRequestType = USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_DEVICE;
- ctrl.bRequest = USB_REQ_GET_DESCRIPTOR;
- ctrl.wValue = (USB_DT_STRING << 8) | 0;
- ctrl.wIndex = 0;
- ctrl.wLength = sizeof(languages);
- ctrl.data = languages;
-
- result = ioctl(fd, USBDEVFS_CONTROL, &ctrl);
- if (result > 0)
- languageCount = (result - 2) / 2;
-
- for (i = 1; i <= languageCount; i++) {
- memset(buffer, 0, sizeof(buffer));
- memset(&ctrl, 0, sizeof(ctrl));
-
- ctrl.bRequestType = USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_DEVICE;
- ctrl.bRequest = USB_REQ_GET_DESCRIPTOR;
- ctrl.wValue = (USB_DT_STRING << 8) | device->iSerialNumber;
- ctrl.wIndex = languages[i];
- ctrl.wLength = sizeof(buffer);
- ctrl.data = buffer;
-
- result = ioctl(fd, USBDEVFS_CONTROL, &ctrl);
- if (result > 0) {
- int i;
- // skip first word, and copy the rest to the serial string, changing shorts to bytes.
- result /= 2;
- for (i = 1; i < result; i++)
- serial[i - 1] = buffer[i];
- serial[i - 1] = 0;
- break;
- }
- }
- }
-
register_device_callback(devname, local_ep_in, local_ep_out,
- interface->bInterfaceNumber, serial, zero_mask);
+ interface->bInterfaceNumber, device->iSerialNumber, zero_mask);
- found_device = 1;
break;
} else {
// seek next interface descriptor
- if (i < interfaces - 1) {
- while (bufptr[1] != USB_DT_INTERFACE) {
- bufptr += bufptr[0];
- }
- }
+ bufptr += (USB_DT_ENDPOINT_SIZE * interface->bNumEndpoints);
}
} // end of for
@@ -332,8 +278,6 @@
closedir(devdir);
} //end of busdir while
closedir(busdir);
-
- return found_device;
}
void usb_cleanup()
@@ -537,26 +481,30 @@
if(h->dead == 0) {
h->dead = 1;
- /* HACK ALERT!
- ** Sometimes we get stuck in ioctl(USBDEVFS_REAPURB).
- ** This is a workaround for that problem.
- */
- if (h->reaper_thread) {
- pthread_kill(h->reaper_thread, SIGALRM);
- }
+ if (h->writeable) {
+ /* HACK ALERT!
+ ** Sometimes we get stuck in ioctl(USBDEVFS_REAPURB).
+ ** This is a workaround for that problem.
+ */
+ if (h->reaper_thread) {
+ pthread_kill(h->reaper_thread, SIGALRM);
+ }
- /* cancel any pending transactions
- ** these will quietly fail if the txns are not active,
- ** but this ensures that a reader blocked on REAPURB
- ** will get unblocked
- */
- ioctl(h->desc, USBDEVFS_DISCARDURB, &h->urb_in);
- ioctl(h->desc, USBDEVFS_DISCARDURB, &h->urb_out);
- h->urb_in.status = -ENODEV;
- h->urb_out.status = -ENODEV;
- h->urb_in_busy = 0;
- h->urb_out_busy = 0;
- adb_cond_broadcast(&h->notify);
+ /* cancel any pending transactions
+ ** these will quietly fail if the txns are not active,
+ ** but this ensures that a reader blocked on REAPURB
+ ** will get unblocked
+ */
+ ioctl(h->desc, USBDEVFS_DISCARDURB, &h->urb_in);
+ ioctl(h->desc, USBDEVFS_DISCARDURB, &h->urb_out);
+ h->urb_in.status = -ENODEV;
+ h->urb_out.status = -ENODEV;
+ h->urb_in_busy = 0;
+ h->urb_out_busy = 0;
+ adb_cond_broadcast(&h->notify);
+ } else {
+ unregister_usb_transport(h);
+ }
}
adb_mutex_unlock(&h->lock);
}
@@ -580,11 +528,11 @@
static void register_device(const char *dev_name,
unsigned char ep_in, unsigned char ep_out,
- int interface,
- const char *serial, unsigned zero_mask)
+ int interface, int serial_index, unsigned zero_mask)
{
usb_handle* usb = 0;
int n = 0;
+ char serial[256];
/* Since Linux will not reassign the device ID (and dev_name)
** as long as the device is open, we can add to the list here
@@ -610,6 +558,7 @@
usb->ep_in = ep_in;
usb->ep_out = ep_out;
usb->zero_mask = zero_mask;
+ usb->writeable = 1;
adb_cond_init(&usb->notify, 0);
adb_mutex_init(&usb->lock, 0);
@@ -618,10 +567,66 @@
usb->reaper_thread = 0;
usb->desc = unix_open(usb->fname, O_RDWR);
- if(usb->desc < 0) goto fail;
- D("[ usb open %s fd = %d]\n", usb->fname, usb->desc);
- n = ioctl(usb->desc, USBDEVFS_CLAIMINTERFACE, &interface);
- if(n != 0) goto fail;
+ if(usb->desc < 0) {
+ /* if we fail, see if have read-only access */
+ usb->desc = unix_open(usb->fname, O_RDONLY);
+ if(usb->desc < 0) goto fail;
+ usb->writeable = 0;
+ D("[ usb open read-only %s fd = %d]\n", usb->fname, usb->desc);
+ } else {
+ D("[ usb open %s fd = %d]\n", usb->fname, usb->desc);
+ n = ioctl(usb->desc, USBDEVFS_CLAIMINTERFACE, &interface);
+ if(n != 0) goto fail;
+ }
+
+ /* read the device's serial number */
+ serial[0] = 0;
+ memset(serial, 0, sizeof(serial));
+ if (serial_index) {
+ struct usbdevfs_ctrltransfer ctrl;
+ __u16 buffer[128];
+ __u16 languages[128];
+ int i, result;
+ int languageCount = 0;
+
+ memset(languages, 0, sizeof(languages));
+ memset(&ctrl, 0, sizeof(ctrl));
+
+ // read list of supported languages
+ ctrl.bRequestType = USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_DEVICE;
+ ctrl.bRequest = USB_REQ_GET_DESCRIPTOR;
+ ctrl.wValue = (USB_DT_STRING << 8) | 0;
+ ctrl.wIndex = 0;
+ ctrl.wLength = sizeof(languages);
+ ctrl.data = languages;
+
+ result = ioctl(usb->desc, USBDEVFS_CONTROL, &ctrl);
+ if (result > 0)
+ languageCount = (result - 2) / 2;
+
+ for (i = 1; i <= languageCount; i++) {
+ memset(buffer, 0, sizeof(buffer));
+ memset(&ctrl, 0, sizeof(ctrl));
+
+ ctrl.bRequestType = USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_DEVICE;
+ ctrl.bRequest = USB_REQ_GET_DESCRIPTOR;
+ ctrl.wValue = (USB_DT_STRING << 8) | serial_index;
+ ctrl.wIndex = languages[i];
+ ctrl.wLength = sizeof(buffer);
+ ctrl.data = buffer;
+
+ result = ioctl(usb->desc, USBDEVFS_CONTROL, &ctrl);
+ if (result > 0) {
+ int i;
+ // skip first word, and copy the rest to the serial string, changing shorts to bytes.
+ result /= 2;
+ for (i = 1; i < result; i++)
+ serial[i - 1] = buffer[i];
+ serial[i - 1] = 0;
+ break;
+ }
+ }
+ }
/* add to the end of the active handles */
adb_mutex_lock(&usb_lock);
@@ -631,7 +636,7 @@
usb->next->prev = usb;
adb_mutex_unlock(&usb_lock);
- register_usb_transport(usb, serial);
+ register_usb_transport(usb, serial, usb->writeable);
return;
fail:
diff --git a/adb/usb_linux_client.c b/adb/usb_linux_client.c
index 530bd04..0a21c6f 100644
--- a/adb/usb_linux_client.c
+++ b/adb/usb_linux_client.c
@@ -72,7 +72,7 @@
usb->fd = fd;
D("[ usb_thread - registering device ]\n");
- register_usb_transport(usb, 0);
+ register_usb_transport(usb, 0, 1);
}
// never gets here
diff --git a/adb/usb_osx.c b/adb/usb_osx.c
index 4892c38..00d02da 100644
--- a/adb/usb_osx.c
+++ b/adb/usb_osx.c
@@ -194,30 +194,54 @@
kr = (*dev)->GetDeviceProduct(dev, &product);
kr = (*dev)->USBGetSerialNumberStringIndex(dev, &serialIndex);
- if (serialIndex > 0) {
- IOUSBDevRequest req;
- UInt16 buffer[256];
+ if (serialIndex > 0) {
+ IOUSBDevRequest req;
+ UInt16 buffer[256];
+ UInt16 languages[128];
- req.bmRequestType =
- USBmakebmRequestType(kUSBIn, kUSBStandard, kUSBDevice);
- req.bRequest = kUSBRqGetDescriptor;
- req.wValue = (kUSBStringDesc << 8) | serialIndex;
- req.wIndex = 0;
- req.pData = buffer;
- req.wLength = sizeof(buffer);
- kr = (*dev)->DeviceRequest(dev, &req);
+ memset(languages, 0, sizeof(languages));
- if (kr == kIOReturnSuccess && req.wLenDone > 0) {
- int i, count;
+ req.bmRequestType =
+ USBmakebmRequestType(kUSBIn, kUSBStandard, kUSBDevice);
+ req.bRequest = kUSBRqGetDescriptor;
+ req.wValue = (kUSBStringDesc << 8) | 0;
+ req.wIndex = 0;
+ req.pData = languages;
+ req.wLength = sizeof(languages);
+ kr = (*dev)->DeviceRequest(dev, &req);
- // skip first word, and copy the rest to the serial string,
- // changing shorts to bytes.
- count = (req.wLenDone - 1) / 2;
- for (i = 0; i < count; i++)
- serial[i] = buffer[i + 1];
- serial[i] = 0;
- }
- }
+ if (kr == kIOReturnSuccess && req.wLenDone > 0) {
+
+ int langCount = (req.wLenDone - 2) / 2, lang;
+
+ for (lang = 1; lang <= langCount; lang++) {
+
+ memset(buffer, 0, sizeof(buffer));
+ memset(&req, 0, sizeof(req));
+
+ req.bmRequestType =
+ USBmakebmRequestType(kUSBIn, kUSBStandard, kUSBDevice);
+ req.bRequest = kUSBRqGetDescriptor;
+ req.wValue = (kUSBStringDesc << 8) | serialIndex;
+ req.wIndex = languages[lang];
+ req.pData = buffer;
+ req.wLength = sizeof(buffer);
+ kr = (*dev)->DeviceRequest(dev, &req);
+
+ if (kr == kIOReturnSuccess && req.wLenDone > 0) {
+ int i, count;
+
+ // skip first word, and copy the rest to the serial string,
+ // changing shorts to bytes.
+ count = (req.wLenDone - 1) / 2;
+ for (i = 0; i < count; i++)
+ serial[i] = buffer[i + 1];
+ serial[i] = 0;
+ break;
+ }
+ }
+ }
+ }
(*dev)->Release(dev);
DBG("INFO: Found vid=%04x pid=%04x serial=%s\n", vendor, product,
@@ -232,7 +256,7 @@
}
DBG("AndroidDeviceAdded calling register_usb_transport\n");
- register_usb_transport(handle, (serial[0] ? serial : NULL));
+ register_usb_transport(handle, (serial[0] ? serial : NULL), 1);
// Register for an interest notification of this device being removed.
// Pass the reference to our private data as the refCon for the
diff --git a/adb/usb_windows.c b/adb/usb_windows.c
index 0951f67..38c4cf4 100644
--- a/adb/usb_windows.c
+++ b/adb/usb_windows.c
@@ -488,7 +488,7 @@
true)) {
// Lets make sure that we don't duplicate this device
if (register_new_device(handle)) {
- register_usb_transport(handle, serial_number);
+ register_usb_transport(handle, serial_number, 1);
} else {
D("register_new_device failed for %s\n", interf_name);
usb_cleanup_handle(handle);
diff --git a/fastboot/util_osx.c b/fastboot/util_osx.c
index 068241c..b43e316 100644
--- a/fastboot/util_osx.c
+++ b/fastboot/util_osx.c
@@ -26,7 +26,6 @@
* SUCH DAMAGE.
*/
-#include <utils/executablepath.h>
#import <Carbon/Carbon.h>
#include <unistd.h>
diff --git a/init/devices.c b/init/devices.c
index 60f9b9c..606a074 100644
--- a/init/devices.c
+++ b/init/devices.c
@@ -288,7 +288,7 @@
chown(path, uid, gid);
}
-#ifdef LOG_UEVENTS
+#if LOG_UEVENTS
static inline suseconds_t get_usecs(void)
{
diff --git a/rootdir/init.rc b/rootdir/init.rc
index a648ad8..aa0ef59 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -38,7 +38,7 @@
# Create cgroup mount points for process groups
mkdir /dev/cpuctl
mount cgroup none /dev/cpuctl cpu
- chown sytem system /dev/cpuctl
+ chown system system /dev/cpuctl
chown system system /dev/cpuctl/tasks
chmod 0777 /dev/cpuctl/tasks
write /dev/cpuctl/cpu.shares 1024