Merge change I4e5c1c26
* changes:
Fix use of memset function
diff --git a/adb/Android.mk b/adb/Android.mk
index f3eaa6e..6325e53 100644
--- a/adb/Android.mk
+++ b/adb/Android.mk
@@ -25,6 +25,12 @@
LOCAL_LDLIBS += -lpthread -framework CoreFoundation -framework IOKit -framework Carbon
endif
+ifeq ($(HOST_OS),freebsd)
+ USB_SRCS := usb_libusb.c
+ EXTRA_SRCS := get_my_path_freebsd.c
+ LOCAL_LDLIBS += -lpthread -lusb
+endif
+
ifeq ($(HOST_OS),windows)
USB_SRCS := usb_windows.c
EXTRA_SRCS := get_my_path_windows.c
diff --git a/adb/MODULE_LICENSE_APACHE2 b/adb/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/adb/MODULE_LICENSE_APACHE2
diff --git a/adb/NOTICE b/adb/NOTICE
new file mode 100644
index 0000000..9ffcc08
--- /dev/null
+++ b/adb/NOTICE
@@ -0,0 +1,191 @@
+
+ Copyright (c) 2006-2009, The Android Open Source Project
+ Copyright 2006, Brian Swetland <swetland@frotz.net>
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
diff --git a/adb/adb.c b/adb/adb.c
index 283ebce..7df3f7b 100644
--- a/adb/adb.c
+++ b/adb/adb.c
@@ -783,7 +783,7 @@
fprintf(stderr, "pipe failed in launch_server, errno: %d\n", errno);
return -1;
}
- get_my_path(path);
+ get_my_path(path, PATH_MAX);
pid_t pid = fork();
if(pid < 0) return -1;
@@ -1020,19 +1020,24 @@
char* portstr = strchr(host, ':');
if (!portstr) {
- snprintf(buffer, sizeof(buffer), "unable to parse %s as <host>:<port>\n", host);
+ snprintf(buffer, sizeof(buffer), "unable to parse %s as <host>:<port>", host);
goto done;
}
+ if (find_transport(host)) {
+ snprintf(buffer, sizeof(buffer), "Already connected to %s", 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);
+ snprintf(buffer, sizeof(buffer), "bad port number %s", 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);
+ snprintf(buffer, sizeof(buffer), "unable to connect to %s:%d", host, port);
goto done;
}
@@ -1041,10 +1046,28 @@
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);
+ snprintf(buffer, sizeof(buffer), "connected to %s:%d", host, port);
done:
- snprintf(buf, sizeof(buf), "OKAY%04x%s",(unsigned)strlen(buffer),buffer);
+ snprintf(buf, sizeof(buf), "OKAY%04x%s",(unsigned)strlen(buffer), buffer);
+ writex(reply_fd, buf, strlen(buf));
+ return 0;
+ }
+
+ // remove TCP transport
+ if (!strncmp(service, "disconnect:", 11)) {
+ char buffer[4096];
+ memset(buffer, 0, sizeof(buffer));
+ char* serial = service + 11;
+ atransport *t = find_transport(serial);
+
+ if (t) {
+ unregister_transport(t);
+ } else {
+ snprintf(buffer, sizeof(buffer), "No such device %s", serial);
+ }
+
+ snprintf(buf, sizeof(buf), "OKAY%04x%s",(unsigned)strlen(buffer), buffer);
writex(reply_fd, buf, strlen(buf));
return 0;
}
diff --git a/adb/adb.h b/adb/adb.h
index 713666f..a148019 100644
--- a/adb/adb.h
+++ b/adb/adb.h
@@ -236,7 +236,7 @@
void handle_packet(apacket *p, atransport *t);
void send_packet(apacket *p, atransport *t);
-void get_my_path(char s[PATH_MAX]);
+void get_my_path(char *s, size_t maxLen);
int launch_server();
int adb_main(int is_daemon);
@@ -270,11 +270,17 @@
/* cause new transports to be init'd and added to the list */
void register_socket_transport(int s, const char *serial, int port, int local);
+
+/* this should only be used for the "adb disconnect" command */
+void unregister_transport(atransport *t);
+
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);
+atransport *find_transport(const char *serial);
+
int service_to_fd(const char *name);
#if ADB_HOST
asocket *host_service_to_socket(const char* name, const char *serial);
diff --git a/adb/commandline.c b/adb/commandline.c
index 411bb82..52bcedc 100644
--- a/adb/commandline.c
+++ b/adb/commandline.c
@@ -50,7 +50,7 @@
static int do_cmd(transport_type ttype, char* serial, char *cmd, ...);
-void get_my_path(char s[PATH_MAX]);
+void get_my_path(char *s, size_t maxLen);
int find_sync_dirs(const char *srcarg,
char **android_srcdir_out, char **data_srcdir_out);
int install_app(transport_type transport, char* serial, int argc, char** argv);
@@ -106,6 +106,7 @@
" be an absolute path.\n"
" devices - list all connected devices\n"
" connect <host>:<port> - connect to a device via TCP/IP"
+ " disconnect <host>:<port> - disconnect from a TCP/IP device"
"\n"
"device commands:\n"
" adb push <local> <remote> - copy file/dir to device\n"
@@ -672,7 +673,7 @@
/* If the CWD isn't under a good-looking top, see if the
* executable is.
*/
- get_my_path(dir);
+ get_my_path(dir, PATH_MAX);
top = find_top_from(dir, path_buf);
}
return top;
@@ -853,10 +854,10 @@
}
}
- if(!strcmp(argv[0], "connect")) {
+ if(!strcmp(argv[0], "connect") || !strcmp(argv[0], "disconnect")) {
char *tmp;
if (argc != 2) {
- fprintf(stderr, "Usage: adb connect <host>:<port>\n");
+ fprintf(stderr, "Usage: adb %s <host>:<port>\n", argv[0]);
return 1;
}
snprintf(buf, sizeof buf, "host:%s:%s", argv[0], argv[1]);
diff --git a/adb/get_my_path_darwin.c b/adb/get_my_path_darwin.c
index 6125cb4..5b95d15 100644
--- a/adb/get_my_path_darwin.c
+++ b/adb/get_my_path_darwin.c
@@ -17,7 +17,7 @@
#import <Carbon/Carbon.h>
#include <unistd.h>
-void get_my_path(char s[PATH_MAX])
+void get_my_path(char *s, size_t maxLen)
{
ProcessSerialNumber psn;
GetCurrentProcess(&psn);
@@ -25,6 +25,6 @@
dict = ProcessInformationCopyDictionary(&psn, 0xffffffff);
CFStringRef value = (CFStringRef)CFDictionaryGetValue(dict,
CFSTR("CFBundleExecutable"));
- CFStringGetCString(value, s, PATH_MAX - 1, kCFStringEncodingUTF8);
+ CFStringGetCString(value, s, maxLen, kCFStringEncodingUTF8);
}
diff --git a/adb/get_my_path_freebsd.c b/adb/get_my_path_freebsd.c
new file mode 100644
index 0000000..b06ec66
--- /dev/null
+++ b/adb/get_my_path_freebsd.c
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2009 bsdroid project
+ * Alexey Tarasov <tarasov@dodologics.com>
+ *
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <sys/types.h>
+#include <unistd.h>
+#include <limits.h>
+#include <stdio.h>
+
+void
+get_my_path(char *exe, size_t maxLen)
+{
+ char proc[64];
+
+ snprintf(proc, sizeof(proc), "/proc/%d/file", getpid());
+
+ int err = readlink(proc, exe, maxLen - 1);
+
+ exe[err > 0 ? err : 0] = '\0';
+}
+
diff --git a/adb/get_my_path_linux.c b/adb/get_my_path_linux.c
index f516e59..179c3dd 100644
--- a/adb/get_my_path_linux.c
+++ b/adb/get_my_path_linux.c
@@ -19,15 +19,15 @@
#include <limits.h>
#include <stdio.h>
-void get_my_path(char exe[PATH_MAX])
+void get_my_path(char *exe, size_t maxLen)
{
char proc[64];
snprintf(proc, sizeof proc, "/proc/%d/exe", getpid());
- int err = readlink(proc, exe, PATH_MAX - 1);
+ int err = readlink(proc, exe, maxLen - 1);
if(err > 0) {
- exe[err] = 0;
+ exe[err] = '\0';
} else {
- exe[0] = 0;
+ exe[0] = '\0';
}
}
diff --git a/adb/get_my_path_windows.c b/adb/get_my_path_windows.c
index fc7143c..ddf2816 100644
--- a/adb/get_my_path_windows.c
+++ b/adb/get_my_path_windows.c
@@ -18,14 +18,17 @@
#include <assert.h>
#include <windows.h>
-void get_my_path(char exe[PATH_MAX])
+void get_my_path(char *exe, size_t maxLen)
{
- char* r;
+ char *r;
- GetModuleFileName( NULL, exe, PATH_MAX-1 );
- exe[PATH_MAX-1] = 0;
- r = strrchr( exe, '\\' );
- if (r)
- *r = 0;
+ /* XXX: should be GetModuleFileNameA */
+ if (GetModuleFileName(NULL, exe, maxLen) > 0) {
+ r = strrchr(exe, '\\');
+ if (r != NULL)
+ *r = '\0';
+ } else {
+ exe[0] = '\0';
+ }
}
diff --git a/adb/jdwp_service.c b/adb/jdwp_service.c
index ae7f12d..0c26f7b 100644
--- a/adb/jdwp_service.c
+++ b/adb/jdwp_service.c
@@ -164,7 +164,7 @@
proc->next->prev = proc->prev;
if (proc->socket >= 0) {
- shutdown(proc->socket, SHUT_RDWR);
+ adb_shutdown(proc->socket);
adb_close(proc->socket);
proc->socket = -1;
}
diff --git a/adb/services.c b/adb/services.c
index 2864ac9..b5df554 100644
--- a/adb/services.c
+++ b/adb/services.c
@@ -32,8 +32,7 @@
# include <netdb.h>
# endif
#else
-#include <sys/poll.h>
-#include <sys/reboot.h>
+# include <sys/reboot.h>
#endif
typedef struct stinfo stinfo;
@@ -64,6 +63,7 @@
adb_mutex_lock(&dns_lock);
hp = gethostbyname(hostname);
+ free(cookie);
if(hp == 0) {
writex(fd, &zero, 4);
} else {
@@ -185,6 +185,7 @@
snprintf(buf, sizeof(buf), "reboot failed: %s\n", strerror(errno));
writex(fd, buf, strlen(buf));
}
+ free(arg);
adb_close(fd);
}
@@ -253,9 +254,12 @@
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;
@@ -298,6 +302,7 @@
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);
@@ -308,11 +313,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"
@@ -320,76 +325,6 @@
#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;
@@ -440,25 +375,22 @@
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]) {
- args[0] = "-c";
- args[1] = name + 6;
+ ret = create_subprocess(SHELL_COMMAND, "-c", name + 6);
} else {
- args[0] = "-";
- args[1] = 0;
+ ret = create_subprocess(SHELL_COMMAND, "-", 0);
}
- ret = create_service_thread(shell_service, (void *)args);
+#if !ADB_HOST
} else if(!strncmp(name, "sync:", 5)) {
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);
+ void* arg = strdup(name + 7);
+ if(arg == 0) return -1;
+ ret = create_service_thread(reboot_service, arg);
} else if(!strncmp(name, "root:", 5)) {
ret = create_service_thread(restart_root_service, NULL);
} else if(!strncmp(name, "tcpip:", 6)) {
diff --git a/adb/sysdeps.h b/adb/sysdeps.h
index 389fbd2..6372649 100644
--- a/adb/sysdeps.h
+++ b/adb/sysdeps.h
@@ -113,6 +113,7 @@
extern int adb_read(int fd, void* buf, int len);
extern int adb_write(int fd, const void* buf, int len);
extern int adb_lseek(int fd, int pos, int where);
+extern int adb_shutdown(int fd);
extern int adb_close(int fd);
static __inline__ int unix_close(int fd)
@@ -327,6 +328,13 @@
#undef open
#define open ___xxx_open
+static __inline__ int adb_shutdown(int fd)
+{
+ return shutdown(fd, SHUT_RDWR);
+}
+#undef shutdown
+#define shutdown ____xxx_shutdown
+
static __inline__ int adb_close(int fd)
{
return close(fd);
diff --git a/adb/sysdeps_win32.c b/adb/sysdeps_win32.c
index a8e3bb9..ced91e8 100644
--- a/adb/sysdeps_win32.c
+++ b/adb/sysdeps_win32.c
@@ -435,6 +435,20 @@
}
+int adb_shutdown(int fd)
+{
+ FH f = _fh_from_int(fd);
+
+ if (!f) {
+ return -1;
+ }
+
+ D( "adb_shutdown: %s\n", f->name);
+ shutdown( f->fh_socket, SD_BOTH );
+ return 0;
+}
+
+
int adb_close(int fd)
{
FH f = _fh_from_int(fd);
diff --git a/adb/transport.c b/adb/transport.c
index 617dabf..c2877d2 100644
--- a/adb/transport.c
+++ b/adb/transport.c
@@ -864,6 +864,38 @@
register_transport(t);
}
+#if ADB_HOST
+atransport *find_transport(const char *serial)
+{
+ atransport *t;
+
+ adb_mutex_lock(&transport_lock);
+ for(t = transport_list.next; t != &transport_list; t = t->next) {
+ if (t->serial && !strcmp(serial, t->serial)) {
+ break;
+ }
+ }
+ adb_mutex_unlock(&transport_lock);
+
+ if (t != &transport_list)
+ return t;
+ else
+ return 0;
+}
+
+void unregister_transport(atransport *t)
+{
+ adb_mutex_lock(&transport_lock);
+ t->next->prev = t->prev;
+ t->prev->next = t->next;
+ adb_mutex_unlock(&transport_lock);
+
+ kick_transport(t);
+ transport_unref(t);
+}
+
+#endif
+
void register_usb_transport(usb_handle *usb, const char *serial, unsigned writeable)
{
atransport *t = calloc(1, sizeof(atransport));
diff --git a/adb/transport_local.c b/adb/transport_local.c
index c528d1f..81d120e 100644
--- a/adb/transport_local.c
+++ b/adb/transport_local.c
@@ -204,6 +204,7 @@
{
int fd = t->sfd;
t->sfd = -1;
+ adb_shutdown(fd);
adb_close(fd);
#if ADB_HOST
diff --git a/adb/usb_libusb.c b/adb/usb_libusb.c
new file mode 100644
index 0000000..8c75266
--- /dev/null
+++ b/adb/usb_libusb.c
@@ -0,0 +1,657 @@
+/*
+ * Copyright (C) 2009 bsdroid project
+ * Alexey Tarasov <tarasov@dodologics.com>
+ *
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <sys/endian.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/uio.h>
+
+#include <err.h>
+#include <errno.h>
+#include <poll.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+#include <string.h>
+#include <sysexits.h>
+#include <unistd.h>
+#include <libusb.h>
+#include "sysdeps.h"
+
+#define TRACE_TAG TRACE_USB
+#include "adb.h"
+
+static adb_mutex_t usb_lock = ADB_MUTEX_INITIALIZER;
+static libusb_context *ctx = NULL;
+
+struct usb_handle
+{
+ usb_handle *prev;
+ usb_handle *next;
+
+ libusb_device *dev;
+ libusb_device_handle *devh;
+ int interface;
+ uint8_t dev_bus;
+ uint8_t dev_addr;
+
+ int zero_mask;
+ unsigned char end_point_address[2];
+ char serial[128];
+
+ adb_cond_t notify;
+ adb_mutex_t lock;
+};
+
+static struct usb_handle handle_list = {
+ .prev = &handle_list,
+ .next = &handle_list,
+};
+
+void
+usb_cleanup()
+{
+ libusb_exit(ctx);
+}
+
+void
+report_bulk_libusb_error(int r)
+{
+ switch (r) {
+ case LIBUSB_ERROR_TIMEOUT:
+ D("Transfer timeout\n");
+ break;
+
+ case LIBUSB_ERROR_PIPE:
+ D("Control request is not supported\n");
+ break;
+
+ case LIBUSB_ERROR_OVERFLOW:
+ D("Device offered more data\n");
+ break;
+
+ case LIBUSB_ERROR_NO_DEVICE :
+ D("Device was disconnected\n");
+ break;
+
+ default:
+ D("Error %d during transfer\n", r);
+ break;
+ };
+}
+
+static int
+usb_bulk_write(usb_handle *uh, const void *data, int len)
+{
+ int r = 0;
+ int transferred = 0;
+
+ r = libusb_bulk_transfer(uh->devh, uh->end_point_address[1], (void *)data, len,
+ &transferred, 0);
+
+ if (r != 0) {
+ D("usb_bulk_write(): ");
+ report_bulk_libusb_error(r);
+ return r;
+ }
+
+ return (transferred);
+}
+
+static int
+usb_bulk_read(usb_handle *uh, void *data, int len)
+{
+ int r = 0;
+ int transferred = 0;
+
+ r = libusb_bulk_transfer(uh->devh, uh->end_point_address[0], data, len,
+ &transferred, 0);
+
+ if (r != 0) {
+ D("usb_bulk_read(): ");
+ report_bulk_libusb_error(r);
+ return r;
+ }
+
+ return (transferred);
+}
+
+int
+usb_write(struct usb_handle *uh, const void *_data, int len)
+{
+ unsigned char *data = (unsigned char*) _data;
+ int n;
+ int need_zero = 0;
+
+ if (uh->zero_mask == 1) {
+ if (!(len & uh->zero_mask)) {
+ need_zero = 1;
+ }
+ }
+
+ D("usb_write(): %p:%d -> transport %p\n", _data, len, uh);
+
+ while (len > 0) {
+ int xfer = (len > 4096) ? 4096 : len;
+
+ n = usb_bulk_write(uh, data, xfer);
+
+ if (n != xfer) {
+ D("usb_write(): failed for transport %p (%d bytes left)\n", uh, len);
+ return -1;
+ }
+
+ len -= xfer;
+ data += xfer;
+ }
+
+ if (need_zero){
+ n = usb_bulk_write(uh, _data, 0);
+
+ if (n < 0) {
+ D("usb_write(): failed to finish operation for transport %p\n", uh);
+ }
+ return n;
+ }
+
+ return 0;
+}
+
+int
+usb_read(struct usb_handle *uh, void *_data, int len)
+{
+ unsigned char *data = (unsigned char*) _data;
+ int n;
+
+ D("usb_read(): %p:%d <- transport %p\n", _data, len, uh);
+
+ while (len > 0) {
+ int xfer = (len > 4096) ? 4096 : len;
+
+ n = usb_bulk_read(uh, data, xfer);
+
+ if (n != xfer) {
+ if (n > 0) {
+ data += n;
+ len -= n;
+ continue;
+ }
+
+ D("usb_read(): failed for transport %p (%d bytes left)\n", uh, len);
+ return -1;
+ }
+
+ len -= xfer;
+ data += xfer;
+ }
+
+ return 0;
+ }
+
+int
+usb_close(struct usb_handle *h)
+{
+ D("usb_close(): closing transport %p\n", h);
+ adb_mutex_lock(&usb_lock);
+
+ h->next->prev = h->prev;
+ h->prev->next = h->next;
+ h->prev = NULL;
+ h->next = NULL;
+
+ libusb_release_interface(h->devh, h->interface);
+ libusb_close(h->devh);
+ libusb_unref_device(h->dev);
+
+ adb_mutex_unlock(&usb_lock);
+
+ free(h);
+
+ return (0);
+}
+
+void usb_kick(struct usb_handle *h)
+{
+ D("usb_cick(): kicking transport %p\n", h);
+
+ adb_mutex_lock(&h->lock);
+ unregister_usb_transport(h);
+ adb_mutex_unlock(&h->lock);
+
+ h->next->prev = h->prev;
+ h->prev->next = h->next;
+ h->prev = NULL;
+ h->next = NULL;
+
+ libusb_release_interface(h->devh, h->interface);
+ libusb_close(h->devh);
+ libusb_unref_device(h->dev);
+ free(h);
+}
+
+int
+check_usb_interface(libusb_interface *interface,
+ libusb_device_descriptor *desc,
+ struct usb_handle *uh)
+{
+ int e;
+
+ if (interface->num_altsetting == 0) {
+ D("check_usb_interface(): No interface settings\n");
+ return -1;
+ }
+
+ libusb_interface_descriptor *idesc = &interface->altsetting[0];
+
+ if (idesc->bNumEndpoints != 2) {
+ D("check_usb_interface(): Interface have not 2 endpoints, ignoring\n");
+ return -1;
+ }
+
+ for (e = 0; e < idesc->bNumEndpoints; e++) {
+ libusb_endpoint_descriptor *edesc = &idesc->endpoint[e];
+
+ if (edesc->bmAttributes != LIBUSB_TRANSFER_TYPE_BULK) {
+ D("check_usb_interface(): Endpoint (%u) is not bulk (%u), ignoring\n",
+ edesc->bmAttributes, LIBUSB_TRANSFER_TYPE_BULK);
+ return -1;
+ }
+
+ if (edesc->bEndpointAddress & LIBUSB_ENDPOINT_IN)
+ uh->end_point_address[0] = edesc->bEndpointAddress;
+ else
+ uh->end_point_address[1] = edesc->bEndpointAddress;
+
+ /* aproto 01 needs 0 termination */
+ if (idesc->bInterfaceProtocol == 0x01) {
+ uh->zero_mask = edesc->wMaxPacketSize - 1;
+ D("check_usb_interface(): Forced Android interface protocol v.1\n");
+ }
+ }
+
+ D("check_usb_interface(): Device: %04x:%04x "
+ "iclass: %x, isclass: %x, iproto: %x ep: %x/%x-> ",
+ desc->idVendor, desc->idProduct, idesc->bInterfaceClass,
+ idesc->bInterfaceSubClass, idesc->bInterfaceProtocol,
+ uh->end_point_address[0], uh->end_point_address[1]);
+
+ if (!is_adb_interface(desc->idVendor, desc->idProduct,
+ idesc->bInterfaceClass, idesc->bInterfaceSubClass,
+ idesc->bInterfaceProtocol))
+ {
+ D("not matches\n");
+ return -1;
+ }
+
+ D("matches\n");
+ return 1;
+}
+
+int
+check_usb_interfaces(libusb_config_descriptor *config,
+ libusb_device_descriptor *desc, struct usb_handle *uh)
+{
+ int i;
+
+ for (i = 0; i < config->bNumInterfaces; ++i) {
+ if (check_usb_interface(&config->interface[i], desc, uh) != -1) {
+ /* found some interface and saved information about it */
+ D("check_usb_interfaces(): Interface %d of %04x:%04x "
+ "matches Android device\n", i, desc->idVendor,
+ desc->idProduct);
+
+ return i;
+ }
+ }
+
+ return -1;
+}
+
+int
+register_device(struct usb_handle *uh, const char *serial)
+{
+ D("register_device(): Registering %p [%s] as USB transport\n",
+ uh, serial);
+
+ struct usb_handle *usb= NULL;
+
+ usb = calloc(1, sizeof(struct usb_handle));
+ memcpy(usb, uh, sizeof(struct usb_handle));
+ strcpy(usb->serial, uh->serial);
+
+ adb_cond_init(&usb->notify, 0);
+ adb_mutex_init(&usb->lock, 0);
+
+ adb_mutex_lock(&usb_lock);
+
+ usb->next = &handle_list;
+ usb->prev = handle_list.prev;
+ usb->prev->next = usb;
+ usb->next->prev = usb;
+
+ adb_mutex_unlock(&usb_lock);
+
+ register_usb_transport(usb, serial, 1);
+
+ return (1);
+}
+
+int
+already_registered(usb_handle *uh)
+{
+ struct usb_handle *usb= NULL;
+ int exists = 0;
+
+ adb_mutex_lock(&usb_lock);
+
+ for (usb = handle_list.next; usb != &handle_list; usb = usb->next) {
+ if ((usb->dev_bus == uh->dev_bus) &&
+ (usb->dev_addr == uh->dev_addr))
+ {
+ exists = 1;
+ break;
+ }
+ }
+
+ adb_mutex_unlock(&usb_lock);
+
+ return exists;
+}
+
+void
+check_device(libusb_device *dev)
+{
+ struct usb_handle uh;
+ int i = 0;
+ int found = -1;
+ char serial[256] = {0};
+
+ libusb_device_descriptor desc;
+ libusb_config_descriptor *config = NULL;
+
+ int r = libusb_get_device_descriptor(dev, &desc);
+
+ if (r != LIBUSB_SUCCESS) {
+ D("check_device(): Failed to get device descriptor\n");
+ return;
+ }
+
+ if ((desc.idVendor == 0) && (desc.idProduct == 0))
+ return;
+
+ D("check_device(): Probing usb device %04x:%04x\n",
+ desc.idVendor, desc.idProduct);
+
+ if (!is_adb_interface (desc.idVendor, desc.idProduct,
+ ADB_CLASS, ADB_SUBCLASS, ADB_PROTOCOL))
+ {
+ D("check_device(): Ignored due unknown vendor id\n");
+ return;
+ }
+
+ uh.dev_bus = libusb_get_bus_number(dev);
+ uh.dev_addr = libusb_get_device_address(dev);
+
+ if (already_registered(&uh)) {
+ D("check_device(): Device (bus: %d, address: %d) "
+ "is already registered\n", uh.dev_bus, uh.dev_addr);
+ return;
+ }
+
+ D("check_device(): Device bus: %d, address: %d\n",
+ uh.dev_bus, uh.dev_addr);
+
+ r = libusb_get_active_config_descriptor(dev, &config);
+
+ if (r != 0) {
+ if (r == LIBUSB_ERROR_NOT_FOUND) {
+ D("check_device(): Device %4x:%4x is unconfigured\n",
+ desc.idVendor, desc.idProduct);
+ return;
+ }
+
+ D("check_device(): Failed to get configuration for %4x:%4x\n",
+ desc.idVendor, desc.idProduct);
+ return;
+ }
+
+ if (config == NULL) {
+ D("check_device(): Sanity check failed after "
+ "getting active config\n");
+ return;
+ }
+
+ if (config->interface != NULL) {
+ found = check_usb_interfaces(config, &desc, &uh);
+ }
+
+ /* not needed anymore */
+ libusb_free_config_descriptor(config);
+
+ r = libusb_open(dev, &uh.devh);
+ uh.dev = dev;
+
+ if (r != 0) {
+ switch (r) {
+ case LIBUSB_ERROR_NO_MEM:
+ D("check_device(): Memory allocation problem\n");
+ break;
+
+ case LIBUSB_ERROR_ACCESS:
+ D("check_device(): Permissions problem, "
+ "current user priveleges are messed up?\n");
+ break;
+
+ case LIBUSB_ERROR_NO_DEVICE:
+ D("check_device(): Device disconected, bad cable?\n");
+ break;
+
+ default:
+ D("check_device(): libusb triggered error %d\n", r);
+ }
+ // skip rest
+ found = -1;
+ }
+
+ if (found >= 0) {
+ D("check_device(): Device matches Android interface\n");
+ // read the device's serial number
+ memset(serial, 0, sizeof(serial));
+ uh.interface = found;
+
+ r = libusb_claim_interface(uh.devh, uh.interface);
+
+ if (r < 0) {
+ D("check_device(): Failed to claim interface %d\n",
+ uh.interface);
+
+ goto fail;
+ }
+
+ if (desc.iSerialNumber) {
+ // reading serial
+ uint16_t buffer[128] = {0};
+ uint16_t languages[128] = {0};
+ int languageCount = 0;
+
+ memset(languages, 0, sizeof(languages));
+ r = libusb_control_transfer(uh.devh,
+ LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_STANDARD | LIBUSB_RECIPIENT_DEVICE,
+ LIBUSB_REQUEST_GET_DESCRIPTOR, LIBUSB_DT_STRING << 8,
+ 0, (uint8_t *)languages, sizeof(languages), 0);
+
+ if (r <= 0) {
+ D("check_device(): Failed to get languages count\n");
+ goto fail;
+ }
+
+ languageCount = (r - 2) / 2;
+
+ for (i = 1; i <= languageCount; ++i) {
+ memset(buffer, 0, sizeof(buffer));
+
+ r = libusb_control_transfer(uh.devh,
+ LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_STANDARD | LIBUSB_RECIPIENT_DEVICE,
+ LIBUSB_REQUEST_GET_DESCRIPTOR, (LIBUSB_DT_STRING << 8) | desc.iSerialNumber,
+ languages[i], (uint8_t *)buffer, sizeof(buffer), 0);
+
+ if (r > 0) { /* converting serial */
+ int j = 0;
+ r /= 2;
+
+ for (j = 1; j < r; ++j)
+ serial[j - 1] = buffer[j];
+
+ serial[j - 1] = '\0';
+ break; /* languagesCount cycle */
+ }
+ }
+
+ if (register_device(&uh, serial) == 0) {
+ D("check_device(): Failed to register device\n");
+ goto fail_interface;
+ }
+
+ libusb_ref_device(dev);
+ }
+ }
+
+ return;
+
+fail_interface:
+ libusb_release_interface(uh.devh, uh.interface);
+
+fail:
+ libusb_close(uh.devh);
+ uh.devh = NULL;
+}
+
+int
+check_device_connected(struct usb_handle *uh)
+{
+ int r = libusb_kernel_driver_active(uh->devh, uh->interface);
+
+ if (r == LIBUSB_ERROR_NO_DEVICE)
+ return 0;
+
+ if (r < 0)
+ return -1;
+
+ return 1;
+}
+
+void
+kick_disconnected()
+{
+ struct usb_handle *usb= NULL;
+
+ adb_mutex_lock(&usb_lock);
+
+ for (usb = handle_list.next; usb != &handle_list; usb = usb->next) {
+
+ if (check_device_connected(usb) == 0) {
+ D("kick_disconnected(): Transport %p is not online anymore\n",
+ usb);
+
+ usb_kick(usb);
+ }
+ }
+
+ adb_mutex_unlock(&usb_lock);
+}
+
+void
+scan_usb_devices()
+{
+ D("scan_usb_devices(): started\n");
+
+ libusb_device **devs= NULL;
+ libusb_device *dev= NULL;
+ ssize_t cnt = libusb_get_device_list(ctx, &devs);
+
+ if (cnt < 0) {
+ D("scan_usb_devices(): Failed to get device list (error: %d)\n",
+ cnt);
+
+ return;
+ }
+
+ int i = 0;
+
+ while ((dev = devs[i++]) != NULL) {
+ check_device(dev);
+ }
+
+ libusb_free_device_list(devs, 1);
+}
+
+void *
+device_poll_thread(void* unused)
+{
+ D("device_poll_thread(): Created USB scan thread\n");
+
+ for (;;) {
+ sleep(5);
+ kick_disconnected();
+ scan_usb_devices();
+ }
+
+ /* never reaching this point */
+ return (NULL);
+}
+
+static void
+sigalrm_handler(int signo)
+{
+ /* nothing */
+}
+
+void
+usb_init()
+{
+ D("usb_init(): started\n");
+ adb_thread_t tid;
+ struct sigaction actions;
+
+ int r = libusb_init(&ctx);
+
+ if (r != LIBUSB_SUCCESS) {
+ err(EX_IOERR, "Failed to init libusb\n");
+ }
+
+ memset(&actions, 0, sizeof(actions));
+
+ sigemptyset(&actions.sa_mask);
+
+ actions.sa_flags = 0;
+ actions.sa_handler = sigalrm_handler;
+
+ sigaction(SIGALRM, &actions, NULL);
+
+ /* initial device scan */
+ scan_usb_devices();
+
+ /* starting USB event polling thread */
+ if (adb_thread_create(&tid, device_poll_thread, NULL)) {
+ err(EX_IOERR, "cannot create USB scan thread\n");
+ }
+
+ D("usb_init(): finished\n");
+}
+
diff --git a/adb/usb_vendors.c b/adb/usb_vendors.c
index f8c54d7..5534fd9 100644
--- a/adb/usb_vendors.c
+++ b/adb/usb_vendors.c
@@ -43,6 +43,12 @@
#define VENDOR_ID_SAMSUNG 0x04e8
// Motorola's USB Vendor ID
#define VENDOR_ID_MOTOROLA 0x22b8
+// LG's USB Vendor ID
+#define VENDOR_ID_LGE 0x1004
+// Huawei's USB Vendor ID
+#define VENDOR_ID_HUAWEI 0x12D1
+// Acer's USB Vendor ID
+#define VENDOR_ID_ACER 0x0502
/** built-in vendor list */
int builtInVendorIds[] = {
@@ -50,6 +56,9 @@
VENDOR_ID_HTC,
VENDOR_ID_SAMSUNG,
VENDOR_ID_MOTOROLA,
+ VENDOR_ID_LGE,
+ VENDOR_ID_HUAWEI,
+ VENDOR_ID_ACER,
};
#define BUILT_IN_VENDOR_COUNT (sizeof(builtInVendorIds)/sizeof(builtInVendorIds[0]))
diff --git a/include/arch/linux-sh/AndroidConfig.h b/include/arch/linux-sh/AndroidConfig.h
new file mode 100644
index 0000000..4af39d9
--- /dev/null
+++ b/include/arch/linux-sh/AndroidConfig.h
@@ -0,0 +1,327 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * Android config -- "android-sh". Used for SuperH device builds.
+ */
+#ifndef _ANDROID_CONFIG_H
+#define _ANDROID_CONFIG_H
+
+/*
+ * ===========================================================================
+ * !!! IMPORTANT !!!
+ * ===========================================================================
+ *
+ * This file is included by ALL C/C++ source files. Don't put anything in
+ * here unless you are absolutely certain it can't go anywhere else.
+ *
+ * Any C++ stuff must be wrapped with "#ifdef __cplusplus". Do not use "//"
+ * comments.
+ */
+
+/*
+ * Threading model. Choose one:
+ *
+ * HAVE_PTHREADS - use the pthreads library.
+ * HAVE_WIN32_THREADS - use Win32 thread primitives.
+ * -- combine HAVE_CREATETHREAD, HAVE_CREATEMUTEX, and HAVE__BEGINTHREADEX
+ */
+#define HAVE_PTHREADS
+
+/*
+ * Do we have the futex syscall?
+ */
+
+#define HAVE_FUTEX
+
+/*
+ * Define if we already have the futex wrapper functions defined. Yes if
+ * compiling against bionic.
+ */
+#define HAVE_FUTEX_WRAPPERS 1
+
+/*
+ * Process creation model. Choose one:
+ *
+ * HAVE_FORKEXEC - use fork() and exec()
+ * HAVE_WIN32_PROC - use CreateProcess()
+ */
+#define HAVE_FORKEXEC
+
+/*
+ * Process out-of-memory adjustment. Set if running on Linux,
+ * where we can write to /proc/<pid>/oom_adj to modify the out-of-memory
+ * badness adjustment.
+ */
+#define HAVE_OOM_ADJ
+
+/*
+ * IPC model. Choose one:
+ *
+ * HAVE_SYSV_IPC - use the classic SysV IPC mechanisms (semget, shmget).
+ * HAVE_MACOSX_IPC - use Macintosh IPC mechanisms (sem_open, mmap).
+ * HAVE_WIN32_IPC - use Win32 IPC (CreateSemaphore, CreateFileMapping).
+ * HAVE_ANDROID_IPC - use Android versions (?, mmap).
+ */
+#define HAVE_ANDROID_IPC
+
+/*
+ * Memory-mapping model. Choose one:
+ *
+ * HAVE_POSIX_FILEMAP - use the Posix sys/mmap.h
+ * HAVE_WIN32_FILEMAP - use Win32 filemaps
+ */
+#define HAVE_POSIX_FILEMAP
+
+/*
+ * Define this if you have <termio.h>
+ */
+#define HAVE_TERMIO_H
+
+/*
+ * Define this if you build against MSVCRT.DLL
+ */
+/* #define HAVE_MS_C_RUNTIME */
+
+/*
+ * Define this if you have sys/uio.h
+ */
+#define HAVE_SYS_UIO_H
+
+/*
+ * Define this if your platforms implements symbolic links
+ * in its filesystems
+ */
+#define HAVE_SYMLINKS
+
+/*
+ * Define this if we have localtime_r().
+ */
+/* #define HAVE_LOCALTIME_R */
+
+/*
+ * Define this if we have gethostbyname_r().
+ */
+/* #define HAVE_GETHOSTBYNAME_R */
+
+/*
+ * Define this if we have ioctl().
+ */
+#define HAVE_IOCTL
+
+/*
+ * Define this if we want to use WinSock.
+ */
+/* #define HAVE_WINSOCK */
+
+/*
+ * Define this if have clock_gettime() and friends
+ */
+#define HAVE_POSIX_CLOCKS
+
+/*
+ * Define this if we have pthread_cond_timedwait_monotonic() and
+ * clock_gettime(CLOCK_MONOTONIC).
+ */
+/* #define HAVE_TIMEDWAIT_MONOTONIC */
+
+/*
+ * Define this if we have linux style epoll()
+ */
+#define HAVE_EPOLL
+
+/*
+ * Endianness of the target machine. Choose one:
+ *
+ * HAVE_ENDIAN_H -- have endian.h header we can include.
+ * HAVE_LITTLE_ENDIAN -- we are little endian.
+ * HAVE_BIG_ENDIAN -- we are big endian.
+ */
+#define HAVE_ENDIAN_H
+#define HAVE_LITTLE_ENDIAN
+
+/*
+ * We need to choose between 32-bit and 64-bit off_t. All of our code should
+ * agree on the same size. For desktop systems, use 64-bit values,
+ * because some of our libraries (e.g. wxWidgets) expect to be built that way.
+ */
+/* #define _FILE_OFFSET_BITS 64 */
+/* #define _LARGEFILE_SOURCE 1 */
+
+/*
+ * Defined if we have the backtrace() call for retrieving a stack trace.
+ * Needed for CallStack to operate; if not defined, CallStack is
+ * non-functional.
+ */
+#define HAVE_BACKTRACE 0
+
+/*
+ * Defined if we have the dladdr() call for retrieving the symbol associated
+ * with a memory address. If not defined, stack crawls will not have symbolic
+ * information.
+ */
+#define HAVE_DLADDR 0
+
+/*
+ * Defined if we have the cxxabi.h header for demangling C++ symbols. If
+ * not defined, stack crawls will be displayed with raw mangled symbols
+ */
+#define HAVE_CXXABI 0
+
+/*
+ * Defined if we have the gettid() system call.
+ */
+#define HAVE_GETTID
+
+/*
+ * Defined if we have the sched_setscheduler() call
+ */
+#define HAVE_SCHED_SETSCHEDULER
+
+/*
+ * Add any extra platform-specific defines here.
+ */
+/* #define __linux__ */ /* for SuperH */
+
+/*
+ * Define if we have <malloc.h> header
+ */
+#define HAVE_MALLOC_H
+
+/*
+ * Define if we're running on *our* linux on device or emulator.
+ */
+#define HAVE_ANDROID_OS 1
+
+/*
+ * Define if we have Linux-style non-filesystem Unix Domain Sockets
+ */
+#define HAVE_LINUX_LOCAL_SOCKET_NAMESPACE 1
+
+/*
+ * Define if we have Linux's inotify in <sys/inotify.h>.
+ */
+#define HAVE_INOTIFY 1
+
+/*
+ * Define if we have madvise() in <sys/mman.h>
+ */
+#define HAVE_MADVISE 1
+
+/*
+ * Define if tm struct has tm_gmtoff field
+ */
+#define HAVE_TM_GMTOFF 1
+
+/*
+ * Define if dirent struct has d_type field
+ */
+#define HAVE_DIRENT_D_TYPE 1
+
+/*
+ * Define if libc includes Android system properties implementation.
+ */
+#define HAVE_LIBC_SYSTEM_PROPERTIES 1
+
+/*
+ * Define if system provides a system property server (should be
+ * mutually exclusive with HAVE_LIBC_SYSTEM_PROPERTIES).
+ */
+/* #define HAVE_SYSTEM_PROPERTY_SERVER */
+
+/*
+ * What CPU architecture does this platform use?
+ */
+#define ARCH_SH
+
+/*
+ * Define if the size of enums is as short as possible,
+ */
+/* #define HAVE_SHORT_ENUMS */
+
+/*
+ * sprintf() format string for shared library naming.
+ */
+#define OS_SHARED_LIB_FORMAT_STR "lib%s.so"
+
+/*
+ * Do we have __memcmp16()?
+ *
+ * TODO : Investigate the perfomance impact of __memcmp16()
+ * and implement it.
+ * This influences on dalvikVM's string performance.
+ * See dalvik/vm/InlineNative.c.
+ */
+/* #define HAVE__MEMCMP16 */
+
+/*
+ * type for the third argument to mincore().
+ */
+#define MINCORE_POINTER_TYPE unsigned char *
+
+/*
+ * Do we have the sigaction flag SA_NOCLDWAIT?
+ */
+#define HAVE_SA_NOCLDWAIT
+
+/*
+ * The default path separator for the platform
+ */
+#define OS_PATH_SEPARATOR '/'
+
+/*
+ * Is the filesystem case sensitive?
+ */
+#define OS_CASE_SENSITIVE
+
+/*
+ * Define if <sys/socket.h> exists.
+ */
+#define HAVE_SYS_SOCKET_H 1
+
+/*
+ * Define if the strlcpy() function exists on the system.
+ */
+#define HAVE_STRLCPY 1
+
+/*
+ * Define if prctl() exists
+ */
+#define HAVE_PRCTL 1
+
+/*
+ * Define if writev() exists
+ */
+#define HAVE_WRITEV 1
+
+/*
+ * For dalvik/libcore
+ */
+#define CANT_PASS_VALIST_AS_CHARPTR
+
+/*
+ * For external/bluez/utils/tools/hciattach.c
+ * TODO : This definition should be somewhere in bionic/libc/kernel/(*).
+ * Cosider the place and move it there.
+ */
+#define N_TTY 0
+
+/*
+ * Whether or not _Unwind_Context is defined as a struct.
+ */
+#define HAVE_UNWIND_CONTEXT_STRUCT
+
+#endif /* _ANDROID_CONFIG_H */
diff --git a/include/sysutils/NetlinkListener.h b/include/sysutils/NetlinkListener.h
index 6dcc005..2880046 100644
--- a/include/sysutils/NetlinkListener.h
+++ b/include/sysutils/NetlinkListener.h
@@ -26,7 +26,9 @@
public:
NetlinkListener(int socket);
virtual ~NetlinkListener() {}
+
protected:
virtual bool onDataAvailable(SocketClient *cli);
+ virtual void onEvent(NetlinkEvent *evt) = 0;
};
#endif
diff --git a/init/devices.c b/init/devices.c
index 606a074..c5f681f 100644
--- a/init/devices.c
+++ b/init/devices.c
@@ -114,6 +114,7 @@
{ "/dev/pmem_camera", 0660, AID_SYSTEM, AID_CAMERA, 1 },
{ "/dev/oncrpc/", 0660, AID_ROOT, AID_SYSTEM, 1 },
{ "/dev/adsp/", 0660, AID_SYSTEM, AID_AUDIO, 1 },
+ { "/dev/snd/", 0660, AID_SYSTEM, AID_AUDIO, 1 },
{ "/dev/mt9t013", 0660, AID_SYSTEM, AID_SYSTEM, 0 },
{ "/dev/msm_camera/", 0660, AID_SYSTEM, AID_SYSTEM, 1 },
{ "/dev/akm8976_daemon",0640, AID_COMPASS, AID_SYSTEM, 0 },
diff --git a/libcutils/Android.mk b/libcutils/Android.mk
index 98e59ee..30f4a49 100644
--- a/libcutils/Android.mk
+++ b/libcutils/Android.mk
@@ -98,7 +98,11 @@
ifeq ($(TARGET_ARCH),arm)
LOCAL_SRC_FILES += memset32.S atomic-android-arm.S
else # !arm
+ifeq ($(TARGET_ARCH),sh)
+LOCAL_SRC_FILES += memory.c atomic-android-sh.c
+else # !sh
LOCAL_SRC_FILES += memory.c
+endif # !sh
endif # !arm
LOCAL_C_INCLUDES := $(KERNEL_HEADERS)
diff --git a/libcutils/atomic-android-arm.S b/libcutils/atomic-android-arm.S
index c56ec5d..9a24976 100644
--- a/libcutils/atomic-android-arm.S
+++ b/libcutils/atomic-android-arm.S
@@ -17,8 +17,7 @@
#include <machine/cpu-features.h>
/*
- * NOTE: these atomic operations are SMP safe on all architectures,
- * except swap(), see below.
+ * NOTE: these atomic operations are SMP safe on all architectures.
*/
.text
@@ -228,11 +227,18 @@
* output: r0 = old value
*/
-/* FIXME: this is not safe on SMP systems
- * a general way to do it is to use kernel_cmpxchg */
-
+/* replaced swp instruction with ldrex/strex for ARMv6 & ARMv7 */
android_atomic_swap:
+#if defined (_ARM_HAVE_LDREX_STREX)
+1: ldrex r2, [r1]
+ strex r3, r0, [r1]
+ teq r3, #0
+ bne 1b
+ mov r0, r2
+ mcr p15, 0, r0, c7, c10, 5 /* or, use dmb */
+#else
swp r0, r0, [r1]
+#endif
bx lr
/*
diff --git a/libcutils/atomic-android-sh.c b/libcutils/atomic-android-sh.c
new file mode 100644
index 0000000..acbea97
--- /dev/null
+++ b/libcutils/atomic-android-sh.c
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <cutils/atomic.h>
+#ifdef HAVE_WIN32_THREADS
+#include <windows.h>
+#else
+#include <sched.h>
+#endif
+
+/*
+ * Note :
+ *
+ * (1) SuperH does not have CMPXCHG. It has only TAS for atomic
+ * operations. It does not seem a good idea to implement CMPXCHG,
+ * with TAS. So, we choose to implemnt these operations with
+ * posix mutexes. Please be sure that this might cause performance
+ * problem for Android-SH. Using LL/SC instructions supported in SH-X3,
+ * best performnace would be realized.
+ *
+ * (2) Mutex initialization problem happens, which is commented for
+ * ARM implementation, in this file above.
+ * We follow the fact that the initializer for mutex is a simple zero
+ * value.
+ */
+
+#include <pthread.h>
+
+#define SWAP_LOCK_COUNT 32U
+static pthread_mutex_t _swap_locks[SWAP_LOCK_COUNT];
+
+#define SWAP_LOCK(addr) \
+ &_swap_locks[((unsigned)(void*)(addr) >> 3U) % SWAP_LOCK_COUNT]
+
+
+void android_atomic_write(int32_t value, volatile int32_t* addr) {
+ int32_t oldValue;
+ do {
+ oldValue = *addr;
+ } while (android_atomic_cmpxchg(oldValue, value, addr));
+}
+
+int32_t android_atomic_inc(volatile int32_t* addr) {
+ int32_t oldValue;
+ do {
+ oldValue = *addr;
+ } while (android_atomic_cmpxchg(oldValue, oldValue+1, addr));
+ return oldValue;
+}
+
+int32_t android_atomic_dec(volatile int32_t* addr) {
+ int32_t oldValue;
+ do {
+ oldValue = *addr;
+ } while (android_atomic_cmpxchg(oldValue, oldValue-1, addr));
+ return oldValue;
+}
+
+int32_t android_atomic_add(int32_t value, volatile int32_t* addr) {
+ int32_t oldValue;
+ do {
+ oldValue = *addr;
+ } while (android_atomic_cmpxchg(oldValue, oldValue+value, addr));
+ return oldValue;
+}
+
+int32_t android_atomic_and(int32_t value, volatile int32_t* addr) {
+ int32_t oldValue;
+ do {
+ oldValue = *addr;
+ } while (android_atomic_cmpxchg(oldValue, oldValue&value, addr));
+ return oldValue;
+}
+
+int32_t android_atomic_or(int32_t value, volatile int32_t* addr) {
+ int32_t oldValue;
+ do {
+ oldValue = *addr;
+ } while (android_atomic_cmpxchg(oldValue, oldValue|value, addr));
+ return oldValue;
+}
+
+int32_t android_atomic_swap(int32_t value, volatile int32_t* addr) {
+ int32_t oldValue;
+ do {
+ oldValue = *addr;
+ } while (android_atomic_cmpxchg(oldValue, value, addr));
+ return oldValue;
+}
+
+int android_atomic_cmpxchg(int32_t oldvalue, int32_t newvalue,
+ volatile int32_t* addr) {
+ int result;
+ pthread_mutex_t* lock = SWAP_LOCK(addr);
+
+ pthread_mutex_lock(lock);
+
+ if (*addr == oldvalue) {
+ *addr = newvalue;
+ result = 0;
+ } else {
+ result = 1;
+ }
+ pthread_mutex_unlock(lock);
+ return result;
+}
+
+int64_t android_quasiatomic_swap_64(int64_t value, volatile int64_t* addr) {
+ int64_t oldValue;
+ pthread_mutex_t* lock = SWAP_LOCK(addr);
+
+ pthread_mutex_lock(lock);
+
+ oldValue = *addr;
+ *addr = value;
+
+ pthread_mutex_unlock(lock);
+ return oldValue;
+}
+
+int android_quasiatomic_cmpxchg_64(int64_t oldvalue, int64_t newvalue,
+ volatile int64_t* addr) {
+ int result;
+ pthread_mutex_t* lock = SWAP_LOCK(addr);
+
+ pthread_mutex_lock(lock);
+
+ if (*addr == oldvalue) {
+ *addr = newvalue;
+ result = 0;
+ } else {
+ result = 1;
+ }
+ pthread_mutex_unlock(lock);
+ return result;
+}
+
+int64_t android_quasiatomic_read_64(volatile int64_t* addr) {
+ int64_t result;
+ pthread_mutex_t* lock = SWAP_LOCK(addr);
+
+ pthread_mutex_lock(lock);
+ result = *addr;
+ pthread_mutex_unlock(lock);
+ return result;
+}
diff --git a/libcutils/atomic.c b/libcutils/atomic.c
index 65d7af0..41faaa2 100644
--- a/libcutils/atomic.c
+++ b/libcutils/atomic.c
@@ -245,6 +245,10 @@
return result;
}
+/*****************************************************************************/
+#elif __sh__
+// implementation for SuperH is in atomic-android-sh.c.
+
#else
#error "Unsupported atomic operations for this platform"
diff --git a/libsysutils/src/NetlinkEvent.cpp b/libsysutils/src/NetlinkEvent.cpp
index 5573c3f..5f959a7 100644
--- a/libsysutils/src/NetlinkEvent.cpp
+++ b/libsysutils/src/NetlinkEvent.cpp
@@ -28,6 +28,9 @@
NetlinkEvent::NetlinkEvent() {
mAction = NlActionUnknown;
+ memset(mParams, 0, sizeof(mParams));
+ mPath = NULL;
+ mSubsystem = NULL;
}
NetlinkEvent::~NetlinkEvent() {
diff --git a/libsysutils/src/NetlinkListener.cpp b/libsysutils/src/NetlinkListener.cpp
index 3ec9d9d..5586dcc 100644
--- a/libsysutils/src/NetlinkListener.cpp
+++ b/libsysutils/src/NetlinkListener.cpp
@@ -32,8 +32,6 @@
bool NetlinkListener::onDataAvailable(SocketClient *cli)
{
int socket = cli->getSocket();
- LOGD("NetlinkListener::onDataAvailable()");
-
int count;
if ((count = recv(socket, mBuffer, sizeof(mBuffer), 0)) < 0) {
@@ -47,8 +45,7 @@
goto out;
}
- LOGD("Ignoring '%s' netlink event", evt->getSubsystem());
-
+ onEvent(evt);
out:
delete evt;
return true;
diff --git a/logcat/Android.mk b/logcat/Android.mk
index f9fd2c9..5a9f12d 100644
--- a/logcat/Android.mk
+++ b/logcat/Android.mk
@@ -21,5 +21,6 @@
LOCAL_MODULE_CLASS := ETC
LOCAL_SRC_FILES := $(LOCAL_MODULE)
+LOCAL_PREBUILT_STRIP_COMMENTS := 1
include $(BUILD_PREBUILT)
diff --git a/rootdir/init.rc b/rootdir/init.rc
index aa0ef59..9d30518 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -51,7 +51,8 @@
mkdir /dev/cpuctl/bg_non_interactive
chown system system /dev/cpuctl/bg_non_interactive/tasks
chmod 0777 /dev/cpuctl/bg_non_interactive/tasks
- write /dev/cpuctl/bg_non_interactive/cpu.shares 16
+ # 5.0 %
+ write /dev/cpuctl/bg_non_interactive/cpu.shares 52
# mount mtd partitions
# Mount /system rw first to give the filesystem a chance to save a checkpoint