merge from donut
diff --git a/adb/services.c b/adb/services.c
index 0a5edcf..78d092b 100644
--- a/adb/services.c
+++ b/adb/services.c
@@ -31,6 +31,8 @@
# include <netinet/in.h>
# include <netdb.h>
# endif
+#else
+#include <sys/poll.h>
#endif
typedef struct stinfo stinfo;
@@ -196,12 +198,9 @@
return s[0];
}
+#if !ADB_HOST
static int create_subprocess(const char *cmd, const char *arg0, const char *arg1)
{
-#ifdef HAVE_WIN32_PROC
- fprintf(stderr, "error: create_subprocess not implemented on Win32 (%s %s %s)\n", cmd, arg0, arg1);
- return -1;
-#else /* !HAVE_WIN32_PROC */
char *devname;
int ptm;
pid_t pid;
@@ -244,7 +243,6 @@
cmd, strerror(errno), errno);
exit(-1);
} else {
-#if !ADB_HOST
// set child's OOM adjustment to zero
char text[64];
snprintf(text, sizeof text, "/proc/%d/oom_adj", pid);
@@ -255,11 +253,11 @@
} else {
D("adb: unable to open %s\n", text);
}
-#endif
+
return ptm;
}
-#endif /* !HAVE_WIN32_PROC */
}
+#endif /* !ADB_HOST */
#if ADB_HOST
#define SHELL_COMMAND "/bin/sh"
@@ -267,6 +265,76 @@
#define SHELL_COMMAND "/system/bin/sh"
#endif
+#if !ADB_HOST
+static void shell_service(int s, void *command)
+{
+ char buffer[MAX_PAYLOAD];
+ char buffer2[MAX_PAYLOAD];
+ struct pollfd ufds[2];
+ int fd, ret = 0;
+ unsigned count = 0;
+ char** args = (char **)command;
+ fd = create_subprocess(SHELL_COMMAND, args[0], args[1]);
+
+ while (1) {
+ while (count < sizeof(buffer)) {
+ ufds[0].fd = fd;
+ ufds[0].events = POLLIN | POLLHUP;
+ ufds[0].revents = 0;
+ ufds[1].fd = s;
+ ufds[1].events = POLLIN | POLLHUP;
+ ufds[1].revents = 0;
+ // use a 100ms timeout so we don't block indefinitely with our
+ // buffer partially filled.
+ ret = poll(ufds, 2, 100);
+ if (ret <= 0) {
+ D("poll returned %d\n", ret);
+ // file has closed or we timed out
+ // set ret to 1 so we don't exit the outer loop
+ ret = 1;
+ break;
+ }
+
+ if (ufds[0].revents & POLLIN) {
+ ret = adb_read(fd, buffer + count, sizeof(buffer) - count);
+ D("read fd ret: %d, count: %d\n", ret, count);
+ if (ret > 0)
+ count += ret;
+ else
+ break;
+ }
+ if (ufds[1].revents & POLLIN) {
+ ret = adb_read(s, buffer2, sizeof(buffer2));
+ D("read s ret: %d\n", ret);
+ if (ret > 0)
+ adb_write(fd, buffer2, ret);
+ else
+ break;
+ }
+
+ if ((ufds[0].revents & POLLHUP) || (ufds[1].revents & POLLHUP)) {
+ // set flag to exit after flushing the buffer
+ ret = -1;
+ break;
+ }
+ }
+
+ D("writing: %d\n", count);
+ if (count > 0) {
+ adb_write(s, buffer, count);
+ count = 0;
+ }
+ if (ret <= 0)
+ break;
+ }
+
+ D("shell_service done\n");
+
+ adb_close(fd);
+ adb_close(s);
+}
+#endif // !ADB_HOST
+
int service_to_fd(const char *name)
{
int ret = -1;
@@ -317,14 +385,16 @@
ret = create_jdwp_connection_fd(atoi(name+5));
} else if (!strncmp(name, "log:", 4)) {
ret = create_service_thread(log_service, get_log_file_path(name + 4));
-#endif
} else if(!HOST && !strncmp(name, "shell:", 6)) {
+ const char* args[2];
if(name[6]) {
- ret = create_subprocess(SHELL_COMMAND, "-c", name + 6);
+ args[0] = "-c";
+ args[1] = name + 6;
} else {
- ret = create_subprocess(SHELL_COMMAND, "-", 0);
+ args[0] = "-";
+ args[1] = 0;
}
-#if !ADB_HOST
+ ret = create_service_thread(shell_service, (void *)args);
} else if(!strncmp(name, "sync:", 5)) {
ret = create_service_thread(file_sync_service, NULL);
} else if(!strncmp(name, "remount:", 8)) {
diff --git a/adb/usb_linux.c b/adb/usb_linux.c
index 95c2ce6..537122d 100644
--- a/adb/usb_linux.c
+++ b/adb/usb_linux.c
@@ -318,9 +318,13 @@
found_device = 1;
break;
} else {
- // skip to next interface
- bufptr += (interface->bNumEndpoints * USB_DT_ENDPOINT_SIZE);
- }
+ // seek next interface descriptor
+ if (i < interfaces - 1) {
+ while (bufptr[1] != USB_DT_INTERFACE) {
+ bufptr += bufptr[0];
+ }
+ }
+ }
} // end of for
adb_close(fd);
diff --git a/adb/usb_vendors.c b/adb/usb_vendors.c
index 9a15146..f8c54d7 100644
--- a/adb/usb_vendors.c
+++ b/adb/usb_vendors.c
@@ -39,11 +39,17 @@
#define VENDOR_ID_GOOGLE 0x18d1
// HTC's USB Vendor ID
#define VENDOR_ID_HTC 0x0bb4
+// Samsung's USB Vendor ID
+#define VENDOR_ID_SAMSUNG 0x04e8
+// Motorola's USB Vendor ID
+#define VENDOR_ID_MOTOROLA 0x22b8
/** built-in vendor list */
int builtInVendorIds[] = {
VENDOR_ID_GOOGLE,
VENDOR_ID_HTC,
+ VENDOR_ID_SAMSUNG,
+ VENDOR_ID_MOTOROLA,
};
#define BUILT_IN_VENDOR_COUNT (sizeof(builtInVendorIds)/sizeof(builtInVendorIds[0]))
diff --git a/rootdir/init.rc b/rootdir/init.rc
index dab9027..a648ad8 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -287,7 +287,7 @@
service installd /system/bin/installd
socket installd stream 600 system system
-service flash_recovery /system/bin/flash_image recovery /system/recovery.img
+service flash_recovery /system/etc/install-recovery.sh
oneshot
service racoon /system/bin/racoon