Merge change 1950 into donut
* changes:
new cdma event log tags
diff --git a/adb/fdevent.c b/adb/fdevent.c
index 5d6fb96..c179b20 100644
--- a/adb/fdevent.c
+++ b/adb/fdevent.c
@@ -87,7 +87,7 @@
{
/* XXX: what's a good size for the passed in hint? */
epoll_fd = epoll_create(256);
-
+
if(epoll_fd < 0) {
perror("epoll_create() failed");
exit(1);
@@ -105,7 +105,7 @@
ev.events = 0;
ev.data.ptr = fde;
-#if 0
+#if 0
if(epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fde->fd, &ev)) {
perror("epoll_ctl() failed\n");
exit(1);
@@ -116,7 +116,7 @@
static void fdevent_disconnect(fdevent *fde)
{
struct epoll_event ev;
-
+
memset(&ev, 0, sizeof(ev));
ev.events = 0;
ev.data.ptr = fde;
@@ -133,9 +133,9 @@
{
struct epoll_event ev;
int active;
-
+
active = (fde->state & FDE_EVENTMASK) != 0;
-
+
memset(&ev, 0, sizeof(ev));
ev.events = 0;
ev.data.ptr = fde;
@@ -241,7 +241,7 @@
static void fdevent_disconnect(fdevent *fde)
{
int i, n;
-
+
FD_CLR(fde->fd, &read_fds);
FD_CLR(fde->fd, &write_fds);
FD_CLR(fde->fd, &error_fds);
@@ -283,9 +283,9 @@
memcpy(&rfd, &read_fds, sizeof(fd_set));
memcpy(&wfd, &write_fds, sizeof(fd_set));
memcpy(&efd, &error_fds, sizeof(fd_set));
-
+
n = select(select_n, &rfd, &wfd, &efd, 0);
-
+
if(n < 0) {
if(errno == EINTR) return;
perror("select");
@@ -300,12 +300,12 @@
if(events) {
n--;
-
+
fde = fd_table[i];
if(fde == 0) FATAL("missing fde for fd %d\n", i);
fde->events |= events;
-
+
if(fde->state & FDE_PENDING) continue;
fde->state |= FDE_PENDING;
fdevent_plist_enqueue(fde);
@@ -320,7 +320,7 @@
if(fde->fd < 0) {
FATAL("bogus negative fd (%d)\n", fde->fd);
}
-
+
if(fde->fd >= fd_table_max) {
int oldmax = fd_table_max;
if(fde->fd > 32000) {
@@ -383,9 +383,9 @@
{
fdevent *list = &list_pending;
fdevent *node = list->next;
-
+
if(node == list) return 0;
-
+
list->next = node->next;
list->next->prev = list;
node->next = 0;
@@ -449,9 +449,9 @@
void fdevent_set(fdevent *fde, unsigned events)
{
events &= FDE_EVENTMASK;
-
+
if((fde->state & FDE_EVENTMASK) == events) return;
-
+
if(fde->state & FDE_ACTIVE) {
fdevent_update(fde, events);
dump_fde(fde, "update");
@@ -487,13 +487,13 @@
void fdevent_loop()
{
fdevent *fde;
-
+
for(;;) {
#if DEBUG
fprintf(stderr,"--- ---- waiting for events\n");
#endif
fdevent_process();
-
+
while((fde = fdevent_plist_dequeue())) {
unsigned events = fde->events;
fde->events = 0;
diff --git a/adb/fdevent.h b/adb/fdevent.h
index 7a442d4..6b7e7ec 100644
--- a/adb/fdevent.h
+++ b/adb/fdevent.h
@@ -17,10 +17,13 @@
#ifndef __FDEVENT_H
#define __FDEVENT_H
+#include <stdint.h> /* for int64_t */
+
/* events that may be observed */
#define FDE_READ 0x0001
#define FDE_WRITE 0x0002
#define FDE_ERROR 0x0004
+#define FDE_TIMEOUT 0x0008
/* features that may be set (via the events set/add/del interface) */
#define FDE_DONT_CLOSE 0x0080
@@ -30,6 +33,8 @@
typedef void (*fd_func)(int fd, unsigned events, void *userdata);
/* Allocate and initialize a new fdevent object
+ * Note: use FD_TIMER as 'fd' to create a fd-less object
+ * (used to implement timers).
*/
fdevent *fdevent_create(int fd, fd_func func, void *arg);
@@ -53,6 +58,8 @@
void fdevent_add(fdevent *fde, unsigned events);
void fdevent_del(fdevent *fde, unsigned events);
+void fdevent_set_timeout(fdevent *fde, int64_t timeout_ms);
+
/* loop forever, handling events.
*/
void fdevent_loop();
@@ -65,7 +72,7 @@
int fd;
unsigned short state;
unsigned short events;
-
+
fd_func func;
void *arg;
};
diff --git a/adb/file_sync_client.c b/adb/file_sync_client.c
index 4e6d385..0ebfe73 100644
--- a/adb/file_sync_client.c
+++ b/adb/file_sync_client.c
@@ -165,7 +165,7 @@
}
static int sync_finish_readtime(int fd, unsigned int *timestamp,
- unsigned int *mode, unsigned int *size)
+ unsigned int *mode, unsigned int *size)
{
syncmsg msg;
@@ -908,12 +908,12 @@
unsigned int timestamp, mode, size;
if (sync_finish_readtime(fd, ×tamp, &mode, &size))
return 1;
- if (size == ci->size) {
+ if (size == ci->size) {
/* for links, we cannot update the atime/mtime */
if ((S_ISREG(ci->mode & mode) && timestamp == ci->time) ||
- (S_ISLNK(ci->mode & mode) && timestamp >= ci->time))
+ (S_ISLNK(ci->mode & mode) && timestamp >= ci->time))
ci->flag = 1;
- }
+ }
}
}
#endif
diff --git a/adb/protocol.txt b/adb/protocol.txt
index d0f307c..398d042 100644
--- a/adb/protocol.txt
+++ b/adb/protocol.txt
@@ -23,7 +23,7 @@
--- protocol overview and basics ---------------------------------------
-
+
The transport layer deals in "messages", which consist of a 24 byte
header followed (optionally) by a payload. The header consists of 6
32 bit words which are sent across the wire in little endian format.
@@ -52,7 +52,7 @@
reversed.
-
+
--- CONNECT(version, maxdata, "system-identity-string") ----------------
The CONNECT message establishes the presence of a remote system.
@@ -114,7 +114,7 @@
not change on later READY messages sent to the same stream.
-
+
--- WRITE(0, remote-id, "data") ----------------------------------------
The WRITE message sends data to the recipient's stream identified by
@@ -172,7 +172,7 @@
#define A_WRTE 0x45545257
-
+
--- implementation details ---------------------------------------------
The core of the bridge program will use three threads. One thread
diff --git a/adb/sysdeps.h b/adb/sysdeps.h
index 3c74e0f..389fbd2 100644
--- a/adb/sysdeps.h
+++ b/adb/sysdeps.h
@@ -67,16 +67,16 @@
static __inline__ int adb_thread_create( adb_thread_t *thread, adb_thread_func_t func, void* arg)
{
- thread->tid = _beginthread( (win_thread_func_t)func, 0, arg );
- if (thread->tid == (unsigned)-1L) {
- return -1;
- }
- return 0;
+ thread->tid = _beginthread( (win_thread_func_t)func, 0, arg );
+ if (thread->tid == (unsigned)-1L) {
+ return -1;
+ }
+ return 0;
}
static __inline__ void close_on_exec(int fd)
{
- /* nothing really */
+ /* nothing really */
}
extern void disable_tcp_nagle(int fd);
@@ -138,7 +138,7 @@
static __inline__ int adb_open_mode(const char* path, int options, int mode)
{
- return adb_open(path, options);
+ return adb_open(path, options);
}
static __inline__ int unix_open(const char* path, int options,...)
@@ -203,7 +203,7 @@
static __inline__ void adb_sleep_ms( int mseconds )
{
- Sleep( mseconds );
+ Sleep( mseconds );
}
extern int adb_socket_accept(int serverfd, struct sockaddr* addr, socklen_t *addrlen);
@@ -290,7 +290,7 @@
static __inline__ void close_on_exec(int fd)
{
- fcntl( fd, F_SETFD, FD_CLOEXEC );
+ fcntl( fd, F_SETFD, FD_CLOEXEC );
}
static __inline__ int unix_open(const char* path, int options,...)
@@ -312,7 +312,7 @@
static __inline__ int adb_open_mode( const char* pathname, int options, int mode )
{
- return open( pathname, options, mode );
+ return open( pathname, options, mode );
}
@@ -368,11 +368,11 @@
{
int fd = creat(path, mode);
- if ( fd < 0 )
- return -1;
+ if ( fd < 0 )
+ return -1;
close_on_exec(fd);
- return fd;
+ return fd;
}
#undef creat
#define creat ___xxx_creat
@@ -439,12 +439,12 @@
static __inline__ void adb_sleep_ms( int mseconds )
{
- usleep( mseconds*1000 );
+ usleep( mseconds*1000 );
}
static __inline__ int adb_mkdir(const char* path, int mode)
{
- return mkdir(path, mode);
+ return mkdir(path, mode);
}
#undef mkdir
#define mkdir ___xxx_mkdir
diff --git a/adb/sysdeps_win32.c b/adb/sysdeps_win32.c
index c2a9a98..a8e3bb9 100644
--- a/adb/sysdeps_win32.c
+++ b/adb/sysdeps_win32.c
@@ -739,12 +739,12 @@
{
FH serverfh = _fh_from_int(serverfd);
FH fh;
-
+
if ( !serverfh || serverfh->clazz != &_fh_socket_class ) {
D( "adb_socket_accept: invalid fd %d\n", serverfd );
return -1;
}
-
+
fh = _fh_alloc( &_fh_socket_class );
if (!fh) {
D( "adb_socket_accept: not enough memory to allocate accepted socket descriptor\n" );
@@ -757,7 +757,7 @@
D( "adb_socket_accept: accept on fd %d return error %ld\n", serverfd, GetLastError() );
return -1;
}
-
+
snprintf( fh->name, sizeof(fh->name), "%d(accept:%s)", _fh_to_int(fh), serverfh->name );
D( "adb_socket_accept on fd %d returns fd %d\n", serverfd, _fh_to_int(fh) );
return _fh_to_int(fh);
@@ -768,7 +768,7 @@
{
FH fh = _fh_from_int(fd);
int on;
-
+
if ( !fh || fh->clazz != &_fh_socket_class )
return;
@@ -1746,7 +1746,7 @@
/** FILE EVENT HOOKS
**/
-
+
static void _event_file_prepare( EventHook hook )
{
if (hook->wanted & (FDE_READ|FDE_WRITE)) {
diff --git a/adb/usb_windows.c b/adb/usb_windows.c
index 7ddaa0c..0951f67 100644
--- a/adb/usb_windows.c
+++ b/adb/usb_windows.c
@@ -446,7 +446,7 @@
}
void find_devices() {
- usb_handle* handle = NULL;
+ usb_handle* handle = NULL;
char entry_buffer[2048];
char interf_name[2048];
AdbInterfaceInfo* next_interface = (AdbInterfaceInfo*)(&entry_buffer[0]);
diff --git a/init/builtins.c b/init/builtins.c
index 95fb223..17df0af 100644
--- a/init/builtins.c
+++ b/init/builtins.c
@@ -126,7 +126,7 @@
static void service_start_if_not_disabled(struct service *svc)
{
if (!(svc->flags & SVC_DISABLED)) {
- service_start(svc);
+ service_start(svc, NULL);
}
}
@@ -316,7 +316,7 @@
struct service *svc;
svc = service_find_by_name(args[1]);
if (svc) {
- service_start(svc);
+ service_start(svc, NULL);
}
return 0;
}
@@ -337,7 +337,7 @@
svc = service_find_by_name(args[1]);
if (svc) {
service_stop(svc);
- service_start(svc);
+ service_start(svc, NULL);
}
return 0;
}
diff --git a/init/init.c b/init/init.c
index a748ec3..b350569 100644
--- a/init/init.c
+++ b/init/init.c
@@ -156,7 +156,7 @@
fcntl(fd, F_SETFD, 0);
}
-void service_start(struct service *svc)
+void service_start(struct service *svc, const char *dynamic_args)
{
struct stat s;
pid_t pid;
@@ -192,6 +192,12 @@
return;
}
+ if ((!(svc->flags & SVC_ONESHOT)) && dynamic_args) {
+ ERROR("service '%s' must be one-shot to use dynamic args, disabling\n", svc->args[0]);
+ svc->flags |= SVC_DISABLED;
+ return;
+ }
+
NOTICE("starting '%s'\n", svc->name);
pid = fork();
@@ -248,7 +254,50 @@
setuid(svc->uid);
}
- execve(svc->args[0], (char**) svc->args, (char**) ENV);
+ if (!dynamic_args)
+ execve(svc->args[0], (char**) svc->args, (char**) ENV);
+ else {
+ char *arg_ptrs[SVC_MAXARGS+1];
+ int arg_idx;
+ char *tmp = strdup(dynamic_args);
+ char *p = tmp;
+
+ /* Copy the static arguments */
+ for (arg_idx = 0; arg_idx < svc->nargs; arg_idx++) {
+ arg_ptrs[arg_idx] = svc->args[arg_idx];
+ }
+
+ int done = 0;
+ while(!done) {
+
+ if (arg_idx == SVC_MAXARGS)
+ break;
+
+ /* Advance over any leading whitespace */
+ if (*p == ' ') {
+ for (p; *p != ' '; p++);
+ p++;
+ }
+ /* Locate next argument */
+ char *q = p;
+ while(1) {
+ if (*q == ' ') {
+ *q = '\0';
+ break;
+ } else if (*q == '\0') {
+ done = 1;
+ break;
+ }
+ q++;
+ }
+ arg_ptrs[arg_idx++] = p;
+
+ q++; // Advance q to the next string
+ p = q;
+ }
+ arg_ptrs[arg_idx] = '\0';
+ execve(svc->args[0], (char**) arg_ptrs, (char**) ENV);
+ }
_exit(127);
}
@@ -379,7 +428,7 @@
if (next_start_time <= gettime()) {
svc->flags &= (~SVC_RESTARTING);
- service_start(svc);
+ service_start(svc, NULL);
return;
}
@@ -405,13 +454,29 @@
static void msg_start(const char *name)
{
- struct service *svc = service_find_by_name(name);
+ struct service *svc;
+ char *tmp = NULL;
+ char *args = NULL;
+
+ if (!strchr(name, ':'))
+ svc = service_find_by_name(name);
+ else {
+ tmp = strdup(name);
+ strcpy(tmp, name);
+ args = strchr(tmp, ':');
+ *args = '\0';
+ args++;
+
+ svc = service_find_by_name(tmp);
+ }
if (svc) {
- service_start(svc);
+ service_start(svc, args);
} else {
ERROR("no such service '%s'\n", name);
}
+ if (tmp)
+ free(tmp);
}
static void msg_stop(const char *name)
@@ -737,7 +802,7 @@
svc = service_find_by_keychord(id);
if (svc) {
INFO("starting service %s from keychord\n", svc->name);
- service_start(svc);
+ service_start(svc, NULL);
} else {
ERROR("service for keychord %d not found\n", id);
}
diff --git a/init/init.h b/init/init.h
index b93eb50..f306b7b 100644
--- a/init/init.h
+++ b/init/init.h
@@ -116,6 +116,8 @@
#define NR_SVC_SUPP_GIDS 6 /* six supplementary groups */
+#define SVC_MAXARGS 64
+
struct service {
/* list of all services */
struct listnode slist;
@@ -160,7 +162,7 @@
void service_for_each_flags(unsigned matchflags,
void (*func)(struct service *svc));
void service_stop(struct service *svc);
-void service_start(struct service *svc);
+void service_start(struct service *svc, const char *dynamic_args);
void property_changed(const char *name, const char *value);
struct action *action_remove_queue_head(void);
diff --git a/init/parser.c b/init/parser.c
index 30fa3de..33c1a68 100644
--- a/init/parser.c
+++ b/init/parser.c
@@ -60,8 +60,6 @@
#endif
}
-#define MAXARGS 64
-
#define T_EOF 0
#define T_TEXT 1
#define T_NEWLINE 2
@@ -357,7 +355,7 @@
static void parse_config(const char *fn, char *s)
{
struct parse_state state;
- char *args[MAXARGS];
+ char *args[SVC_MAXARGS];
int nargs;
nargs = 0;
@@ -384,7 +382,7 @@
}
break;
case T_TEXT:
- if (nargs < MAXARGS) {
+ if (nargs < SVC_MAXARGS) {
args[nargs++] = state.text;
}
break;