summaryrefslogtreecommitdiffstats
path: root/libcutils
diff options
context:
space:
mode:
authorMathias Agopian <mathias@google.com>2009-05-22 01:08:01 -0700
committerMathias Agopian <mathias@google.com>2009-05-22 01:08:01 -0700
commit67667115c51693ac27338be2aa7004789b15ff81 (patch)
tree19b840f4ae9c91448722069085a5e97f6c5a1d10 /libcutils
parentb862ab74c95e4f76c7081ea5756c7ba719833f8c (diff)
parentad3f0d74b4d0c52a819b0b4b242f26bd4ce07bc9 (diff)
downloadsystem_core-67667115c51693ac27338be2aa7004789b15ff81.zip
system_core-67667115c51693ac27338be2aa7004789b15ff81.tar.gz
system_core-67667115c51693ac27338be2aa7004789b15ff81.tar.bz2
merge master to master_gl
Diffstat (limited to 'libcutils')
-rw-r--r--libcutils/Android.mk2
-rw-r--r--libcutils/abort_socket.c293
-rw-r--r--libcutils/fdevent.c506
-rw-r--r--libcutils/native_handle.c20
-rw-r--r--libcutils/tzstrftime.c15
5 files changed, 315 insertions, 521 deletions
diff --git a/libcutils/Android.mk b/libcutils/Android.mk
index 3bc48fb..aaee8bf 100644
--- a/libcutils/Android.mk
+++ b/libcutils/Android.mk
@@ -17,6 +17,7 @@ LOCAL_PATH := $(my-dir)
include $(CLEAR_VARS)
commonSources := \
+ abort_socket.c \
array.c \
hashmap.c \
atomic.c \
@@ -62,7 +63,6 @@ else
commonSources += \
mspace.c \
selector.c \
- fdevent.c \
tztime.c \
adb_networking.c \
zygote.c
diff --git a/libcutils/abort_socket.c b/libcutils/abort_socket.c
new file mode 100644
index 0000000..d732142
--- /dev/null
+++ b/libcutils/abort_socket.c
@@ -0,0 +1,293 @@
+/*
+ * Copyright 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.
+ */
+
+#include <stdlib.h>
+#include <errno.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/socket.h>
+#include <sys/poll.h>
+
+#include "cutils/abort_socket.h"
+
+struct asocket *asocket_init(int fd) {
+ int abort_fd[2];
+ int flags;
+ struct asocket *s;
+
+ /* set primary socket to non-blocking */
+ flags = fcntl(fd, F_GETFL);
+ if (flags == -1)
+ return NULL;
+ if (fcntl(fd, F_SETFL, flags | O_NONBLOCK))
+ return NULL;
+
+ /* create pipe with non-blocking write, so that asocket_close() cannot
+ block */
+ if (pipe(abort_fd))
+ return NULL;
+ flags = fcntl(abort_fd[1], F_GETFL);
+ if (flags == -1)
+ return NULL;
+ if (fcntl(abort_fd[1], F_SETFL, flags | O_NONBLOCK))
+ return NULL;
+
+ s = malloc(sizeof(struct asocket));
+ if (!s)
+ return NULL;
+
+ s->fd = fd;
+ s->abort_fd[0] = abort_fd[0];
+ s->abort_fd[1] = abort_fd[1];
+
+ return s;
+}
+
+int asocket_connect(struct asocket *s, const struct sockaddr *addr,
+ socklen_t addrlen, int timeout) {
+
+ int ret;
+
+ do {
+ ret = connect(s->fd, addr, addrlen);
+ } while (ret && errno == EINTR);
+
+ if (ret && errno == EINPROGRESS) {
+ /* ready to poll() */
+ socklen_t retlen;
+ struct pollfd pfd[2];
+
+ pfd[0].fd = s->fd;
+ pfd[0].events = POLLOUT;
+ pfd[0].revents = 0;
+ pfd[1].fd = s->abort_fd[0];
+ pfd[1].events = POLLIN;
+ pfd[1].revents = 0;
+
+ do {
+ ret = poll(pfd, 2, timeout);
+ } while (ret < 0 && errno == EINTR);
+
+ if (ret < 0)
+ return -1;
+ else if (ret == 0) {
+ /* timeout */
+ errno = ETIMEDOUT;
+ return -1;
+ }
+
+ if (pfd[1].revents) {
+ /* abort due to asocket_abort() */
+ errno = ECANCELED;
+ return -1;
+ }
+
+ if (pfd[0].revents) {
+ if (pfd[0].revents & POLLOUT) {
+ /* connect call complete, read return code */
+ retlen = sizeof(ret);
+ if (getsockopt(s->fd, SOL_SOCKET, SO_ERROR, &ret, &retlen))
+ return -1;
+ /* got connect() return code */
+ if (ret) {
+ errno = ret;
+ }
+ } else {
+ /* some error event on this fd */
+ errno = ECONNABORTED;
+ return -1;
+ }
+ }
+ }
+
+ return ret;
+}
+
+int asocket_accept(struct asocket *s, struct sockaddr *addr,
+ socklen_t *addrlen, int timeout) {
+
+ int ret;
+ struct pollfd pfd[2];
+
+ pfd[0].fd = s->fd;
+ pfd[0].events = POLLIN;
+ pfd[0].revents = 0;
+ pfd[1].fd = s->abort_fd[0];
+ pfd[1].events = POLLIN;
+ pfd[1].revents = 0;
+
+ do {
+ ret = poll(pfd, 2, timeout);
+ } while (ret < 0 && errno == EINTR);
+
+ if (ret < 0)
+ return -1;
+ else if (ret == 0) {
+ /* timeout */
+ errno = ETIMEDOUT;
+ return -1;
+ }
+
+ if (pfd[1].revents) {
+ /* abort due to asocket_abort() */
+ errno = ECANCELED;
+ return -1;
+ }
+
+ if (pfd[0].revents) {
+ if (pfd[0].revents & POLLIN) {
+ /* ready to accept() without blocking */
+ do {
+ ret = accept(s->fd, addr, addrlen);
+ } while (ret < 0 && errno == EINTR);
+ } else {
+ /* some error event on this fd */
+ errno = ECONNABORTED;
+ return -1;
+ }
+ }
+
+ return ret;
+}
+
+int asocket_read(struct asocket *s, void *buf, size_t count, int timeout) {
+ int ret;
+ struct pollfd pfd[2];
+
+ pfd[0].fd = s->fd;
+ pfd[0].events = POLLIN;
+ pfd[0].revents = 0;
+ pfd[1].fd = s->abort_fd[0];
+ pfd[1].events = POLLIN;
+ pfd[1].revents = 0;
+
+ do {
+ ret = poll(pfd, 2, timeout);
+ } while (ret < 0 && errno == EINTR);
+
+ if (ret < 0)
+ return -1;
+ else if (ret == 0) {
+ /* timeout */
+ errno = ETIMEDOUT;
+ return -1;
+ }
+
+ if (pfd[1].revents) {
+ /* abort due to asocket_abort() */
+ errno = ECANCELED;
+ return -1;
+ }
+
+ if (pfd[0].revents) {
+ if (pfd[0].revents & POLLIN) {
+ /* ready to read() without blocking */
+ do {
+ ret = read(s->fd, buf, count);
+ } while (ret < 0 && errno == EINTR);
+ } else {
+ /* some error event on this fd */
+ errno = ECONNABORTED;
+ return -1;
+ }
+ }
+
+ return ret;
+}
+
+int asocket_write(struct asocket *s, const void *buf, size_t count,
+ int timeout) {
+ int ret;
+ struct pollfd pfd[2];
+
+ pfd[0].fd = s->fd;
+ pfd[0].events = POLLOUT;
+ pfd[0].revents = 0;
+ pfd[1].fd = s->abort_fd[0];
+ pfd[1].events = POLLIN;
+ pfd[1].revents = 0;
+
+ do {
+ ret = poll(pfd, 2, timeout);
+ } while (ret < 0 && errno == EINTR);
+
+ if (ret < 0)
+ return -1;
+ else if (ret == 0) {
+ /* timeout */
+ errno = ETIMEDOUT;
+ return -1;
+ }
+
+ if (pfd[1].revents) {
+ /* abort due to asocket_abort() */
+ errno = ECANCELED;
+ return -1;
+ }
+
+ if (pfd[0].revents) {
+ if (pfd[0].revents & POLLIN) {
+ /* ready to write() without blocking */
+ do {
+ ret = write(s->fd, buf, count);
+ } while (ret < 0 && errno == EINTR);
+ } else {
+ /* some error event on this fd */
+ errno = ECONNABORTED;
+ return -1;
+ }
+ }
+
+ return ret;
+}
+
+void asocket_abort(struct asocket *s) {
+ int ret;
+ char buf = 0;
+
+ /* Prevent further use of fd, without yet releasing the fd */
+ shutdown(s->fd, SHUT_RDWR);
+
+ /* wake up calls blocked at poll() */
+ do {
+ ret = write(s->abort_fd[1], &buf, 1);
+ } while (ret < 0 && errno == EINTR);
+}
+
+void asocket_destroy(struct asocket *s) {
+ struct asocket s_copy = *s;
+
+ /* Clients should *not* be using these fd's after calling
+ asocket_destroy(), but in case they do, set to -1 so they cannot use a
+ stale fd */
+ s->fd = -1;
+ s->abort_fd[0] = -1;
+ s->abort_fd[1] = -1;
+
+ /* Call asocket_abort() in case there are still threads blocked on this
+ socket. Clients should not rely on this behavior - it is racy because we
+ are about to close() these sockets - clients should instead make sure
+ all threads are done with the socket before calling asocket_destory().
+ */
+ asocket_abort(&s_copy);
+
+ /* enough safety checks, close and release memory */
+ close(s_copy.abort_fd[1]);
+ close(s_copy.abort_fd[0]);
+ close(s_copy.fd);
+
+ free(s);
+}
diff --git a/libcutils/fdevent.c b/libcutils/fdevent.c
deleted file mode 100644
index 4cf46fa..0000000
--- a/libcutils/fdevent.c
+++ /dev/null
@@ -1,506 +0,0 @@
-/* http://frotznet.googlecode.com/svn/trunk/utils/fdevent.c
-**
-** 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.
-** 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 <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <errno.h>
-
-#include <fcntl.h>
-
-#include <stdarg.h>
-#include <stddef.h>
-
-#include <cutils/fdevent.h>
-
-#define TRACE(x...) fprintf(stderr,x)
-
-#define DEBUG 0
-
-static void fatal(const char *fn, const char *fmt, ...)
-{
- va_list ap;
- va_start(ap, fmt);
- fprintf(stderr, "%s:", fn);
- vfprintf(stderr, fmt, ap);
- va_end(ap);
- abort();
-}
-
-#define FATAL(x...) fatal(__FUNCTION__, x)
-
-#if DEBUG
-static void dump_fde(fdevent *fde, const char *info)
-{
- fprintf(stderr,"FDE #%03d %c%c%c %s\n", fde->fd,
- fde->state & FDE_READ ? 'R' : ' ',
- fde->state & FDE_WRITE ? 'W' : ' ',
- fde->state & FDE_ERROR ? 'E' : ' ',
- info);
-}
-#else
-#define dump_fde(fde, info) do { } while(0)
-#endif
-
-#define FDE_EVENTMASK 0x00ff
-#define FDE_STATEMASK 0xff00
-
-#define FDE_ACTIVE 0x0100
-#define FDE_PENDING 0x0200
-#define FDE_CREATED 0x0400
-
-static void fdevent_plist_enqueue(fdevent *node);
-static void fdevent_plist_remove(fdevent *node);
-static fdevent *fdevent_plist_dequeue(void);
-
-static fdevent list_pending = {
- .next = &list_pending,
- .prev = &list_pending,
-};
-
-static fdevent **fd_table = 0;
-static int fd_table_max = 0;
-
-#ifdef CRAPTASTIC
-//HAVE_EPOLL
-
-#include <sys/epoll.h>
-
-static int epoll_fd = -1;
-
-static void fdevent_init()
-{
- /* 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);
- }
-
- /* mark for close-on-exec */
- fcntl(epoll_fd, F_SETFD, FD_CLOEXEC);
-}
-
-static void fdevent_connect(fdevent *fde)
-{
- struct epoll_event ev;
-
- memset(&ev, 0, sizeof(ev));
- ev.events = 0;
- ev.data.ptr = fde;
-
-#if 0
- if(epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fde->fd, &ev)) {
- perror("epoll_ctl() failed\n");
- exit(1);
- }
-#endif
-}
-
-static void fdevent_disconnect(fdevent *fde)
-{
- struct epoll_event ev;
-
- memset(&ev, 0, sizeof(ev));
- ev.events = 0;
- ev.data.ptr = fde;
-
- /* technically we only need to delete if we
- ** were actively monitoring events, but let's
- ** be aggressive and do it anyway, just in case
- ** something's out of sync
- */
- epoll_ctl(epoll_fd, EPOLL_CTL_DEL, fde->fd, &ev);
-}
-
-static void fdevent_update(fdevent *fde, unsigned events)
-{
- struct epoll_event ev;
- int active;
-
- active = (fde->state & FDE_EVENTMASK) != 0;
-
- memset(&ev, 0, sizeof(ev));
- ev.events = 0;
- ev.data.ptr = fde;
-
- if(events & FDE_READ) ev.events |= EPOLLIN;
- if(events & FDE_WRITE) ev.events |= EPOLLOUT;
- if(events & FDE_ERROR) ev.events |= (EPOLLERR | EPOLLHUP);
-
- fde->state = (fde->state & FDE_STATEMASK) | events;
-
- if(active) {
- /* we're already active. if we're changing to *no*
- ** events being monitored, we need to delete, otherwise
- ** we need to just modify
- */
- if(ev.events) {
- if(epoll_ctl(epoll_fd, EPOLL_CTL_MOD, fde->fd, &ev)) {
- perror("epoll_ctl() failed\n");
- exit(1);
- }
- } else {
- if(epoll_ctl(epoll_fd, EPOLL_CTL_DEL, fde->fd, &ev)) {
- perror("epoll_ctl() failed\n");
- exit(1);
- }
- }
- } else {
- /* we're not active. if we're watching events, we need
- ** to add, otherwise we can just do nothing
- */
- if(ev.events) {
- if(epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fde->fd, &ev)) {
- perror("epoll_ctl() failed\n");
- exit(1);
- }
- }
- }
-}
-
-static void fdevent_process()
-{
- struct epoll_event events[256];
- fdevent *fde;
- int i, n;
-
- n = epoll_wait(epoll_fd, events, 256, -1);
-
- if(n < 0) {
- if(errno == EINTR) return;
- perror("epoll_wait");
- exit(1);
- }
-
- for(i = 0; i < n; i++) {
- struct epoll_event *ev = events + i;
- fde = ev->data.ptr;
-
- if(ev->events & EPOLLIN) {
- fde->events |= FDE_READ;
- }
- if(ev->events & EPOLLOUT) {
- fde->events |= FDE_WRITE;
- }
- if(ev->events & (EPOLLERR | EPOLLHUP)) {
- fde->events |= FDE_ERROR;
- }
- if(fde->events) {
- if(fde->state & FDE_PENDING) continue;
- fde->state |= FDE_PENDING;
- fdevent_plist_enqueue(fde);
- }
- }
-}
-
-#else /* USE_SELECT */
-
-#ifdef HAVE_WINSOCK
-#include <winsock2.h>
-#else
-#include <sys/select.h>
-#endif
-
-static fd_set read_fds;
-static fd_set write_fds;
-static fd_set error_fds;
-
-static int select_n = 0;
-
-static void fdevent_init(void)
-{
- FD_ZERO(&read_fds);
- FD_ZERO(&write_fds);
- FD_ZERO(&error_fds);
-}
-
-static void fdevent_connect(fdevent *fde)
-{
- if(fde->fd >= select_n) {
- select_n = fde->fd + 1;
- }
-}
-
-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);
-
- for(n = 0, i = 0; i < select_n; i++) {
- if(fd_table[i] != 0) n = i;
- }
- select_n = n + 1;
-}
-
-static void fdevent_update(fdevent *fde, unsigned events)
-{
- if(events & FDE_READ) {
- FD_SET(fde->fd, &read_fds);
- } else {
- FD_CLR(fde->fd, &read_fds);
- }
- if(events & FDE_WRITE) {
- FD_SET(fde->fd, &write_fds);
- } else {
- FD_CLR(fde->fd, &write_fds);
- }
- if(events & FDE_ERROR) {
- FD_SET(fde->fd, &error_fds);
- } else {
- FD_CLR(fde->fd, &error_fds);
- }
-
- fde->state = (fde->state & FDE_STATEMASK) | events;
-}
-
-static void fdevent_process()
-{
- int i, n;
- fdevent *fde;
- unsigned events;
- fd_set rfd, wfd, efd;
-
- 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");
- return;
- }
-
- for(i = 0; (i < select_n) && (n > 0); i++) {
- events = 0;
- if(FD_ISSET(i, &rfd)) events |= FDE_READ;
- if(FD_ISSET(i, &wfd)) events |= FDE_WRITE;
- if(FD_ISSET(i, &efd)) events |= FDE_ERROR;
-
- 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);
- }
- }
-}
-
-#endif
-
-static void fdevent_register(fdevent *fde)
-{
- 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) {
- FATAL("bogus huuuuge fd (%d)\n", fde->fd);
- }
- if(fd_table_max == 0) {
- fdevent_init();
- fd_table_max = 256;
- }
- while(fd_table_max <= fde->fd) {
- fd_table_max *= 2;
- }
- fd_table = realloc(fd_table, sizeof(fdevent*) * fd_table_max);
- if(fd_table == 0) {
- FATAL("could not expand fd_table to %d entries\n", fd_table_max);
- }
- memset(fd_table + oldmax, 0, sizeof(int) * (fd_table_max - oldmax));
- }
-
- fd_table[fde->fd] = fde;
-}
-
-static void fdevent_unregister(fdevent *fde)
-{
- if((fde->fd < 0) || (fde->fd >= fd_table_max)) {
- FATAL("fd out of range (%d)\n", fde->fd);
- }
-
- if(fd_table[fde->fd] != fde) {
- FATAL("fd_table out of sync");
- }
-
- fd_table[fde->fd] = 0;
-
- if(!(fde->state & FDE_DONT_CLOSE)) {
- dump_fde(fde, "close");
- close(fde->fd);
- }
-}
-
-static void fdevent_plist_enqueue(fdevent *node)
-{
- fdevent *list = &list_pending;
-
- node->next = list;
- node->prev = list->prev;
- node->prev->next = node;
- list->prev = node;
-}
-
-static void fdevent_plist_remove(fdevent *node)
-{
- node->prev->next = node->next;
- node->next->prev = node->prev;
- node->next = 0;
- node->prev = 0;
-}
-
-static fdevent *fdevent_plist_dequeue(void)
-{
- fdevent *list = &list_pending;
- fdevent *node = list->next;
-
- if(node == list) return 0;
-
- list->next = node->next;
- list->next->prev = list;
- node->next = 0;
- node->prev = 0;
-
- return node;
-}
-
-fdevent *fdevent_create(int fd, fd_func func, void *arg)
-{
- fdevent *fde = (fdevent*) malloc(sizeof(fdevent));
- if(fde == 0) return 0;
- fdevent_install(fde, fd, func, arg);
- fde->state |= FDE_CREATED;
- return fde;
-}
-
-void fdevent_destroy(fdevent *fde)
-{
- if(fde == 0) return;
- if(!(fde->state & FDE_CREATED)) {
- FATAL("fde %p not created by fdevent_create()\n", fde);
- }
- fdevent_remove(fde);
-}
-
-void fdevent_install(fdevent *fde, int fd, fd_func func, void *arg)
-{
- memset(fde, 0, sizeof(fdevent));
- fde->state = FDE_ACTIVE;
- fde->fd = fd;
- fde->func = func;
- fde->arg = arg;
-
-#ifndef HAVE_WINSOCK
- fcntl(fd, F_SETFL, O_NONBLOCK);
-#endif
- fdevent_register(fde);
- dump_fde(fde, "connect");
- fdevent_connect(fde);
- fde->state |= FDE_ACTIVE;
-}
-
-void fdevent_remove(fdevent *fde)
-{
- if(fde->state & FDE_PENDING) {
- fdevent_plist_remove(fde);
- }
-
- if(fde->state & FDE_ACTIVE) {
- fdevent_disconnect(fde);
- dump_fde(fde, "disconnect");
- fdevent_unregister(fde);
- }
-
- fde->state = 0;
- fde->events = 0;
-}
-
-
-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");
- }
-
- fde->state = (fde->state & FDE_STATEMASK) | events;
-
- if(fde->state & FDE_PENDING) {
- /* if we're pending, make sure
- ** we don't signal an event that
- ** is no longer wanted.
- */
- fde->events &= (~events);
- if(fde->events == 0) {
- fdevent_plist_remove(fde);
- fde->state &= (~FDE_PENDING);
- }
- }
-}
-
-void fdevent_add(fdevent *fde, unsigned events)
-{
- fdevent_set(
- fde, (fde->state & FDE_EVENTMASK) | (events & FDE_EVENTMASK));
-}
-
-void fdevent_del(fdevent *fde, unsigned events)
-{
- fdevent_set(
- fde, (fde->state & FDE_EVENTMASK) & (~(events & FDE_EVENTMASK)));
-}
-
-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;
- fde->state &= (~FDE_PENDING);
- dump_fde(fde, "callback");
- fde->func(fde->fd, events, fde->arg);
- }
- }
-}
-
diff --git a/libcutils/native_handle.c b/libcutils/native_handle.c
index 842e1ed..4089968 100644
--- a/libcutils/native_handle.c
+++ b/libcutils/native_handle.c
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-#define LOG_TAG "Gralloc"
+#define LOG_TAG "NativeHandle"
#include <stdint.h>
#include <errno.h>
@@ -25,30 +25,30 @@
#include <cutils/log.h>
#include <cutils/native_handle.h>
-native_handle* native_handle_create(int numFds, int numInts)
+native_handle_t* native_handle_create(int numFds, int numInts)
{
- native_handle* h = malloc(
- sizeof(native_handle) + sizeof(int)*(numFds+numInts));
-
- h->version = sizeof(native_handle);
+ native_handle_t* h = malloc(
+ sizeof(native_handle_t) + sizeof(int)*(numFds+numInts));
+
+ h->version = sizeof(native_handle_t);
h->numFds = numFds;
h->numInts = numInts;
return h;
}
-int native_handle_delete(native_handle* h)
+int native_handle_delete(native_handle_t* h)
{
if (h) {
- if (h->version != sizeof(native_handle))
+ if (h->version != sizeof(native_handle_t))
return -EINVAL;
free(h);
}
return 0;
}
-int native_handle_close(const native_handle* h)
+int native_handle_close(const native_handle_t* h)
{
- if (h->version != sizeof(native_handle))
+ if (h->version != sizeof(native_handle_t))
return -EINVAL;
const int numFds = h->numFds;
diff --git a/libcutils/tzstrftime.c b/libcutils/tzstrftime.c
index 29c5015..e37d79a 100644
--- a/libcutils/tzstrftime.c
+++ b/libcutils/tzstrftime.c
@@ -172,10 +172,17 @@ label:
pt, ptlim, modifier);
continue;
case 'B':
- pt = _add((t->tm_mon < 0 ||
- t->tm_mon >= MONSPERYEAR) ?
- "?" : Locale->month[t->tm_mon],
- pt, ptlim, modifier);
+ if (modifier == '-') {
+ pt = _add((t->tm_mon < 0 ||
+ t->tm_mon >= MONSPERYEAR) ?
+ "?" : Locale->standalone_month[t->tm_mon],
+ pt, ptlim, modifier);
+ } else {
+ pt = _add((t->tm_mon < 0 ||
+ t->tm_mon >= MONSPERYEAR) ?
+ "?" : Locale->month[t->tm_mon],
+ pt, ptlim, modifier);
+ }
continue;
case 'b':
case 'h':