Merge "adb: improve debug traces readability."
diff --git a/adb/usb_linux.c b/adb/usb_linux.c
index 2f7f870..cd61083 100644
--- a/adb/usb_linux.c
+++ b/adb/usb_linux.c
@@ -149,7 +149,7 @@
// DBGX("[ scanning %s ]\n", busname);
while((de = readdir(devdir))) {
- unsigned char devdesc[256];
+ unsigned char devdesc[4096];
unsigned char* bufptr = devdesc;
unsigned char* bufend;
struct usb_device_descriptor* device;
diff --git a/include/usbhost/usbhost.h b/include/usbhost/usbhost.h
index 4a8a4fc..7ef7ace 100644
--- a/include/usbhost/usbhost.h
+++ b/include/usbhost/usbhost.h
@@ -39,6 +39,17 @@
unsigned char* curr_desc;
};
+struct usb_request
+{
+ struct usb_device *dev;
+ void* buffer;
+ int buffer_length;
+ int actual_length;
+ int max_packet_size;
+ void *private_data; /* struct usbdevfs_urb* */
+ void *client_data; /* free for use by client */
+};
+
/* Callback for notification when new USB devices are attached.
* Return true to exit from usb_host_run.
*/
@@ -81,14 +92,10 @@
/* Releases all resources associated with the USB device */
void usb_device_close(struct usb_device *device);
-/* Creates a usb_device object for already open USB device.
- * This is intended to facilitate sharing USB devices across address spaces.
- */
+/* Creates a usb_device object for already open USB device */
struct usb_device *usb_device_new(const char *dev_name, int fd);
-/* Returns the file descriptor for the usb_device. Used in conjunction with
- * usb_device_new() for sharing USB devices across address spaces.
- */
+/* Returns the file descriptor for the usb_device */
int usb_device_get_fd(struct usb_device *device);
/* Returns the name for the USB device, which is the same as
@@ -170,38 +177,23 @@
/* Releases the specified interface of a USB device */
int usb_device_release_interface(struct usb_device *device, unsigned int interface);
+/* Creates a new usb_request. */
+struct usb_request *usb_request_new(struct usb_device *dev,
+ const struct usb_endpoint_descriptor *ep_desc);
-/* Creates a new usb_endpoint for the specified endpoint of a USB device.
- * This can be used to read or write data across the endpoint.
- */
-struct usb_endpoint *usb_endpoint_open(struct usb_device *dev,
- const struct usb_endpoint_descriptor *desc);
+/* Releases all resources associated with the request */
+void usb_request_free(struct usb_request *req);
-/* Releases all resources associated with the endpoint */
-void usb_endpoint_close(struct usb_endpoint *ep);
+/* Submits a read or write request on the specified device */
+int usb_request_queue(struct usb_request *req);
-/* Begins a read or write operation on the specified endpoint */
-int usb_endpoint_queue(struct usb_endpoint *ep, void *data, int len);
-
- /* Waits for the results of a previous usb_endpoint_queue operation on the
- * specified endpoint. Returns number of bytes transferred, or a negative
- * value for error.
+ /* Waits for the results of a previous usb_request_queue operation.
+ * Returns a usb_request, or NULL for error.
*/
-int usb_endpoint_wait(struct usb_device *device, int *out_ep_num);
+struct usb_request *usb_request_wait(struct usb_device *dev);
-/* Cancels a pending usb_endpoint_queue() operation on an endpoint. */
-int usb_endpoint_cancel(struct usb_endpoint *ep);
-
-/* Returns the usb_device for the given endpoint */
-struct usb_device *usb_endpoint_get_device(struct usb_endpoint *ep);
-
-/* Returns the endpoint address for the given endpoint */
-int usb_endpoint_number(struct usb_endpoint *ep);
-
-/* Returns the maximum packet size for the given endpoint.
- * For bulk endpoints this should be 512 for highspeed or 64 for fullspeed.
- */
-int usb_endpoint_max_packet(struct usb_endpoint *ep);
+/* Cancels a pending usb_request_queue() operation. */
+int usb_request_cancel(struct usb_request *req);
#ifdef __cplusplus
}
diff --git a/libusbhost/Android.mk b/libusbhost/Android.mk
index c9a1c8a..52b4ead 100644
--- a/libusbhost/Android.mk
+++ b/libusbhost/Android.mk
@@ -40,4 +40,7 @@
LOCAL_CFLAGS := -g -DUSE_LIBLOG
+# needed for logcat
+LOCAL_SHARED_LIBRARIES := libcutils
+
include $(BUILD_SHARED_LIBRARY)
diff --git a/libusbhost/usbhost.c b/libusbhost/usbhost.c
index dbc7962..d6736d3 100644
--- a/libusbhost/usbhost.c
+++ b/libusbhost/usbhost.c
@@ -45,12 +45,6 @@
#include <pthread.h>
#include <linux/usbdevice_fs.h>
-#include <linux/version.h>
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 20)
-#include <linux/usb/ch9.h>
-#else
-#include <linux/usb_ch9.h>
-#endif
#include <asm/byteorder.h>
#include "usbhost/usbhost.h"
@@ -72,13 +66,6 @@
int writeable;
};
-struct usb_endpoint
-{
- struct usb_device *dev;
- struct usb_endpoint_descriptor desc;
- struct usbdevfs_urb urb;
-};
-
static inline int badname(const char *name)
{
while(*name) {
@@ -465,83 +452,89 @@
return ioctl(device->fd, USBDEVFS_RELEASEINTERFACE, &interface);
}
-struct usb_endpoint *usb_endpoint_open(struct usb_device *dev,
- const struct usb_endpoint_descriptor *desc)
+struct usb_request *usb_request_new(struct usb_device *dev,
+ const struct usb_endpoint_descriptor *ep_desc)
{
- struct usb_endpoint *ep = calloc(1, sizeof(struct usb_endpoint));
- memcpy(&ep->desc, desc, sizeof(ep->desc));
- ep->dev = dev;
- return ep;
+ struct usbdevfs_urb *urb = calloc(1, sizeof(struct usbdevfs_urb));
+ if (!urb)
+ return NULL;
+
+ if ((ep_desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK)
+ urb->type = USBDEVFS_URB_TYPE_BULK;
+ else if ((ep_desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT)
+ urb->type = USBDEVFS_URB_TYPE_INTERRUPT;
+ else {
+ D("Unsupported endpoint type %d", ep_desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK);
+ free(urb);
+ return NULL;
+ }
+ urb->endpoint = ep_desc->bEndpointAddress;
+
+ struct usb_request *req = calloc(1, sizeof(struct usb_request));
+ if (!req) {
+ free(urb);
+ return NULL;
+ }
+
+ req->dev = dev;
+ req->max_packet_size = __le16_to_cpu(ep_desc->wMaxPacketSize);
+ req->private_data = urb;
+ urb->usercontext = req;
+
+ return req;
}
-void usb_endpoint_close(struct usb_endpoint *ep)
+void usb_request_free(struct usb_request *req)
{
- // cancel IO here?
- free(ep);
+ free(req->private_data);
+ free(req);
}
-int usb_endpoint_queue(struct usb_endpoint *ep, void *data, int len)
+int usb_request_queue(struct usb_request *req)
{
- struct usbdevfs_urb *urb = &ep->urb;
+ struct usbdevfs_urb *urb = (struct usbdevfs_urb*)req->private_data;
int res;
- D("usb_endpoint_queue\n");
- memset(urb, 0, sizeof(*urb));
- urb->type = USBDEVFS_URB_TYPE_BULK;
- urb->endpoint = ep->desc.bEndpointAddress;
urb->status = -1;
- urb->buffer = data;
- urb->buffer_length = len;
+ urb->buffer = req->buffer;
+ urb->buffer_length = req->buffer_length;
do {
- res = ioctl(ep->dev->fd, USBDEVFS_SUBMITURB, urb);
+ res = ioctl(req->dev->fd, USBDEVFS_SUBMITURB, urb);
} while((res < 0) && (errno == EINTR));
return res;
}
-int usb_endpoint_wait(struct usb_device *dev, int *out_ep_num)
+struct usb_request *usb_request_wait(struct usb_device *dev)
{
- struct usbdevfs_urb *out = NULL;
+ struct usbdevfs_urb *urb = NULL;
+ struct usb_request *req = NULL;
int res;
while (1) {
- res = ioctl(dev->fd, USBDEVFS_REAPURB, &out);
+ int res = ioctl(dev->fd, USBDEVFS_REAPURB, &urb);
D("USBDEVFS_REAPURB returned %d\n", res);
if (res < 0) {
if(errno == EINTR) {
continue;
}
D("[ reap urb - error ]\n");
- *out_ep_num = -1;
+ return NULL;
} else {
D("[ urb @%p status = %d, actual = %d ]\n",
- out, out->status, out->actual_length);
- res = out->actual_length;
- *out_ep_num = out->endpoint;
+ urb, urb->status, urb->actual_length);
+ req = (struct usb_request*)urb->usercontext;
+ req->actual_length = urb->actual_length;
}
break;
}
- return res;
+ return req;
}
-int usb_endpoint_cancel(struct usb_endpoint *ep)
+int usb_request_cancel(struct usb_request *req)
{
- return ioctl(ep->dev->fd, USBDEVFS_DISCARDURB, &ep->urb);
-}
-
-struct usb_device *usb_endpoint_get_device(struct usb_endpoint *ep)
-{
- return ep->dev;
-}
-
-int usb_endpoint_number(struct usb_endpoint *ep)
-{
- return ep->desc.bEndpointAddress;
-}
-
-int usb_endpoint_max_packet(struct usb_endpoint *ep)
-{
- return __le16_to_cpu(ep->desc.wMaxPacketSize);
+ struct usbdevfs_urb *urb = ((struct usbdevfs_urb*)req->private_data);
+ return ioctl(req->dev->fd, USBDEVFS_DISCARDURB, &urb);
}
diff --git a/rootdir/etc/init.goldfish.rc b/rootdir/etc/init.goldfish.rc
index 6f30843..fa70c2e 100644
--- a/rootdir/etc/init.goldfish.rc
+++ b/rootdir/etc/init.goldfish.rc
@@ -22,6 +22,11 @@
stop dund
stop akmd
+# start essential services
+ start qemud
+ start goldfish-logcat
+ start goldfish-setup
+
setprop ro.setupwizard.mode EMULATOR
# enable Google-specific location features,
@@ -42,6 +47,8 @@
# something else.
service goldfish-setup /system/etc/init.goldfish.sh
+ user root
+ group root
oneshot
service qemud /system/bin/qemud
@@ -52,7 +59,7 @@
# program to check wether it runs on the emulator
# if it does, it redirects its output to the device
# named by the androidboot.console kernel option
-# if not, is simply exit immediately
+# if not, is simply exits immediately
service goldfish-logcat /system/bin/logcat -Q
oneshot
diff --git a/rootdir/etc/init.goldfish.sh b/rootdir/etc/init.goldfish.sh
index cfa2c82..c18c032 100755
--- a/rootdir/etc/init.goldfish.sh
+++ b/rootdir/etc/init.goldfish.sh
@@ -18,7 +18,7 @@
;;
esac
-num_dns=`getprop ro.kernel.android.ndns`
+num_dns=`getprop ro.kernel.ndns`
case "$num_dns" in
2) setprop net.eth0.dns2 10.0.2.4
;;
@@ -44,7 +44,7 @@
# this line doesn't really do anything useful. however without it the
# previous setprop doesn't seem to apply for some really odd reason
-setprop ro.qemu.init.completed 1
+#setprop ro.qemu.init.completed 1
# set up the second interface (for inter-emulator connections)
# if required
diff --git a/rootdir/etc/ueventd.goldfish.rc b/rootdir/etc/ueventd.goldfish.rc
index e69de29..b5828e7 100644
--- a/rootdir/etc/ueventd.goldfish.rc
+++ b/rootdir/etc/ueventd.goldfish.rc
@@ -0,0 +1,4 @@
+# These settings are specific to running under the Android emulator
+/dev/qemu_trace 0666 system system
+/dev/ttyS* 0666 system system
+/proc 0666 system system
diff --git a/rootdir/init.rc b/rootdir/init.rc
index 9f3020f..f230965 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -374,7 +374,7 @@
service drm /system/bin/drmserver
class main
user drm
- group system root inet
+ group inet
service drmio /system/bin/drmioserver
class main
diff --git a/rootdir/ueventd.rc b/rootdir/ueventd.rc
index a52bdda..c0540a7 100644
--- a/rootdir/ueventd.rc
+++ b/rootdir/ueventd.rc
@@ -63,7 +63,6 @@
/dev/snd/dsp1 0660 system audio
/dev/snd/mixer 0660 system audio
/dev/smd0 0640 radio radio
-/dev/qemu_trace 0666 system system
/dev/qmi 0640 radio radio
/dev/qmi0 0640 radio radio
/dev/qmi1 0640 radio radio
diff --git a/toolbox/Android.mk b/toolbox/Android.mk
index bc8c02f..ff01172 100644
--- a/toolbox/Android.mk
+++ b/toolbox/Android.mk
@@ -57,6 +57,7 @@
lsof
LOCAL_SRC_FILES:= \
+ dynarray.c \
toolbox.c \
$(patsubst %,%.c,$(TOOLS))
diff --git a/toolbox/dynarray.c b/toolbox/dynarray.c
new file mode 100644
index 0000000..e9b7b03
--- /dev/null
+++ b/toolbox/dynarray.c
@@ -0,0 +1,103 @@
+#include "dynarray.h"
+#include <stdlib.h>
+#include <limits.h>
+
+void
+dynarray_init( dynarray_t *a )
+{
+ a->count = a->capacity = 0;
+ a->items = NULL;
+}
+
+
+static void
+dynarray_reserve_more( dynarray_t *a, int count )
+{
+ int old_cap = a->capacity;
+ int new_cap = old_cap;
+ const int max_cap = INT_MAX/sizeof(void*);
+ void** new_items;
+ int new_count = a->count + count;
+
+ if (count <= 0)
+ return;
+
+ if (count > max_cap - a->count)
+ abort();
+
+ new_count = a->count + count;
+
+ while (new_cap < new_count) {
+ old_cap = new_cap;
+ new_cap += (new_cap >> 2) + 4;
+ if (new_cap < old_cap || new_cap > max_cap) {
+ new_cap = max_cap;
+ }
+ }
+ new_items = realloc(a->items, new_cap*sizeof(void*));
+ if (new_items == NULL)
+ abort();
+
+ a->items = new_items;
+ a->capacity = new_cap;
+}
+
+void
+dynarray_append( dynarray_t *a, void* item )
+{
+ if (a->count >= a->capacity)
+ dynarray_reserve_more(a, 1);
+
+ a->items[a->count++] = item;
+}
+
+void
+dynarray_done( dynarray_t *a )
+{
+ free(a->items);
+ a->items = NULL;
+ a->count = a->capacity = 0;
+}
+
+// string arrays
+
+void strlist_init( strlist_t *list )
+{
+ dynarray_init(list);
+}
+
+void strlist_append_b( strlist_t *list, const void* str, size_t slen )
+{
+ char *copy = malloc(slen+1);
+ memcpy(copy, str, slen);
+ copy[slen] = '\0';
+ dynarray_append(list, copy);
+}
+
+void strlist_append_dup( strlist_t *list, const char *str)
+{
+ strlist_append_b(list, str, strlen(str));
+}
+
+void strlist_done( strlist_t *list )
+{
+ STRLIST_FOREACH(list, string, free(string));
+ dynarray_done(list);
+}
+
+static int strlist_compare_strings(const void* a, const void* b)
+{
+ const char *sa = *(const char **)a;
+ const char *sb = *(const char **)b;
+ return strcmp(sa, sb);
+}
+
+void strlist_sort( strlist_t *list )
+{
+ if (list->count > 0) {
+ qsort(list->items,
+ (size_t)list->count,
+ sizeof(void*),
+ strlist_compare_strings);
+ }
+}
diff --git a/toolbox/dynarray.h b/toolbox/dynarray.h
new file mode 100644
index 0000000..f73fb3b
--- /dev/null
+++ b/toolbox/dynarray.h
@@ -0,0 +1,80 @@
+#ifndef DYNARRAY_H
+#define DYNARRAY_H
+
+#include <stddef.h>
+
+/* simple dynamic array of pointers */
+typedef struct {
+ int count;
+ int capacity;
+ void** items;
+} dynarray_t;
+
+#define DYNARRAY_INITIALIZER { 0, 0, NULL }
+
+void dynarray_init( dynarray_t *a );
+void dynarray_done( dynarray_t *a );
+
+void dynarray_append( dynarray_t *a, void* item );
+
+/* Used to iterate over a dynarray_t
+ * _array :: pointer to the array
+ * _item_type :: type of objects pointed to by the array
+ * _item :: name of a local variable defined within the loop
+ * with type '_item_type'
+ * _stmnt :: C statement that will be executed in each iteration.
+ *
+ * You case use 'break' and 'continue' within _stmnt
+ *
+ * This macro is only intended for simple uses. I.e. do not add or
+ * remove items from the array during iteration.
+ */
+#define DYNARRAY_FOREACH_TYPE(_array,_item_type,_item,_stmnt) \
+ do { \
+ int _nn_##__LINE__ = 0; \
+ for (;_nn_##__LINE__ < (_array)->count; ++ _nn_##__LINE__) { \
+ _item_type _item = (_item_type)(_array)->items[_nn_##__LINE__]; \
+ _stmnt; \
+ } \
+ } while (0)
+
+#define DYNARRAY_FOREACH(_array,_item,_stmnt) \
+ DYNARRAY_FOREACH_TYPE(_array,void *,_item,_stmnt)
+
+/* Simple dynamic string arrays
+ *
+ * NOTE: A strlist_t owns the strings it references.
+ */
+typedef dynarray_t strlist_t;
+
+#define STRLIST_INITIALIZER DYNARRAY_INITIALIZER
+
+/* Used to iterate over a strlist_t
+ * _list :: pointer to strlist_t object
+ * _string :: name of local variable name defined within the loop with
+ * type 'char*'
+ * _stmnt :: C statement executed in each iteration
+ *
+ * This macro is only intended for simple uses. Do not add or remove items
+ * to/from the list during iteration.
+ */
+#define STRLIST_FOREACH(_list,_string,_stmnt) \
+ DYNARRAY_FOREACH_TYPE(_list,char *,_string,_stmnt)
+
+void strlist_init( strlist_t *list );
+
+/* note: strlist_done will free all the strings owned by the list */
+void strlist_done( strlist_t *list );
+
+/* append a new string made of the first 'slen' characters from 'str'
+ * followed by a trailing zero.
+ */
+void strlist_append_b( strlist_t *list, const void* str, size_t slen );
+
+/* append the copy of a given input string to a strlist_t */
+void strlist_append_dup( strlist_t *list, const char *str);
+
+/* sort the strings in a given list (using strcmp) */
+void strlist_sort( strlist_t *list );
+
+#endif /* DYNARRAY_H */
\ No newline at end of file
diff --git a/toolbox/getprop.c b/toolbox/getprop.c
index fc80a4d..616644a 100644
--- a/toolbox/getprop.c
+++ b/toolbox/getprop.c
@@ -1,13 +1,34 @@
#include <stdio.h>
+#include <stdlib.h>
#include <cutils/properties.h>
#include <sys/system_properties.h>
+#include "dynarray.h"
-static void proplist(const char *key, const char *name,
- void *user __attribute__((unused)))
+static void record_prop(const char* key, const char* name, void* opaque)
{
- printf("[%s]: [%s]\n", key, name);
+ strlist_t* list = opaque;
+ char temp[PROP_VALUE_MAX + PROP_NAME_MAX + 16];
+ snprintf(temp, sizeof temp, "[%s] [%s]", key, name);
+ strlist_append_dup(list, temp);
+}
+
+static void list_properties(void)
+{
+ strlist_t list[1] = { STRLIST_INITIALIZER };
+
+ /* Record properties in the string list */
+ (void)property_list(record_prop, list);
+
+ /* Sort everything */
+ strlist_sort(list);
+
+ /* print everything */
+ STRLIST_FOREACH(list, str, printf("%s\n", str));
+
+ /* voila */
+ strlist_done(list);
}
int __system_property_wait(prop_info *pi);
@@ -17,7 +38,7 @@
int n = 0;
if (argc == 1) {
- (void)property_list(proplist, NULL);
+ list_properties();
} else {
char value[PROPERTY_VALUE_MAX];
char *default_value;
diff --git a/toolbox/ls.c b/toolbox/ls.c
index daa8095..b08e378 100644
--- a/toolbox/ls.c
+++ b/toolbox/ls.c
@@ -15,128 +15,7 @@
#include <linux/kdev_t.h>
#include <limits.h>
-// dynamic arrays
-typedef struct {
- int count;
- int capacity;
- void** items;
-} dynarray_t;
-
-#define DYNARRAY_INITIALIZER { 0, 0, NULL }
-
-static void dynarray_init( dynarray_t *a )
-{
- a->count = a->capacity = 0;
- a->items = NULL;
-}
-
-static void dynarray_reserve_more( dynarray_t *a, int count )
-{
- int old_cap = a->capacity;
- int new_cap = old_cap;
- const int max_cap = INT_MAX/sizeof(void*);
- void** new_items;
- int new_count = a->count + count;
-
- if (count <= 0)
- return;
-
- if (count > max_cap - a->count)
- abort();
-
- new_count = a->count + count;
-
- while (new_cap < new_count) {
- old_cap = new_cap;
- new_cap += (new_cap >> 2) + 4;
- if (new_cap < old_cap || new_cap > max_cap) {
- new_cap = max_cap;
- }
- }
- new_items = realloc(a->items, new_cap*sizeof(void*));
- if (new_items == NULL)
- abort();
-
- a->items = new_items;
- a->capacity = new_cap;
-}
-
-static void dynarray_append( dynarray_t *a, void* item )
-{
- if (a->count >= a->capacity)
- dynarray_reserve_more(a, 1);
-
- a->items[a->count++] = item;
-}
-
-static void dynarray_done( dynarray_t *a )
-{
- free(a->items);
- a->items = NULL;
- a->count = a->capacity = 0;
-}
-
-#define DYNARRAY_FOREACH_TYPE(_array,_item_type,_item,_stmnt) \
- do { \
- int _nn_##__LINE__ = 0; \
- for (;_nn_##__LINE__ < (_array)->count; ++ _nn_##__LINE__) { \
- _item_type _item = (_item_type)(_array)->items[_nn_##__LINE__]; \
- _stmnt; \
- } \
- } while (0)
-
-#define DYNARRAY_FOREACH(_array,_item,_stmnt) \
- DYNARRAY_FOREACH_TYPE(_array,void *,_item,_stmnt)
-
-// string arrays
-
-typedef dynarray_t strlist_t;
-
-#define STRLIST_INITIALIZER DYNARRAY_INITIALIZER
-
-#define STRLIST_FOREACH(_list,_string,_stmnt) \
- DYNARRAY_FOREACH_TYPE(_list,char *,_string,_stmnt)
-
-static void strlist_init( strlist_t *list )
-{
- dynarray_init(list);
-}
-
-static void strlist_append_b( strlist_t *list, const void* str, size_t slen )
-{
- char *copy = malloc(slen+1);
- memcpy(copy, str, slen);
- copy[slen] = '\0';
- dynarray_append(list, copy);
-}
-
-static void strlist_append_dup( strlist_t *list, const char *str)
-{
- strlist_append_b(list, str, strlen(str));
-}
-
-static void strlist_done( strlist_t *list )
-{
- STRLIST_FOREACH(list, string, free(string));
- dynarray_done(list);
-}
-
-static int strlist_compare_strings(const void* a, const void* b)
-{
- const char *sa = *(const char **)a;
- const char *sb = *(const char **)b;
- return strcmp(sa, sb);
-}
-
-static void strlist_sort( strlist_t *list )
-{
- if (list->count > 0) {
- qsort(list->items,
- (size_t)list->count,
- sizeof(void*),
- strlist_compare_strings);
- }
-}
+#include "dynarray.h"
// bits for flags argument
#define LIST_LONG (1 << 0)
@@ -166,7 +45,7 @@
static void mode2str(unsigned mode, char *out)
{
*out++ = mode2kind(mode);
-
+
*out++ = (mode & 0400) ? 'r' : '-';
*out++ = (mode & 0200) ? 'w' : '-';
if(mode & 04000) {
@@ -290,7 +169,7 @@
strftime(date, 32, "%Y-%m-%d %H:%M", localtime((const time_t*)&s.st_mtime));
date[31] = 0;
-
+
// 12345678901234567890123456789012345678901234567890123456789012345678901234567890
// MMMMMMMM UUUUUUUU GGGGGGGGG XXXXXXXX YYYY-MM-DD HH:MM NAME (->LINK)
@@ -298,7 +177,7 @@
case S_IFBLK:
case S_IFCHR:
printf("%s %-8s %-8s %3d, %3d %s %s\n",
- mode, user, group,
+ mode, user, group,
(int) MAJOR(s.st_rdev), (int) MINOR(s.st_rdev),
date, name);
break;
@@ -312,7 +191,7 @@
len = readlink(path, linkto, 256);
if(len < 0) return -1;
-
+
if(len > 255) {
linkto[252] = '.';
linkto[253] = '.';
@@ -321,7 +200,7 @@
} else {
linkto[len] = 0;
}
-
+
printf("%s %-8s %-8s %s %s -> %s\n",
mode, user, group, date, name, linkto);
break;
@@ -364,7 +243,7 @@
DIR *d;
struct dirent *de;
strlist_t files = STRLIST_INITIALIZER;
-
+
d = opendir(name);
if(d == 0) {
fprintf(stderr, "opendir failed, %s\n", strerror(errno));
@@ -469,7 +348,7 @@
{
int flags = 0;
int listed = 0;
-
+
if(argc > 1) {
int i;
int err = 0;
@@ -509,7 +388,7 @@
return err;
}
}
-
- // list working directory if no files or directories were specified
+
+ // list working directory if no files or directories were specified
return listpath(".", flags);
}
diff --git a/toolbox/uptime.c b/toolbox/uptime.c
index 3d8061c..1c312b0 100644
--- a/toolbox/uptime.c
+++ b/toolbox/uptime.c
@@ -35,6 +35,7 @@
#include <linux/android_alarm.h>
#include <fcntl.h>
#include <stdio.h>
+#include <time.h>
static void format_time(int time, char* buffer) {
@@ -75,19 +76,26 @@
float up_time, idle_time;
char up_string[100], idle_string[100], sleep_string[100];
int elapsed;
+ struct timespec up_timespec;
FILE* file = fopen("/proc/uptime", "r");
if (!file) {
fprintf(stderr, "Could not open /proc/uptime\n");
return -1;
}
- if (fscanf(file, "%f %f", &up_time, &idle_time) != 2) {
+ if (fscanf(file, "%*f %f", &idle_time) != 1) {
fprintf(stderr, "Could not parse /proc/uptime\n");
fclose(file);
return -1;
}
fclose(file);
+ if (clock_gettime(CLOCK_MONOTONIC, &up_timespec) < 0) {
+ fprintf(stderr, "Could not get monotonic time\n");
+ return -1;
+ }
+ up_time = up_timespec.tv_sec + up_timespec.tv_nsec / 1e9;
+
elapsed = elapsedRealtime();
if (elapsed < 0) {
fprintf(stderr, "elapsedRealtime failed\n");