author | Calin Juravle <calin@google.com> | |
Tue, 4 Mar 2014 14:25:30 +0000 (14:25 +0000) | ||
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | |
Tue, 4 Mar 2014 14:25:30 +0000 (14:25 +0000) |
30 files changed:
diff --git a/libc/Android.mk b/libc/Android.mk
index f3a2ce8b883793747b71d018baa0bd83e95d135f..25de501f549e1b9d6cfd147ed502bbef30830c8e 100644 (file)
--- a/libc/Android.mk
+++ b/libc/Android.mk
stdlib/putenv.c \
stdlib/setenv.c \
stdlib/strtod.c \
- unistd/alarm.c \
unistd/syslog.c \
unistd/time.c \
upstream-netbsd/lib/libc/unistd/killpg.c \
libc_upstream_openbsd_src_files := \
+ upstream-openbsd/lib/libc/gen/alarm.c \
upstream-openbsd/lib/libc/gen/exec.c \
- upstream-openbsd/lib/libc/gen/ftok.c \
upstream-openbsd/lib/libc/gen/fnmatch.c \
- upstream-openbsd/lib/libc/gen/toupper_.c \
+ upstream-openbsd/lib/libc/gen/ftok.c \
+ upstream-openbsd/lib/libc/gen/getprogname.c \
+ upstream-openbsd/lib/libc/gen/setprogname.c \
upstream-openbsd/lib/libc/gen/tolower_.c \
+ upstream-openbsd/lib/libc/gen/toupper_.c \
upstream-openbsd/lib/libc/string/strstr.c \
upstream-openbsd/lib/libc/string/strsep.c \
upstream-openbsd/lib/libc/string/wcslcpy.c \
LOCAL_SRC_FILES := bionic/__stack_chk_fail.cpp
LOCAL_CFLAGS := $(libc_common_cflags) -fno-stack-protector -Werror
-ifeq ($(TARGET_USES_LOGD),yes)
-LOCAL_CFLAGS += -DTARGET_USES_LOGD
-endif
LOCAL_CONLYFLAGS := $(libc_common_conlyflags)
LOCAL_CPPFLAGS := $(libc_common_cppflags)
LOCAL_C_INCLUDES := $(libc_common_c_includes)
# Since this code is experimental it is disabled by default.
LOCAL_CFLAGS += -DPTHREAD_DEBUG_ENABLED=false
+ifeq ($(TARGET_USES_LOGD),true)
+LOCAL_CFLAGS += -DTARGET_USES_LOGD
+endif
+
$(eval $(call patch-up-arch-specific-flags,LOCAL_CFLAGS,libc_common_cflags))
$(eval $(call patch-up-arch-specific-flags,LOCAL_SRC_FILES,libc_bionic_src_files))
include $(BUILD_STATIC_LIBRARY)
diff --git a/libc/SYSCALLS.TXT b/libc/SYSCALLS.TXT
index ee3a05b198aae6a7e0d68cad8607af4c162481de..192816816a2d937d6dce02000ae46058f4c8fe54 100644 (file)
--- a/libc/SYSCALLS.TXT
+++ b/libc/SYSCALLS.TXT
int getsockopt(int, int, int, void*, socklen_t*) arm,arm64,mips,mips64,x86_64
int sendmsg(int, const struct msghdr*, unsigned int) arm,arm64,mips,mips64,x86_64
int recvmsg(int, struct msghdr*, unsigned int) arm,arm64,mips,mips64,x86_64
+int recvmmsg(int, struct mmsghdr*, unsigned int, int, const struct timespec*) arm,arm64,mips,mips64,x86_64
+int sendmmsg(int, struct mmsghdr*, unsigned int, int) arm,arm64,mips,mips64,x86_64
# sockets for x86. These are done as an "indexed" call to socketcall syscall.
int socket:socketcall:1(int, int, int) x86
int getsockopt:socketcall:15(int, int, int, void*, socklen_t*) x86
int sendmsg:socketcall:16(int, const struct msghdr*, unsigned int) x86
int recvmsg:socketcall:17(int, struct msghdr*, unsigned int) x86
+int recvmmsg:socketcall:19(int, struct mmsghdr*, unsigned int, int, const struct timespec*) x86
+int sendmmsg:socketcall:20(int, struct mmsghdr*, unsigned int, int) x86
# scheduler & real-time
int sched_setscheduler(pid_t pid, int policy, const struct sched_param* param) all
diff --git a/libc/arch-arm/syscalls/recvmmsg.S b/libc/arch-arm/syscalls/recvmmsg.S
--- /dev/null
@@ -0,0 +1,22 @@
+/* Generated by gensyscalls.py. Do not edit. */
+
+#include <private/bionic_asm.h>
+
+ENTRY(recvmmsg)
+ mov ip, sp
+ stmfd sp!, {r4, r5, r6, r7}
+ .cfi_def_cfa_offset 16
+ .cfi_rel_offset r4, 0
+ .cfi_rel_offset r5, 4
+ .cfi_rel_offset r6, 8
+ .cfi_rel_offset r7, 12
+ ldmfd ip, {r4, r5, r6}
+ ldr r7, =__NR_recvmmsg
+ swi #0
+ ldmfd sp!, {r4, r5, r6, r7}
+ .cfi_def_cfa_offset 0
+ cmn r0, #(MAX_ERRNO + 1)
+ bxls lr
+ neg r0, r0
+ b __set_errno
+END(recvmmsg)
diff --git a/libc/arch-arm/syscalls/sendmmsg.S b/libc/arch-arm/syscalls/sendmmsg.S
--- /dev/null
@@ -0,0 +1,14 @@
+/* Generated by gensyscalls.py. Do not edit. */
+
+#include <private/bionic_asm.h>
+
+ENTRY(sendmmsg)
+ mov ip, r7
+ ldr r7, =__NR_sendmmsg
+ swi #0
+ mov r7, ip
+ cmn r0, #(MAX_ERRNO + 1)
+ bxls lr
+ neg r0, r0
+ b __set_errno
+END(sendmmsg)
diff --git a/libc/arch-arm64/syscalls/recvmmsg.S b/libc/arch-arm64/syscalls/recvmmsg.S
--- /dev/null
@@ -0,0 +1,21 @@
+/* Generated by gensyscalls.py. Do not edit. */
+
+#include <private/bionic_asm.h>
+
+ENTRY(recvmmsg)
+ stp x29, x30, [sp, #-16]!
+ mov x29, sp
+ str x8, [sp, #-16]!
+
+ mov x8, __NR_recvmmsg
+ svc #0
+
+ ldr x8, [sp], #16
+ ldp x29, x30, [sp], #16
+
+ cmn x0, #(MAX_ERRNO + 1)
+ cneg x0, x0, hi
+ b.hi __set_errno
+
+ ret
+END(recvmmsg)
diff --git a/libc/arch-arm64/syscalls/sendmmsg.S b/libc/arch-arm64/syscalls/sendmmsg.S
--- /dev/null
@@ -0,0 +1,21 @@
+/* Generated by gensyscalls.py. Do not edit. */
+
+#include <private/bionic_asm.h>
+
+ENTRY(sendmmsg)
+ stp x29, x30, [sp, #-16]!
+ mov x29, sp
+ str x8, [sp, #-16]!
+
+ mov x8, __NR_sendmmsg
+ svc #0
+
+ ldr x8, [sp], #16
+ ldp x29, x30, [sp], #16
+
+ cmn x0, #(MAX_ERRNO + 1)
+ cneg x0, x0, hi
+ b.hi __set_errno
+
+ ret
+END(sendmmsg)
diff --git a/libc/arch-mips/syscalls/recvmmsg.S b/libc/arch-mips/syscalls/recvmmsg.S
--- /dev/null
@@ -0,0 +1,19 @@
+/* Generated by gensyscalls.py. Do not edit. */
+
+#include <private/bionic_asm.h>
+
+ENTRY(recvmmsg)
+ .set noreorder
+ .cpload t9
+ li v0, __NR_recvmmsg
+ syscall
+ bnez a3, 1f
+ move a0, v0
+ j ra
+ nop
+1:
+ la t9,__set_errno
+ j t9
+ nop
+ .set reorder
+END(recvmmsg)
diff --git a/libc/arch-mips/syscalls/sendmmsg.S b/libc/arch-mips/syscalls/sendmmsg.S
--- /dev/null
@@ -0,0 +1,19 @@
+/* Generated by gensyscalls.py. Do not edit. */
+
+#include <private/bionic_asm.h>
+
+ENTRY(sendmmsg)
+ .set noreorder
+ .cpload t9
+ li v0, __NR_sendmmsg
+ syscall
+ bnez a3, 1f
+ move a0, v0
+ j ra
+ nop
+1:
+ la t9,__set_errno
+ j t9
+ nop
+ .set reorder
+END(sendmmsg)
diff --git a/libc/arch-mips64/syscalls/recvmmsg.S b/libc/arch-mips64/syscalls/recvmmsg.S
--- /dev/null
@@ -0,0 +1,25 @@
+/* Generated by gensyscalls.py. Do not edit. */
+
+#include <private/bionic_asm.h>
+
+ENTRY(recvmmsg)
+ .set push
+ .set noreorder
+ li v0, __NR_recvmmsg
+ syscall
+ bnez a3, 1f
+ move a0, v0
+ j ra
+ nop
+1:
+ move t0, ra
+ bal 2f
+ nop
+2:
+ .cpsetup ra, t1, 2b
+ LA t9,__set_errno
+ .cpreturn
+ j t9
+ move ra, t0
+ .set pop
+END(recvmmsg)
diff --git a/libc/arch-mips64/syscalls/sendmmsg.S b/libc/arch-mips64/syscalls/sendmmsg.S
--- /dev/null
@@ -0,0 +1,25 @@
+/* Generated by gensyscalls.py. Do not edit. */
+
+#include <private/bionic_asm.h>
+
+ENTRY(sendmmsg)
+ .set push
+ .set noreorder
+ li v0, __NR_sendmmsg
+ syscall
+ bnez a3, 1f
+ move a0, v0
+ j ra
+ nop
+1:
+ move t0, ra
+ bal 2f
+ nop
+2:
+ .cpsetup ra, t1, 2b
+ LA t9,__set_errno
+ .cpreturn
+ j t9
+ move ra, t0
+ .set pop
+END(sendmmsg)
diff --git a/libc/arch-x86/syscalls/recvmmsg.S b/libc/arch-x86/syscalls/recvmmsg.S
--- /dev/null
@@ -0,0 +1,27 @@
+/* Generated by gensyscalls.py. Do not edit. */
+
+#include <private/bionic_asm.h>
+
+ENTRY(recvmmsg)
+ pushl %ebx
+ pushl %ecx
+ .cfi_def_cfa_offset 8
+ .cfi_rel_offset ebx, 0
+ .cfi_rel_offset ecx, 4
+ mov $19, %ebx
+ mov %esp, %ecx
+ addl $12, %ecx
+ movl $__NR_socketcall, %eax
+ int $0x80
+ cmpl $-MAX_ERRNO, %eax
+ jb 1f
+ negl %eax
+ pushl %eax
+ call __set_errno
+ addl $4, %esp
+ orl $-1, %eax
+1:
+ popl %ecx
+ popl %ebx
+ ret
+END(recvmmsg)
diff --git a/libc/arch-x86/syscalls/sendmmsg.S b/libc/arch-x86/syscalls/sendmmsg.S
--- /dev/null
@@ -0,0 +1,27 @@
+/* Generated by gensyscalls.py. Do not edit. */
+
+#include <private/bionic_asm.h>
+
+ENTRY(sendmmsg)
+ pushl %ebx
+ pushl %ecx
+ .cfi_def_cfa_offset 8
+ .cfi_rel_offset ebx, 0
+ .cfi_rel_offset ecx, 4
+ mov $20, %ebx
+ mov %esp, %ecx
+ addl $12, %ecx
+ movl $__NR_socketcall, %eax
+ int $0x80
+ cmpl $-MAX_ERRNO, %eax
+ jb 1f
+ negl %eax
+ pushl %eax
+ call __set_errno
+ addl $4, %esp
+ orl $-1, %eax
+1:
+ popl %ecx
+ popl %ebx
+ ret
+END(sendmmsg)
diff --git a/libc/arch-x86_64/syscalls/recvmmsg.S b/libc/arch-x86_64/syscalls/recvmmsg.S
--- /dev/null
@@ -0,0 +1,17 @@
+/* Generated by gensyscalls.py. Do not edit. */
+
+#include <private/bionic_asm.h>
+
+ENTRY(recvmmsg)
+ movq %rcx, %r10
+ movl $__NR_recvmmsg, %eax
+ syscall
+ cmpq $-MAX_ERRNO, %rax
+ jb 1f
+ negl %eax
+ movl %eax, %edi
+ call __set_errno
+ orq $-1, %rax
+1:
+ ret
+END(recvmmsg)
diff --git a/libc/arch-x86_64/syscalls/sendmmsg.S b/libc/arch-x86_64/syscalls/sendmmsg.S
--- /dev/null
@@ -0,0 +1,17 @@
+/* Generated by gensyscalls.py. Do not edit. */
+
+#include <private/bionic_asm.h>
+
+ENTRY(sendmmsg)
+ movq %rcx, %r10
+ movl $__NR_sendmmsg, %eax
+ syscall
+ cmpq $-MAX_ERRNO, %rax
+ jb 1f
+ negl %eax
+ movl %eax, %edi
+ call __set_errno
+ orq $-1, %rax
+1:
+ ret
+END(sendmmsg)
diff --git a/libc/bionic/mmap.cpp b/libc/bionic/mmap.cpp
index 28a47cc9d2c1fa17fd5ca4af5b3d4ec6be9a5eff..8f25a89410ce7fb99d23503916e2306138e2cea2 100644 (file)
--- a/libc/bionic/mmap.cpp
+++ b/libc/bionic/mmap.cpp
#define MMAP2_SHIFT 12 // 2**12 == 4096
+static bool kernel_has_MADV_MERGEABLE = true;
+
void* mmap64(void* addr, size_t size, int prot, int flags, int fd, off64_t offset) {
if (offset < 0 || (offset & ((1UL << MMAP2_SHIFT)-1)) != 0) {
errno = EINVAL;
return MAP_FAILED;
}
+ bool is_private_anonymous = (flags & (MAP_PRIVATE | MAP_ANONYMOUS)) != 0;
void* result = __mmap2(addr, size, prot, flags, fd, offset >> MMAP2_SHIFT);
- if (result != MAP_FAILED && (flags & (MAP_PRIVATE | MAP_ANONYMOUS)) != 0) {
+
+ if (result != MAP_FAILED && kernel_has_MADV_MERGEABLE && is_private_anonymous) {
ErrnoRestorer errno_restorer;
- madvise(result, size, MADV_MERGEABLE);
+ int rc = madvise(result, size, MADV_MERGEABLE);
+ if (rc == -1 && errno == EINVAL) {
+ kernel_has_MADV_MERGEABLE = false;
+ }
}
return result;
index 4583cef9d99f2e6dd771e2d4f65498324f524a15..e67afbafb01430f9f0909560d8a3cad8da26410a 100644 (file)
#include <limits.h>
#include <sys/atomics.h>
#include <sys/mman.h>
+#include <time.h>
#include <unistd.h>
#include "pthread_internal.h"
#include "private/bionic_tls.h"
#include "private/thread_private.h"
+// We use one bit in pthread_condattr_t (long) values as the 'shared' flag
+// and one bit for the clock type (CLOCK_REALTIME is ((clockid_t) 1), and
+// CLOCK_MONOTONIC is ((clockid_t) 0).). The rest of the bits are a counter.
+//
+// The 'value' field pthread_cond_t has the same layout.
+
+#define COND_SHARED_MASK 0x0001
+#define COND_CLOCK_MASK 0x0002
+#define COND_COUNTER_STEP 0x0004
+#define COND_FLAGS_MASK (COND_SHARED_MASK | COND_CLOCK_MASK)
+#define COND_COUNTER_MASK (~COND_FLAGS_MASK)
+
+#define COND_IS_SHARED(c) (((c) & COND_SHARED_MASK) != 0)
+#define COND_GET_CLOCK(c) (((c) & COND_CLOCK_MASK) >> 1)
+#define COND_SET_CLOCK(attr, c) ((attr) | (c << 1))
+
+
int pthread_condattr_init(pthread_condattr_t* attr) {
- if (attr == NULL) {
- return EINVAL;
- }
- *attr = PTHREAD_PROCESS_PRIVATE;
+ *attr = 0;
+ *attr |= PTHREAD_PROCESS_PRIVATE;
+ *attr |= (CLOCK_REALTIME << 1);
return 0;
}
int pthread_condattr_getpshared(const pthread_condattr_t* attr, int* pshared) {
- if (attr == NULL || pshared == NULL) {
- return EINVAL;
- }
- *pshared = *attr;
+ *pshared = static_cast<int>(COND_IS_SHARED(*attr));
return 0;
}
int pthread_condattr_setpshared(pthread_condattr_t* attr, int pshared) {
- if (attr == NULL) {
+ if (pshared != PTHREAD_PROCESS_SHARED && pshared != PTHREAD_PROCESS_PRIVATE) {
return EINVAL;
}
- if (pshared != PTHREAD_PROCESS_SHARED && pshared != PTHREAD_PROCESS_PRIVATE) {
+
+ *attr |= pshared;
+ return 0;
+}
+
+int pthread_condattr_getclock(const pthread_condattr_t* attr, clockid_t* clock) {
+ *clock = COND_GET_CLOCK(*attr);
+ return 0;
+}
+
+int pthread_condattr_setclock(pthread_condattr_t* attr, clockid_t clock) {
+ if (clock != CLOCK_MONOTONIC && clock != CLOCK_REALTIME) {
return EINVAL;
}
- *attr = pshared;
+
+ *attr = COND_SET_CLOCK(*attr, clock);
return 0;
}
return 0;
}
-// We use one bit in condition variable values as the 'shared' flag
-// The rest is a counter.
-#define COND_SHARED_MASK 0x0001
-#define COND_COUNTER_INCREMENT 0x0002
-#define COND_COUNTER_MASK (~COND_SHARED_MASK)
-
-#define COND_IS_SHARED(c) (((c)->value & COND_SHARED_MASK) != 0)
// XXX *technically* there is a race condition that could allow
// XXX a signal to be missed. If thread A is preempted in _wait()
return EINVAL;
}
- cond->value = 0;
-
- if (attr != NULL && *attr == PTHREAD_PROCESS_SHARED) {
- cond->value |= COND_SHARED_MASK;
+ if (attr != NULL) {
+ cond->value = (*attr & COND_FLAGS_MASK);
+ } else {
+ cond->value = 0;
}
return 0;
return EINVAL;
}
- long flags = (cond->value & ~COND_COUNTER_MASK);
+ int flags = (cond->value & COND_FLAGS_MASK);
while (true) {
- long old_value = cond->value;
- long new_value = ((old_value - COND_COUNTER_INCREMENT) & COND_COUNTER_MASK) | flags;
+ int old_value = cond->value;
+ int new_value = ((old_value - COND_COUNTER_STEP) & COND_COUNTER_MASK) | flags;
if (__bionic_cmpxchg(old_value, new_value, &cond->value) == 0) {
break;
}
// hold the mutex, they're subject to race conditions anyway.
ANDROID_MEMBAR_FULL();
- __futex_wake_ex(&cond->value, COND_IS_SHARED(cond), counter);
+ __futex_wake_ex(&cond->value, COND_IS_SHARED(cond->value), counter);
return 0;
}
@@ -151,7 +170,7 @@ int __pthread_cond_timedwait_relative(pthread_cond_t* cond, pthread_mutex_t* mut
int old_value = cond->value;
pthread_mutex_unlock(mutex);
- int status = __futex_wait_ex(&cond->value, COND_IS_SHARED(cond), old_value, reltime);
+ int status = __futex_wait_ex(&cond->value, COND_IS_SHARED(cond->value), old_value, reltime);
pthread_mutex_lock(mutex);
if (status == -ETIMEDOUT) {
}
int pthread_cond_wait(pthread_cond_t* cond, pthread_mutex_t* mutex) {
- return __pthread_cond_timedwait(cond, mutex, NULL, CLOCK_REALTIME);
+ return __pthread_cond_timedwait(cond, mutex, NULL, COND_GET_CLOCK(cond->value));
}
int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t * mutex, const timespec *abstime) {
- return __pthread_cond_timedwait(cond, mutex, abstime, CLOCK_REALTIME);
+ return __pthread_cond_timedwait(cond, mutex, abstime, COND_GET_CLOCK(cond->value));
}
-// TODO: this exists only for backward binary compatibility.
-int pthread_cond_timedwait_monotonic(pthread_cond_t* cond, pthread_mutex_t* mutex, const timespec* abstime) {
+#if !defined(__LP64__)
+// TODO: this exists only for backward binary compatibility on 32 bit platforms.
+extern "C" int pthread_cond_timedwait_monotonic(pthread_cond_t* cond, pthread_mutex_t* mutex, const timespec* abstime) {
return __pthread_cond_timedwait(cond, mutex, abstime, CLOCK_MONOTONIC);
}
-int pthread_cond_timedwait_monotonic_np(pthread_cond_t* cond, pthread_mutex_t* mutex, const timespec* abstime) {
+extern "C" int pthread_cond_timedwait_monotonic_np(pthread_cond_t* cond, pthread_mutex_t* mutex, const timespec* abstime) {
return __pthread_cond_timedwait(cond, mutex, abstime, CLOCK_MONOTONIC);
}
+#endif // !defined(__LP64__)
int pthread_cond_timedwait_relative_np(pthread_cond_t* cond, pthread_mutex_t* mutex, const timespec* reltime) {
return __pthread_cond_timedwait_relative(cond, mutex, reltime);
diff --git a/libc/include/pthread.h b/libc/include/pthread.h
index c5380be9d8ee5b891876d83295d55c0896436fd9..6330a6f9d5791723a26601e8bbf398dd057629ae 100644 (file)
--- a/libc/include/pthread.h
+++ b/libc/include/pthread.h
@@ -127,11 +127,13 @@ int pthread_attr_setschedparam(pthread_attr_t*, const struct sched_param*) __non
int pthread_attr_setschedpolicy(pthread_attr_t*, int) __nonnull((1));
int pthread_attr_setscope(pthread_attr_t*, int) __nonnull((1));
int pthread_attr_setstack(pthread_attr_t*, void*, size_t) __nonnull((1));
-int pthread_attr_setstacksize(pthread_attr_t * attr, size_t stack_size) __nonnull((1));
+int pthread_attr_setstacksize(pthread_attr_t*, size_t stack_size) __nonnull((1));
int pthread_condattr_destroy(pthread_condattr_t*) __nonnull((1));
+int pthread_condattr_getclock(const pthread_condattr_t*, clockid_t*) __nonnull((1, 2));
int pthread_condattr_getpshared(const pthread_condattr_t*, int*) __nonnull((1, 2));
int pthread_condattr_init(pthread_condattr_t*) __nonnull((1));
+int pthread_condattr_setclock(pthread_condattr_t*, clockid_t) __nonnull((1));
int pthread_condattr_setpshared(pthread_condattr_t*, int) __nonnull((1));
int pthread_cond_broadcast(pthread_cond_t*) __nonnull((1));
int pthread_attr_getstackaddr(const pthread_attr_t*, void**) __nonnull((1, 2)); /* deprecated */
int pthread_attr_setstackaddr(pthread_attr_t*, void*) __nonnull((1)); /* deprecated */
-/* Bionic additions that are deprecated even in the 32-bit ABI. */
+// Bionic additions that are deprecated even in the 32-bit ABI.
+//
+// TODO: Remove them once chromium_org / NFC have switched over.
int pthread_cond_timedwait_monotonic_np(pthread_cond_t*, pthread_mutex_t*, const struct timespec*);
int pthread_cond_timedwait_monotonic(pthread_cond_t*, pthread_mutex_t*, const struct timespec*);
#define HAVE_PTHREAD_COND_TIMEDWAIT_MONOTONIC 1
diff --git a/libc/include/stdlib.h b/libc/include/stdlib.h
index 9c04059b32c8ec0127a566134976fc985f6d1e45..9595170a30d63752973758ae436a8e8eca21bc3f 100644 (file)
--- a/libc/include/stdlib.h
+++ b/libc/include/stdlib.h
extern lldiv_t lldiv(long long, long long);
+/* BSD compatibility. */
+extern const char* getprogname(void);
+extern void setprogname(const char*);
+
#if 1 /* MISSING FROM BIONIC - ENABLED FOR STLPort and libstdc++-v3 */
/* make STLPort happy */
extern int mblen(const char *, size_t);
index 02851d290972af2f5de5e6a675cc6b258d4b9d74..acfaa206982e6d9642ff6882491b02f4c2cbf8ad 100644 (file)
--- a/libc/include/sys/klog.h
+++ b/libc/include/sys/klog.h
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
+
#ifndef _SYS_KLOG_H_
#define _SYS_KLOG_H_
#define KLOG_SIZE_UNREAD 9
#define KLOG_SIZE_BUFFER 10
-/* These are deprecated names that were used in earlier bionic releases. Do not use. */
-#define KLOG_DISABLE 6
-#define KLOG_ENABLE 7
-#define KLOG_SETLEVEL 8
-#define KLOG_UNREADSIZE 9
-#define KLOG_WRITE 10
-
extern int klogctl(int, char *, int);
__END_DECLS
index 5eb7e3d90be2774da0fcde20c3e939ccfdddc5d3..db6902a9ff0300c73f76a3b4863403a9a503357b 100644 (file)
#define sockaddr_storage __kernel_sockaddr_storage
typedef unsigned short sa_family_t;
+struct timespec;
+
#ifdef __mips__
#define SOCK_DGRAM 1
#define SOCK_STREAM 2
};
struct sockaddr {
- sa_family_t sa_family;
- char sa_data[14];
+ sa_family_t sa_family;
+ char sa_data[14];
};
struct linger {
- int l_onoff;
- int l_linger;
+ int l_onoff;
+ int l_linger;
};
struct msghdr {
- void * msg_name;
- int msg_namelen;
- struct iovec * msg_iov;
- __kernel_size_t msg_iovlen;
- void * msg_control;
- __kernel_size_t msg_controllen;
- unsigned msg_flags;
+ void* msg_name;
+ socklen_t msg_namelen;
+ struct iovec* msg_iov;
+ size_t msg_iovlen;
+ void* msg_control;
+ size_t msg_controllen;
+ int msg_flags;
+};
+
+struct mmsghdr {
+ struct msghdr msg_hdr;
+ unsigned int msg_len;
};
struct cmsghdr {
- __kernel_size_t cmsg_len;
- int cmsg_level;
- int cmsg_type;
+ size_t cmsg_len;
+ int cmsg_level;
+ int cmsg_type;
};
#define __CMSG_NXTHDR(ctl, len, cmsg) __cmsg_nxthdr((ctl),(len),(cmsg))
#define CMSG_NXTHDR(mhdr, cmsg) cmsg_nxthdr((mhdr), (cmsg))
#define CMSG_ALIGN(len) ( ((len)+sizeof(long)-1) & ~(sizeof(long)-1) )
-#define CMSG_DATA(cmsg) ((void *)((char *)(cmsg) + CMSG_ALIGN(sizeof(struct cmsghdr))))
+#define CMSG_DATA(cmsg) ((void*)((char*)(cmsg) + CMSG_ALIGN(sizeof(struct cmsghdr))))
#define CMSG_SPACE(len) (CMSG_ALIGN(sizeof(struct cmsghdr)) + CMSG_ALIGN(len))
#define CMSG_LEN(len) (CMSG_ALIGN(sizeof(struct cmsghdr)) + (len))
-#define __CMSG_FIRSTHDR(ctl,len) ((len) >= sizeof(struct cmsghdr) ? (struct cmsghdr *)(ctl) : (struct cmsghdr *)NULL)
+#define __CMSG_FIRSTHDR(ctl,len) ((len) >= sizeof(struct cmsghdr) ? (struct cmsghdr*)(ctl) : (struct cmsghdr*)NULL)
#define CMSG_FIRSTHDR(msg) __CMSG_FIRSTHDR((msg)->msg_control, (msg)->msg_controllen)
-#define CMSG_OK(mhdr, cmsg) ((cmsg)->cmsg_len >= sizeof(struct cmsghdr) && (cmsg)->cmsg_len <= (unsigned long) ((mhdr)->msg_controllen - ((char *)(cmsg) - (char *)(mhdr)->msg_control)))
+#define CMSG_OK(mhdr, cmsg) ((cmsg)->cmsg_len >= sizeof(struct cmsghdr) && (cmsg)->cmsg_len <= (unsigned long) ((mhdr)->msg_controllen - ((char*)(cmsg) - (char*)(mhdr)->msg_control)))
#ifdef __GNUC__
#define __KINLINE static __inline__
#define __KINLINE static
#endif
-__KINLINE struct cmsghdr * __cmsg_nxthdr(void *__ctl, __kernel_size_t __size, struct cmsghdr *__cmsg) {
- struct cmsghdr * __ptr;
- __ptr = (struct cmsghdr*)(((unsigned char *) __cmsg) + CMSG_ALIGN(__cmsg->cmsg_len));
- if ((unsigned long)((char*)(__ptr+1) - (char *) __ctl) > __size)
- return (struct cmsghdr *)0;
- return __ptr;
+__KINLINE struct cmsghdr* __cmsg_nxthdr(void* __ctl, size_t __size, struct cmsghdr* __cmsg) {
+ struct cmsghdr* __ptr;
+ __ptr = (struct cmsghdr*)(((unsigned char*) __cmsg) + CMSG_ALIGN(__cmsg->cmsg_len));
+ if ((unsigned long)((char*)(__ptr+1) - (char*) __ctl) > __size) {
+ return NULL;
+ }
+ return __ptr;
}
-__KINLINE struct cmsghdr * cmsg_nxthdr (struct msghdr *__msg, struct cmsghdr *__cmsg) {
- return __cmsg_nxthdr(__msg->msg_control, __msg->msg_controllen, __cmsg);
+__KINLINE struct cmsghdr* cmsg_nxthdr (struct msghdr* __msg, struct cmsghdr* __cmsg) {
+ return __cmsg_nxthdr(__msg->msg_control, __msg->msg_controllen, __cmsg);
}
#define SCM_RIGHTS 0x01
@@ -135,9 +143,9 @@ __KINLINE struct cmsghdr * cmsg_nxthdr (struct msghdr *__msg, struct cmsghdr *__
#define SCM_SECURITY 0x03
struct ucred {
- __u32 pid;
- __u32 uid;
- __u32 gid;
+ pid_t pid;
+ uid_t uid;
+ gid_t gid;
};
#define AF_UNSPEC 0
#define MSG_ERRQUEUE 0x2000
#define MSG_NOSIGNAL 0x4000
#define MSG_MORE 0x8000
+#define MSG_WAITFORONE 0x10000
+#define MSG_FASTOPEN 0x20000000
+#define MSG_CMSG_CLOEXEC 0x40000000
#define MSG_EOF MSG_FIN
#define MSG_CMSG_COMPAT 0
# define __socketcall extern
#endif
-__socketcall int socket(int, int, int);
-__socketcall int bind(int, const struct sockaddr *, int);
-__socketcall int connect(int, const struct sockaddr *, socklen_t);
+__socketcall int accept(int, struct sockaddr*, socklen_t*);
+__socketcall int bind(int, const struct sockaddr*, int);
+__socketcall int connect(int, const struct sockaddr*, socklen_t);
+__socketcall int getpeername(int, struct sockaddr*, socklen_t*);
+__socketcall int getsockname(int, struct sockaddr*, socklen_t*);
+__socketcall int getsockopt(int, int, int, void*, socklen_t*);
__socketcall int listen(int, int);
-__socketcall int accept(int, struct sockaddr *, socklen_t *);
-__socketcall int getsockname(int, struct sockaddr *, socklen_t *);
-__socketcall int getpeername(int, struct sockaddr *, socklen_t *);
-__socketcall int socketpair(int, int, int, int *);
+__socketcall int recvmmsg(int, struct mmsghdr*, unsigned int, int, const struct timespec*);
+__socketcall int recvmsg(int, struct msghdr*, unsigned int);
+__socketcall int sendmmsg(int, const struct mmsghdr*, unsigned int, int);
+__socketcall int sendmsg(int, const struct msghdr*, unsigned int);
+__socketcall int setsockopt(int, int, int, const void*, socklen_t);
__socketcall int shutdown(int, int);
-__socketcall int setsockopt(int, int, int, const void *, socklen_t);
-__socketcall int getsockopt(int, int, int, void *, socklen_t *);
-__socketcall int sendmsg(int, const struct msghdr *, unsigned int);
-__socketcall int recvmsg(int, struct msghdr *, unsigned int);
+__socketcall int socket(int, int, int);
+__socketcall int socketpair(int, int, int, int*);
-extern ssize_t send(int, const void *, size_t, unsigned int);
-extern ssize_t recv(int, void *, size_t, unsigned int);
+extern ssize_t send(int, const void*, size_t, unsigned int);
+extern ssize_t recv(int, void*, size_t, unsigned int);
-__socketcall ssize_t sendto(int, const void *, size_t, int, const struct sockaddr *, socklen_t);
-__socketcall ssize_t recvfrom(int, void *, size_t, unsigned int, const struct sockaddr *, socklen_t *);
+__socketcall ssize_t sendto(int, const void*, size_t, int, const struct sockaddr*, socklen_t);
+__socketcall ssize_t recvfrom(int, void*, size_t, unsigned int, const struct sockaddr*, socklen_t*);
#if defined(__BIONIC_FORTIFY)
__errordecl(__recvfrom_error, "recvfrom called with size bigger than buffer");
-extern ssize_t __recvfrom_chk(int, void*, size_t, size_t, unsigned int, const struct sockaddr*, socklen_t *);
-extern ssize_t __recvfrom_real(int, void *, size_t, unsigned int, const struct sockaddr*, socklen_t*)
+extern ssize_t __recvfrom_chk(int, void*, size_t, size_t, unsigned int, const struct sockaddr*, socklen_t*);
+extern ssize_t __recvfrom_real(int, void*, size_t, unsigned int, const struct sockaddr*, socklen_t*)
__asm__(__USER_LABEL_PREFIX__ "recvfrom");
__BIONIC_FORTIFY_INLINE
@@ -324,7 +337,7 @@ ssize_t recvfrom(int fd, void* buf, size_t len, unsigned int flags, const struct
}
__BIONIC_FORTIFY_INLINE
-ssize_t recv(int socket, void *buf, size_t buflen, unsigned int flags) {
+ssize_t recv(int socket, void* buf, size_t buflen, unsigned int flags) {
return recvfrom(socket, buf, buflen, flags, NULL, 0);
}
index 202f031afcb79cd29d38dc9f24d391b622c5b315..6e7eaa9ea89ae3687071755120f40cad75e58a99 100644 (file)
--- a/libc/tzcode/localtime.c
+++ b/libc/tzcode/localtime.c
#define WILDABBR " "
#endif /* !defined WILDABBR */
-static char wildabbr[] = WILDABBR;
+static char wildabbr[] = WILDABBR;
-static const char gmt[] = "GMT";
+static const char gmt[] = "GMT";
/*
** The DST rules to use if TZ has no rules and we can't load TZDEFRULES.
#define TZDEFRULESTRING ",M4.1.0,M10.5.0"
#endif /* !defined TZDEFDST */
-struct ttinfo { /* time type information */
+struct ttinfo { /* time type information */
int_fast32_t tt_gmtoff; /* UT offset in seconds */
int tt_isdst; /* used to set tm_isdst */
int tt_abbrind; /* abbreviation list index */
int tt_ttisgmt; /* TRUE if transition is UT */
};
-struct lsinfo { /* leap second information */
+struct lsinfo { /* leap second information */
time_t ls_trans; /* transition time */
int_fast64_t ls_corr; /* correction to apply */
};
#endif /* !defined TZNAME_MAX */
struct state {
- int leapcnt;
- int timecnt;
- int typecnt;
- int charcnt;
- int goback;
- int goahead;
- time_t ats[TZ_MAX_TIMES];
- unsigned char types[TZ_MAX_TIMES];
- struct ttinfo ttis[TZ_MAX_TYPES];
- char chars[BIGGEST(BIGGEST(TZ_MAX_CHARS + 1, sizeof gmt),
- (2 * (MY_TZNAME_MAX + 1)))];
- struct lsinfo lsis[TZ_MAX_LEAPS];
- int defaulttype; /* for early times or if no transitions */
+ int leapcnt;
+ int timecnt;
+ int typecnt;
+ int charcnt;
+ int goback;
+ int goahead;
+ time_t ats[TZ_MAX_TIMES];
+ unsigned char types[TZ_MAX_TIMES];
+ struct ttinfo ttis[TZ_MAX_TYPES];
+ char chars[BIGGEST(BIGGEST(TZ_MAX_CHARS + 1, sizeof gmt),
+ (2 * (MY_TZNAME_MAX + 1)))];
+ struct lsinfo lsis[TZ_MAX_LEAPS];
+ int defaulttype; /* for early times or if no transitions */
};
struct rule {
- int r_type; /* type of rule--see below */
- int r_day; /* day number of rule */
- int r_week; /* week number of rule */
- int r_mon; /* month number of rule */
- int_fast32_t r_time; /* transition time of rule */
+ int r_type; /* type of rule--see below */
+ int r_day; /* day number of rule */
+ int r_week; /* week number of rule */
+ int r_mon; /* month number of rule */
+ int_fast32_t r_time; /* transition time of rule */
};
-#define JULIAN_DAY 0 /* Jn - Julian day */
-#define DAY_OF_YEAR 1 /* n - day of year */
-#define MONTH_NTH_DAY_OF_WEEK 2 /* Mm.n.d - month, week, day of week */
+#define JULIAN_DAY 0 /* Jn - Julian day */
+#define DAY_OF_YEAR 1 /* n - day of year */
+#define MONTH_NTH_DAY_OF_WEEK 2 /* Mm.n.d - month, week, day of week */
/*
** Prototypes for static functions.
static int __bionic_open_tzdata(const char*, int*);
static int_fast32_t detzcode(const char * codep);
-static time_t detzcode64(const char * codep);
+static int_fast64_t detzcode64(const char * codep);
static int differ_by_repeat(time_t t1, time_t t0);
static const char * getzname(const char * strp) ATTRIBUTE_PURE;
static const char * getqzname(const char * strp, const int delim)
static int increment_overflow(int * number, int delta);
static int leaps_thru_end_of(int y) ATTRIBUTE_PURE;
static int increment_overflow32(int_fast32_t * number, int delta);
+static int increment_overflow_time(time_t *t, int_fast32_t delta);
static int normalize_overflow32(int_fast32_t * tensptr,
int * unitsptr, int base);
static int normalize_overflow(int * tensptr, int * unitsptr,
const struct state * sp, struct tm * tmp);
static int tmcomp(const struct tm * atmp,
const struct tm * btmp);
-static time_t transtime(time_t janfirst, int year,
- const struct rule * rulep, int_fast32_t offset)
+static int_fast32_t transtime(int year, const struct rule * rulep,
+ int_fast32_t offset)
ATTRIBUTE_PURE;
-static int typesequiv(const struct state * sp, int a, int b);
+static int typesequiv(const struct state * sp, int a, int b);
static int tzload(const char * name, struct state * sp,
int doextend);
static int tzparse(const char * name, struct state * sp,
int lastditch);
#ifdef ALL_STATE
-static struct state * lclptr;
-static struct state * gmtptr;
+static struct state * lclptr;
+static struct state * gmtptr;
#endif /* defined ALL_STATE */
#ifndef ALL_STATE
#define TZ_STRLEN_MAX 255
#endif /* !defined TZ_STRLEN_MAX */
-static char lcl_TZname[TZ_STRLEN_MAX + 1];
-static int lcl_is_set;
-static int gmt_is_set;
+static char lcl_TZname[TZ_STRLEN_MAX + 1];
+static int lcl_is_set;
+static int gmt_is_set;
-char * tzname[2] = {
+char * tzname[2] = {
wildabbr,
wildabbr
};
static struct tm tmGlobal;
#ifdef USG_COMPAT
-long timezone = 0;
-int daylight = 0;
+long timezone = 0;
+int daylight = 0;
#endif /* defined USG_COMPAT */
#ifdef ALTZONE
-long altzone = 0;
+long altzone = 0;
#endif /* defined ALTZONE */
static int_fast32_t
detzcode(const char *const codep)
{
- register int_fast32_t result;
- register int i;
+ register int_fast32_t result;
+ register int i;
- result = (codep[0] & 0x80) ? -1 : 0;
- for (i = 0; i < 4; ++i)
- result = (result << 8) | (codep[i] & 0xff);
- return result;
+ result = (codep[0] & 0x80) ? -1 : 0;
+ for (i = 0; i < 4; ++i)
+ result = (result << 8) | (codep[i] & 0xff);
+ return result;
}
-static time_t
+static int_fast64_t
detzcode64(const char *const codep)
{
- register time_t result;
- register int i;
+ register int_fast64_t result;
+ register int i;
- result = (codep[0] & 0x80) ? (~(int_fast64_t) 0) : 0;
- for (i = 0; i < 8; ++i)
- result = result * 256 + (codep[i] & 0xff);
- return result;
+ result = (codep[0] & 0x80) ? -1 : 0;
+ for (i = 0; i < 8; ++i)
+ result = (result << 8) | (codep[i] & 0xff);
+ return result;
}
static void
settzname(void)
{
- register struct state * const sp = lclptr;
- register int i;
+ register struct state * const sp = lclptr;
+ register int i;
tzname[0] = wildabbr;
tzname[1] = wildabbr;
static int
differ_by_repeat(const time_t t1, const time_t t0)
{
- if (TYPE_BIT(time_t) - TYPE_SIGNED(time_t) < SECSPERREPEAT_BITS)
- return 0;
+ if (TYPE_BIT(time_t) - TYPE_SIGNED(time_t) < SECSPERREPEAT_BITS)
+ return 0;
#if __LP64__ // 32-bit Android only has a signed 32-bit time_t; 64-bit Android is fixed.
- return t1 - t0 == SECSPERREPEAT;
+ return t1 - t0 == SECSPERREPEAT;
#endif
}
tzload(register const char* name, register struct state* const sp,
register const int doextend)
{
- register const char * p;
- register int i;
- register int fid;
- register int stored;
- register int nread;
+ register const char * p;
+ register int i;
+ register int fid;
+ register int stored;
+ register int nread;
typedef union {
- struct tzhead tzhead;
- char buf[2 * sizeof(struct tzhead) +
- 2 * sizeof *sp +
- 4 * TZ_MAX_TIMES];
+ struct tzhead tzhead;
+ char buf[2 * sizeof(struct tzhead) +
+ 2 * sizeof *sp +
+ 4 * TZ_MAX_TIMES];
} u_t;
#ifdef ALL_STATE
- register u_t * up;
+ register u_t * up;
up = (u_t *) calloc(1, sizeof *up);
if (up == NULL)
return -1;
#else /* !defined ALL_STATE */
- u_t u;
- register u_t * const up = &u;
+ u_t u;
+ register u_t * const up = &u;
#endif /* !defined ALL_STATE */
sp->goback = sp->goahead = FALSE;
if (close(fid) < 0 || nread <= 0)
goto oops;
for (stored = 4; stored <= 8; stored *= 2) {
- int ttisstdcnt;
- int ttisgmtcnt;
+ int ttisstdcnt;
+ int ttisgmtcnt;
+ int timecnt;
ttisstdcnt = (int) detzcode(up->tzhead.tzh_ttisstdcnt);
ttisgmtcnt = (int) detzcode(up->tzhead.tzh_ttisgmtcnt);
(ttisgmtcnt != sp->typecnt && ttisgmtcnt != 0))
goto oops;
if (nread - (p - up->buf) <
- sp->timecnt * stored + /* ats */
- sp->timecnt + /* types */
- sp->typecnt * 6 + /* ttinfos */
- sp->charcnt + /* chars */
- sp->leapcnt * (stored + 4) + /* lsinfos */
- ttisstdcnt + /* ttisstds */
- ttisgmtcnt) /* ttisgmts */
+ sp->timecnt * stored + /* ats */
+ sp->timecnt + /* types */
+ sp->typecnt * 6 + /* ttinfos */
+ sp->charcnt + /* chars */
+ sp->leapcnt * (stored + 4) + /* lsinfos */
+ ttisstdcnt + /* ttisstds */
+ ttisgmtcnt) /* ttisgmts */
goto oops;
+ timecnt = 0;
for (i = 0; i < sp->timecnt; ++i) {
- sp->ats[i] = (stored == 4) ?
- detzcode(p) : detzcode64(p);
+ int_fast64_t at
+ = stored == 4 ? detzcode(p) : detzcode64(p);
+ sp->types[i] = ((TYPE_SIGNED(time_t)
+ ? time_t_min <= at
+ : 0 <= at)
+ && at <= time_t_max);
+ if (sp->types[i]) {
+ if (i && !timecnt && at != time_t_min) {
+ /*
+ ** Keep the earlier record, but tweak
+ ** it so that it starts with the
+ ** minimum time_t value.
+ */
+ sp->types[i - 1] = 1;
+ sp->ats[timecnt++] = time_t_min;
+ }
+ sp->ats[timecnt++] = at;
+ }
p += stored;
}
+ timecnt = 0;
for (i = 0; i < sp->timecnt; ++i) {
- sp->types[i] = (unsigned char) *p++;
- if (sp->types[i] >= sp->typecnt)
+ unsigned char typ = *p++;
+ if (sp->typecnt <= typ)
goto oops;
+ if (sp->types[i])
+ sp->types[timecnt++] = typ;
}
+ sp->timecnt = timecnt;
for (i = 0; i < sp->typecnt; ++i) {
register struct ttinfo * ttisp;
}
}
/*
- ** Out-of-sort ats should mean we're running on a
- ** signed time_t system but using a data file with
- ** unsigned values (or vice versa).
- */
- for (i = 0; i < sp->timecnt; ++i)
- if ((i < sp->timecnt - 1 &&
- sp->ats[i] > sp->ats[i + 1]) ||
- (i == sp->timecnt - 1 && !TYPE_SIGNED(time_t) &&
- sp->ats[i] >
- ((stored == 4) ? INT32_MAX : INT64_MAX))) {
- if (TYPE_SIGNED(time_t)) {
- /*
- ** Ignore the end (easy).
- */
- sp->timecnt = i + 1;
- } else {
- /*
- ** Ignore the beginning (harder).
- */
- register int j;
-
- /*
- ** Keep the record right before the
- ** epoch boundary,
- ** but tweak it so that it starts
- ** right with the epoch
- ** (thanks to Doug Bailey).
- */
- sp->ats[i] = 0;
- for (j = 0; j + i < sp->timecnt; ++j) {
- sp->ats[j] = sp->ats[j + i];
- sp->types[j] = sp->types[j + i];
- }
- sp->timecnt = j;
- }
- break;
- }
- /*
** If this is an old file, we're done.
*/
if (up->tzhead.tzh_version[0] == '\0')
for (i = 0; i < nread; ++i)
up->buf[i] = p[i];
/*
- ** If this is a narrow time_t system, we're done.
+ ** If this is a signed narrow time_t system, we're done.
*/
- if (stored >= (int) sizeof(time_t))
+ if (TYPE_SIGNED(time_t) && stored >= (int) sizeof(time_t))
break;
}
if (doextend && nread > 2 &&
up->buf[0] == '\n' && up->buf[nread - 1] == '\n' &&
sp->typecnt + 2 <= TZ_MAX_TYPES) {
- struct state ts;
- register int result;
+ struct state ts;
+ register int result;
up->buf[nread - 1] = '\0';
result = tzparse(&up->buf[1], &ts, FALSE);
static int
typesequiv(const struct state *const sp, const int a, const int b)
{
- register int result;
-
- if (sp == NULL ||
- a < 0 || a >= sp->typecnt ||
- b < 0 || b >= sp->typecnt)
- result = FALSE;
- else {
- register const struct ttinfo * ap = &sp->ttis[a];
- register const struct ttinfo * bp = &sp->ttis[b];
- result = ap->tt_gmtoff == bp->tt_gmtoff &&
- ap->tt_isdst == bp->tt_isdst &&
- ap->tt_ttisstd == bp->tt_ttisstd &&
- ap->tt_ttisgmt == bp->tt_ttisgmt &&
- strcmp(&sp->chars[ap->tt_abbrind],
- &sp->chars[bp->tt_abbrind]) == 0;
- }
- return result;
+ register int result;
+
+ if (sp == NULL ||
+ a < 0 || a >= sp->typecnt ||
+ b < 0 || b >= sp->typecnt)
+ result = FALSE;
+ else {
+ register const struct ttinfo * ap = &sp->ttis[a];
+ register const struct ttinfo * bp = &sp->ttis[b];
+ result = ap->tt_gmtoff == bp->tt_gmtoff &&
+ ap->tt_isdst == bp->tt_isdst &&
+ ap->tt_ttisstd == bp->tt_ttisstd &&
+ ap->tt_ttisgmt == bp->tt_ttisgmt &&
+ strcmp(&sp->chars[ap->tt_abbrind],
+ &sp->chars[bp->tt_abbrind]) == 0;
+ }
+ return result;
}
-static const int mon_lengths[2][MONSPERYEAR] = {
+static const int mon_lengths[2][MONSPERYEAR] = {
{ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
{ 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
};
-static const int year_lengths[2] = {
+static const int year_lengths[2] = {
DAYSPERNYEAR, DAYSPERLYEAR
};
static const char *
getqzname(register const char *strp, const int delim)
{
- register int c;
+ register int c;
while ((c = *strp) != '\0' && c != delim)
++strp;
static const char *
getnum(register const char * strp, int * const nump, const int min, const int max)
{
- register char c;
- register int num;
+ register char c;
+ register int num;
if (strp == NULL || !is_digit(c = *strp))
return NULL;
static const char *
getoffset(register const char *strp, int_fast32_t *const offsetp)
{
- register int neg = 0;
+ register int neg = 0;
if (*strp == '-') {
neg = 1;
}
/*
-** Given the Epoch-relative time of January 1, 00:00:00 UTC, in a year, the
-** year, a rule, and the offset from UT at the time that rule takes effect,
-** calculate the Epoch-relative time that rule takes effect.
+** Given a year, a rule, and the offset from UT at the time that rule takes
+** effect, calculate the year-relative time that rule takes effect.
*/
-static time_t
-transtime(const time_t janfirst, const int year,
- register const struct rule *const rulep, const int_fast32_t offset)
+static int_fast32_t
+transtime(const int year, register const struct rule *const rulep,
+ const int_fast32_t offset)
{
- register int leapyear;
- register time_t value;
- register int i;
- int d, m1, yy0, yy1, yy2, dow;
+ register int leapyear;
+ register int_fast32_t value;
+ register int i;
+ int d, m1, yy0, yy1, yy2, dow;
INITIALIZE(value);
leapyear = isleap(year);
** add SECSPERDAY times the day number-1 to the time of
** January 1, midnight, to get the day.
*/
- value = janfirst + (rulep->r_day - 1) * SECSPERDAY;
+ value = (rulep->r_day - 1) * SECSPERDAY;
if (leapyear && rulep->r_day >= 60)
value += SECSPERDAY;
break;
** Just add SECSPERDAY times the day number to the time of
** January 1, midnight, to get the day.
*/
- value = janfirst + rulep->r_day * SECSPERDAY;
+ value = rulep->r_day * SECSPERDAY;
break;
case MONTH_NTH_DAY_OF_WEEK:
/*
** Mm.n.d - nth "dth day" of month m.
*/
- value = janfirst;
- for (i = 0; i < rulep->r_mon - 1; ++i)
- value += mon_lengths[leapyear][i] * SECSPERDAY;
/*
** Use Zeller's Congruence to get day-of-week of first day of
/*
** "d" is the day-of-month (zero-origin) of the day we want.
*/
- value += d * SECSPERDAY;
+ value = d * SECSPERDAY;
+ for (i = 0; i < rulep->r_mon - 1; ++i)
+ value += mon_lengths[leapyear][i] * SECSPERDAY;
break;
}
/*
- ** "value" is the Epoch-relative time of 00:00:00 UT on the day in
- ** question. To get the Epoch-relative time of the specified local
+ ** "value" is the year-relative time of 00:00:00 UT on the day in
+ ** question. To get the year-relative time of the specified local
** time on that day, add the transition time and the current offset
** from UT.
*/
tzparse(const char * name, register struct state * const sp,
const int lastditch)
{
- const char * stdname;
- const char * dstname;
- size_t stdlen;
- size_t dstlen;
- int_fast32_t stdoffset;
- int_fast32_t dstoffset;
- register time_t * atp;
- register unsigned char * typep;
- register char * cp;
- register int load_result;
- static struct ttinfo zttinfo;
+ const char * stdname;
+ const char * dstname;
+ size_t stdlen;
+ size_t dstlen;
+ int_fast32_t stdoffset;
+ int_fast32_t dstoffset;
+ register char * cp;
+ register int load_result;
+ static struct ttinfo zttinfo;
INITIALIZE(dstname);
stdname = name;
if (*name == '\0' && load_result != 0)
name = TZDEFRULESTRING;
if (*name == ',' || *name == ';') {
- struct rule start;
- struct rule end;
- register int year;
- register int yearlim;
- register time_t janfirst;
- time_t starttime;
- time_t endtime;
+ struct rule start;
+ struct rule end;
+ register int year;
+ register int yearlim;
+ register int timecnt;
+ time_t janfirst;
++name;
if ((name = getrule(name, &start)) == NULL)
sp->ttis[1].tt_gmtoff = -stdoffset;
sp->ttis[1].tt_isdst = 0;
sp->ttis[1].tt_abbrind = 0;
- atp = sp->ats;
- typep = sp->types;
+ timecnt = 0;
janfirst = 0;
yearlim = EPOCH_YEAR + YEARSPERREPEAT;
for (year = EPOCH_YEAR; year < yearlim; year++) {
- int_fast32_t yearsecs;
-
- starttime = transtime(janfirst, year, &start,
- stdoffset);
- endtime = transtime(janfirst, year, &end,
- dstoffset);
+ int_fast32_t
+ starttime = transtime(year, &start, stdoffset),
+ endtime = transtime(year, &end, dstoffset);
+ int_fast32_t
yearsecs = (year_lengths[isleap(year)]
* SECSPERDAY);
- if (starttime > endtime
+ int reversed = endtime < starttime;
+ if (reversed) {
+ int_fast32_t swap = starttime;
+ starttime = endtime;
+ endtime = swap;
+ }
+ if (reversed
|| (starttime < endtime
&& (endtime - starttime
< (yearsecs
+ (stdoffset - dstoffset))))) {
- if (&sp->ats[TZ_MAX_TIMES - 2] < atp)
+ if (TZ_MAX_TIMES - 2 < timecnt)
break;
yearlim = year + YEARSPERREPEAT + 1;
- if (starttime > endtime) {
- *atp++ = endtime;
- *typep++ = 1; /* DST ends */
- *atp++ = starttime;
- *typep++ = 0; /* DST begins */
- } else {
- *atp++ = starttime;
- *typep++ = 0; /* DST begins */
- *atp++ = endtime;
- *typep++ = 1; /* DST ends */
+ sp->ats[timecnt] = janfirst;
+ if (increment_overflow_time
+ (&sp->ats[timecnt], starttime))
+ break;
+ sp->types[timecnt++] = reversed;
+ sp->ats[timecnt] = janfirst;
+ if (increment_overflow_time
+ (&sp->ats[timecnt], endtime))
+ break;
+ sp->types[timecnt++] = !reversed;
}
- }
- if (time_t_max - janfirst < yearsecs)
+ if (increment_overflow_time(&janfirst, yearsecs))
break;
- janfirst += yearsecs;
}
- sp->timecnt = atp - sp->ats;
- if (!sp->timecnt)
- sp->typecnt = 1; /* Perpetual DST. */
+ sp->timecnt = timecnt;
+ if (!timecnt)
+ sp->typecnt = 1; /* Perpetual DST. */
} else {
register int_fast32_t theirstdoffset;
register int_fast32_t theirdstoffset;
static void
tzset_locked(void)
{
- register const char * name = NULL;
+ register const char * name = NULL;
name = getenv("TZ");
localsub(const time_t * const timep, const int_fast32_t offset,
struct tm * const tmp, const struct state * sp) // android-changed: added sp.
{
- register const struct ttinfo * ttisp;
- register int i;
- register struct tm * result;
- const time_t t = *timep;
+ register const struct ttinfo * ttisp;
+ register int i;
+ register struct tm * result;
+ const time_t t = *timep;
// BEGIN android-changed: support user-supplied sp.
if (sp == NULL) {
if ((sp->goback && t < sp->ats[0]) ||
(sp->goahead && t > sp->ats[sp->timecnt - 1])) {
time_t newt = t;
- register time_t seconds;
- register time_t years;
+ register time_t seconds;
+ register time_t years;
if (t < sp->ats[0])
seconds = sp->ats[0] - t;
if (sp->timecnt == 0 || t < sp->ats[0]) {
i = sp->defaulttype;
} else {
- register int lo = 1;
- register int hi = sp->timecnt;
+ register int lo = 1;
+ register int hi = sp->timecnt;
while (lo < hi) {
register int mid = (lo + hi) >> 1;
struct tm *
localtime_r(const time_t * const timep, struct tm * tmp)
{
- struct tm* result;
+ struct tm* result;
_tzLock();
tzset_locked();
gmtsub(const time_t * const timep, const int_fast32_t offset,
struct tm *const tmp, const struct state * sp) // android-changed: added sp.
{
- register struct tm * result;
+ register struct tm * result;
(void) sp; // android-added: unused.
struct tm *
gmtime_r(const time_t * const timep, struct tm * tmp)
{
- struct tm* result;
+ struct tm* result;
_tzLock();
result = gmtsub(timep, 0L, tmp, NULL); // android-changed: extra parameter.
register const struct state *const sp,
register struct tm *const tmp)
{
- register const struct lsinfo * lp;
- register time_t tdays;
- register int idays; /* unsigned would be so 2003 */
- register int_fast64_t rem;
- int y;
- register const int * ip;
- register int_fast64_t corr;
- register int hit;
- register int i;
+ register const struct lsinfo * lp;
+ register time_t tdays;
+ register int idays; /* unsigned would be so 2003 */
+ register int_fast64_t rem;
+ int y;
+ register const int * ip;
+ register int_fast64_t corr;
+ register int hit;
+ register int i;
corr = 0;
hit = 0;
static int
increment_overflow(int *const ip, int j)
{
- register int const i = *ip;
-
- /*
- ** If i >= 0 there can only be overflow if i + j > INT_MAX
- ** or if j > INT_MAX - i; given i >= 0, INT_MAX - i cannot overflow.
- ** If i < 0 there can only be overflow if i + j < INT_MIN
- ** or if j < INT_MIN - i; given i < 0, INT_MIN - i cannot overflow.
- */
- if ((i >= 0) ? (j > INT_MAX - i) : (j < INT_MIN - i))
- return TRUE;
- *ip += j;
- return FALSE;
+ register int const i = *ip;
+
+ /*
+ ** If i >= 0 there can only be overflow if i + j > INT_MAX
+ ** or if j > INT_MAX - i; given i >= 0, INT_MAX - i cannot overflow.
+ ** If i < 0 there can only be overflow if i + j < INT_MIN
+ ** or if j < INT_MIN - i; given i < 0, INT_MIN - i cannot overflow.
+ */
+ if ((i >= 0) ? (j > INT_MAX - i) : (j < INT_MIN - i))
+ return TRUE;
+ *ip += j;
+ return FALSE;
}
static int
increment_overflow32(int_fast32_t *const lp, int const m)
{
- register int_fast32_t const l = *lp;
+ register int_fast32_t const l = *lp;
- if ((l >= 0) ? (m > INT_FAST32_MAX - l) : (m < INT_FAST32_MIN - l))
- return TRUE;
- *lp += m;
- return FALSE;
+ if ((l >= 0) ? (m > INT_FAST32_MAX - l) : (m < INT_FAST32_MIN - l))
+ return TRUE;
+ *lp += m;
+ return FALSE;
+}
+
+static int
+increment_overflow_time(time_t *tp, int_fast32_t j)
+{
+ /*
+ ** This is like
+ ** 'if (! (time_t_min <= *tp + j && *tp + j <= time_t_max)) ...',
+ ** except that it does the right thing even if *tp + j would overflow.
+ */
+ if (! (j < 0
+ ? (TYPE_SIGNED(time_t) ? time_t_min - j <= *tp : -1 - j < *tp)
+ : *tp <= time_t_max - j))
+ return TRUE;
+ *tp += j;
+ return FALSE;
}
static int
normalize_overflow(int *const tensptr, int *const unitsptr, const int base)
{
- register int tensdelta;
+ register int tensdelta;
- tensdelta = (*unitsptr >= 0) ?
- (*unitsptr / base) :
- (-1 - (-1 - *unitsptr) / base);
- *unitsptr -= tensdelta * base;
- return increment_overflow(tensptr, tensdelta);
+ tensdelta = (*unitsptr >= 0) ?
+ (*unitsptr / base) :
+ (-1 - (-1 - *unitsptr) / base);
+ *unitsptr -= tensdelta * base;
+ return increment_overflow(tensptr, tensdelta);
}
static int
normalize_overflow32(int_fast32_t *const tensptr, int *const unitsptr,
- const int base)
+ const int base)
{
- register int tensdelta;
+ register int tensdelta;
- tensdelta = (*unitsptr >= 0) ?
- (*unitsptr / base) :
- (-1 - (-1 - *unitsptr) / base);
- *unitsptr -= tensdelta * base;
- return increment_overflow32(tensptr, tensdelta);
+ tensdelta = (*unitsptr >= 0) ?
+ (*unitsptr / base) :
+ (-1 - (-1 - *unitsptr) / base);
+ *unitsptr -= tensdelta * base;
+ return increment_overflow32(tensptr, tensdelta);
}
static int
tmcomp(register const struct tm * const atmp,
register const struct tm * const btmp)
{
- register int result;
+ register int result;
if (atmp->tm_year != btmp->tm_year)
return atmp->tm_year < btmp->tm_year ? -1 : 1;
int * const okayp,
const int do_norm_secs, const struct state * sp) // android-changed: added sp
{
- register int dir;
- register int i, j;
- register int saved_seconds;
- register int_fast32_t li;
- register time_t lo;
- register time_t hi;
- int_fast32_t y;
- time_t newt;
- time_t t;
- struct tm yourtm, mytm;
+ register int dir;
+ register int i, j;
+ register int saved_seconds;
+ register int_fast32_t li;
+ register time_t lo;
+ register time_t hi;
+ int_fast32_t y;
+ time_t newt;
+ time_t t;
+ struct tm yourtm, mytm;
*okayp = FALSE;
yourtm = *tmp;
const int_fast32_t offset,
int *const okayp, const struct state* sp) // android-changed: added sp.
{
- time_t t;
+ time_t t;
/*
** First try without normalization of seconds
struct tm * (* const funcp) (const time_t *, int_fast32_t, struct tm *, const struct state *), // android-changed: added sp.
const int_fast32_t offset, const struct state * sp) // android-changed: added sp.
{
- register time_t t;
- register int samei, otheri;
- register int sameind, otherind;
- register int i;
- register int nseen;
+ register time_t t;
+ register int samei, otheri;
+ register int sameind, otherind;
+ register int i;
+ register int nseen;
int seen[TZ_MAX_TYPES];
int types[TZ_MAX_TYPES];
int okay;
time_t
timegm(struct tm * const tmp)
{
- time_t result;
+ time_t result;
if (tmp != NULL)
tmp->tm_isdst = 0;
long
gtime(struct tm * const tmp)
{
- const time_t t = mktime(tmp);
+ const time_t t = mktime(tmp);
if (t == WRONG)
return -1;
static int_fast64_t
leapcorr(time_t * timep)
{
- register struct state * sp;
- register struct lsinfo * lp;
- register int i;
+ register struct state * sp;
+ register struct lsinfo * lp;
+ register int i;
sp = lclptr;
i = sp->leapcnt;
time_t
posix2time(time_t t)
{
- time_t x;
- time_t y;
+ time_t x;
+ time_t y;
tzset();
/*
@@ -2167,26 +2164,40 @@ static int __bionic_open_tzdata_path(const char* path_prefix_variable, const cha
}
off_t specific_zone_offset = -1;
+ ssize_t index_size = ntohl(header.data_offset) - ntohl(header.index_offset);
+ char* index = malloc(index_size);
+ if (TEMP_FAILURE_RETRY(read(fd, index, index_size)) != index_size) {
+ fprintf(stderr, "%s: could not read index of \"%s\": %s\n",
+ __FUNCTION__, path, (bytes_read == -1) ? strerror(errno) : "short read");
+ free(index);
+ close(fd);
+ return -1;
+ }
static const size_t NAME_LENGTH = 40;
- unsigned char buf[NAME_LENGTH + 3 * sizeof(int32_t)];
-
- size_t id_count = (ntohl(header.data_offset) - ntohl(header.index_offset)) / sizeof(buf);
+ struct index_entry_t {
+ char buf[NAME_LENGTH];
+ int32_t start;
+ int32_t length;
+ int32_t raw_gmt_offset;
+ };
+
+ size_t id_count = (ntohl(header.data_offset) - ntohl(header.index_offset)) / sizeof(struct index_entry_t);
+ struct index_entry_t* entry = (struct index_entry_t*) index;
for (size_t i = 0; i < id_count; ++i) {
- if (TEMP_FAILURE_RETRY(read(fd, buf, sizeof(buf))) != (ssize_t) sizeof(buf)) {
- break;
- }
-
char this_id[NAME_LENGTH + 1];
- memcpy(this_id, buf, NAME_LENGTH);
+ memcpy(this_id, entry->buf, NAME_LENGTH);
this_id[NAME_LENGTH] = '\0';
if (strcmp(this_id, olson_id) == 0) {
- specific_zone_offset = to_int(buf + NAME_LENGTH) + ntohl(header.data_offset);
- *data_size = to_int(buf + NAME_LENGTH + sizeof(int32_t));
+ specific_zone_offset = ntohl(entry->start) + ntohl(header.data_offset);
+ *data_size = ntohl(entry->length);
break;
}
+
+ ++entry;
}
+ free(index);
if (specific_zone_offset == -1) {
XLOG(("%s: couldn't find zone \"%s\"\n", __FUNCTION__, olson_id));
diff --git a/libc/tzcode/private.h b/libc/tzcode/private.h
index 3a1930571db5e178ab27833cb549d2fd83ec567c..4eb0ab62215bf39b52119fc6934466388ffe6471 100644 (file)
--- a/libc/tzcode/private.h
+++ b/libc/tzcode/private.h
#define HAVE_INCOMPATIBLE_CTIME_R 0
#endif /* !defined INCOMPATIBLE_CTIME_R */
+#ifndef HAVE_LINK
+#define HAVE_LINK 1
+#endif /* !defined HAVE_LINK */
+
#ifndef HAVE_SETTIMEOFDAY
#define HAVE_SETTIMEOFDAY 3
#endif /* !defined HAVE_SETTIMEOFDAY */
diff --git a/libc/tzcode/tzfile.h b/libc/tzcode/tzfile.h
index a2955dd1479965cef256f84877524db1cdc03819..529650dd8a044b7a141dd41fbff76134c36dcb01 100644 (file)
--- a/libc/tzcode/tzfile.h
+++ b/libc/tzcode/tzfile.h
#endif /* !defined TZ_MAX_TIMES */
#ifndef TZ_MAX_TYPES
-#ifndef NOSOLAR
+/* This must be at least 17 for Europe/Samara and Europe/Vilnius. */
#define TZ_MAX_TYPES 256 /* Limited by what (unsigned char)'s can hold */
-#endif /* !defined NOSOLAR */
-#ifdef NOSOLAR
-/*
-** Must be at least 14 for Europe/Riga as of Jan 12 1995,
-** as noted by Earl Chew.
-*/
-#define TZ_MAX_TYPES 20 /* Maximum number of local time types */
-#endif /* !defined NOSOLAR */
#endif /* !defined TZ_MAX_TYPES */
#ifndef TZ_MAX_CHARS
similarity index 78%
rename from libc/unistd/alarm.c
rename to libc/upstream-openbsd/lib/libc/gen/alarm.c
index 53edea949854e082ea454fd1eebc53a360a21676..2af847a46a39c2706693ae11b1701c8fadb460b0 100644 (file)
rename from libc/unistd/alarm.c
rename to libc/upstream-openbsd/lib/libc/gen/alarm.c
index 53edea949854e082ea454fd1eebc53a360a21676..2af847a46a39c2706693ae11b1701c8fadb460b0 100644 (file)
--- a/libc/unistd/alarm.c
+/* $OpenBSD: alarm.c,v 1.7 2005/08/08 08:05:33 espie Exp $ */
/*
* Copyright (c) 1983, 1993
* The Regents of the University of California. All rights reserved.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* SUCH DAMAGE.
*/
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)alarm.c 8.1 (Berkeley) 6/4/93";
-#endif /* LIBC_SCCS and not lint */
-#include <sys/cdefs.h>
-//__FBSDID("$FreeBSD: /repoman/r/ncvs/src/lib/libc/gen/alarm.c,v 1.3 2007/01/09 00:27:53 imp Exp $");
-
/*
* Backwards compatible alarm.
*/
#include <unistd.h>
unsigned int
-alarm(secs)
- unsigned int secs;
+alarm(unsigned int secs)
{
struct itimerval it, oitv;
struct itimerval *itp = ⁢
- itp->it_interval.tv_usec = 0;
- itp->it_interval.tv_sec = 0;
+ timerclear(&itp->it_interval);
itp->it_value.tv_sec = secs;
itp->it_value.tv_usec = 0;
if (setitimer(ITIMER_REAL, itp, &oitv) < 0)
-#if 1 /* BIONIC: Same behaviour than GLibc for errors */
- return 0;
-#else
- return (-1);
-#endif
+ return ((unsigned int) -1);
if (oitv.it_value.tv_usec)
oitv.it_value.tv_sec++;
return (oitv.it_value.tv_sec);
diff --git a/libc/upstream-openbsd/lib/libc/gen/getprogname.c b/libc/upstream-openbsd/lib/libc/gen/getprogname.c
--- /dev/null
@@ -0,0 +1,24 @@
+/* $OpenBSD: getprogname.c,v 1.2 2013/05/31 21:19:01 tedu Exp $ */
+/*
+ * Copyright (c) 2013 Antoine Jacoutot <ajacoutot@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+extern const char *__progname;
+
+const char *
+getprogname(void)
+{
+ return (__progname);
+}
diff --git a/libc/upstream-openbsd/lib/libc/gen/setprogname.c b/libc/upstream-openbsd/lib/libc/gen/setprogname.c
--- /dev/null
@@ -0,0 +1,32 @@
+/* $OpenBSD: setprogname.c,v 1.3 2013/06/01 01:43:43 tedu Exp $ */
+/*
+ * Copyright (c) 2013 Antoine Jacoutot <ajacoutot@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <string.h>
+
+extern const char *__progname;
+
+void
+setprogname(const char *progname)
+{
+ const char *tmpn;
+
+ tmpn = strrchr(progname, '/');
+ if (tmpn == NULL)
+ __progname = progname;
+ else
+ __progname = tmpn + 1;
+}
diff --git a/tests/Android.mk b/tests/Android.mk
index 5fafba6b06d17e4ab84405b8d28cfc3eea4afe3e..451b3a99dfc28de764cfa69001a234483ad6a5cb 100644 (file)
--- a/tests/Android.mk
+++ b/tests/Android.mk
sys_resource_test.cpp \
sys_select_test.cpp \
sys_sendfile_test.cpp \
+ sys_socket_test.cpp \
sys_stat_test.cpp \
sys_statvfs_test.cpp \
sys_syscall_test.cpp \
diff --git a/tests/pthread_test.cpp b/tests/pthread_test.cpp
index d2341188beff50668c19e8ad6e0e935d0dbb283c..d481a1d86fe18bd5881df54ca521dd00dc1d1f90 100644 (file)
--- a/tests/pthread_test.cpp
+++ b/tests/pthread_test.cpp
#include <pthread.h>
#include <signal.h>
#include <sys/mman.h>
+#include <time.h>
#include <unistd.h>
TEST(pthread, pthread_key_create) {
ASSERT_EQ(0, pthread_attr_getscope(&attr, &scope));
ASSERT_EQ(PTHREAD_SCOPE_SYSTEM, scope);
}
+
+TEST(pthread, pthread_condattr_init) {
+ pthread_condattr_t attr;
+ pthread_condattr_init(&attr);
+
+ clockid_t clock;
+ ASSERT_EQ(0, pthread_condattr_getclock(&attr, &clock));
+ ASSERT_EQ(CLOCK_REALTIME, clock);
+
+ int pshared;
+ ASSERT_EQ(0, pthread_condattr_getpshared(&attr, &pshared));
+ ASSERT_EQ(PTHREAD_PROCESS_PRIVATE, pshared);
+}
+
+TEST(pthread, pthread_condattr_setclock) {
+ pthread_condattr_t attr;
+ pthread_condattr_init(&attr);
+
+ ASSERT_EQ(0, pthread_condattr_setclock(&attr, CLOCK_REALTIME));
+ clockid_t clock;
+ ASSERT_EQ(0, pthread_condattr_getclock(&attr, &clock));
+ ASSERT_EQ(CLOCK_REALTIME, clock);
+
+ ASSERT_EQ(0, pthread_condattr_setclock(&attr, CLOCK_MONOTONIC));
+ ASSERT_EQ(0, pthread_condattr_getclock(&attr, &clock));
+ ASSERT_EQ(CLOCK_MONOTONIC, clock);
+
+ ASSERT_EQ(EINVAL, pthread_condattr_setclock(&attr, CLOCK_PROCESS_CPUTIME_ID));
+}
+
+TEST(pthread, pthread_cond_broadcast__preserves_condattr_flags) {
+#if defined(__BIONIC__) // This tests a bionic implementation detail.
+ pthread_condattr_t attr;
+ pthread_condattr_init(&attr);
+
+ ASSERT_EQ(0, pthread_condattr_setclock(&attr, CLOCK_MONOTONIC));
+ ASSERT_EQ(0, pthread_condattr_setpshared(&attr, PTHREAD_PROCESS_SHARED));
+
+ pthread_cond_t cond_var;
+ ASSERT_EQ(0, pthread_cond_init(&cond_var, &attr));
+
+ ASSERT_EQ(0, pthread_cond_signal(&cond_var));
+ ASSERT_EQ(0, pthread_cond_broadcast(&cond_var));
+
+ attr = static_cast<pthread_condattr_t>(cond_var.value);
+ clockid_t clock;
+ ASSERT_EQ(0, pthread_condattr_getclock(&attr, &clock));
+ ASSERT_EQ(CLOCK_MONOTONIC, clock);
+ int pshared;
+ ASSERT_EQ(0, pthread_condattr_getpshared(&attr, &pshared));
+ ASSERT_EQ(PTHREAD_PROCESS_SHARED, pshared);
+#else // __BIONIC__
+ GTEST_LOG_(INFO) << "This test does nothing.\n";
+#endif // __BIONIC__
+}
diff --git a/tests/sys_socket_test.cpp b/tests/sys_socket_test.cpp
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2014 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 <gtest/gtest.h>
+
+#include <errno.h>
+#include <sys/socket.h>
+
+TEST(sys_socket, recvmmsg) {
+#if !defined(__GLIBC__) // TODO: Android's prebuilt gcc is too old for recvmmsg/sendmmsg.
+ ASSERT_EQ(-1, recvmmsg(-1, NULL, 0, 0, NULL));
+ ASSERT_EQ(EBADF, errno);
+#endif
+}
+
+TEST(sys_socket, sendmmsg) {
+#if !defined(__GLIBC__) // TODO: Android's prebuilt gcc is too old for recvmmsg/sendmmsg.
+ ASSERT_EQ(-1, sendmmsg(-1, NULL, 0, 0));
+ ASSERT_EQ(EBADF, errno);
+#endif
+}
diff --git a/tests/unistd_test.cpp b/tests/unistd_test.cpp
index 9969d49bcdf9cf018628ff62665f297d1987cbb8..f50c102f6b187d922a4a2cbfa63ea6bee3eeee0b 100644 (file)
--- a/tests/unistd_test.cpp
+++ b/tests/unistd_test.cpp
ASSERT_EQ(-1, read(-1, buf, sizeof(buf)));
ASSERT_EQ(EBADF, errno);
}
+
+TEST(unistd, alarm) {
+ ASSERT_EQ(0U, alarm(0));
+}