diff --git a/libc/SYSCALLS.TXT b/libc/SYSCALLS.TXT index e0450494e..d5dd2063e 100644 --- a/libc/SYSCALLS.TXT +++ b/libc/SYSCALLS.TXT @@ -224,6 +224,7 @@ int timerfd_create(clockid_t, int) all int timerfd_settime(int, int, const struct itimerspec*, struct itimerspec*) all int timerfd_gettime(int, struct itimerspec*) all int adjtimex(struct timex*) all +int clock_adjtime(clockid_t, struct timex*) all # signals int __sigaction:sigaction(int, const struct sigaction*, struct sigaction*) arm,mips,x86 diff --git a/libc/arch-arm/syscalls/clock_adjtime.S b/libc/arch-arm/syscalls/clock_adjtime.S new file mode 100644 index 000000000..fa778e124 --- /dev/null +++ b/libc/arch-arm/syscalls/clock_adjtime.S @@ -0,0 +1,14 @@ +/* Generated by gensyscalls.py. Do not edit. */ + +#include + +ENTRY(clock_adjtime) + mov ip, r7 + ldr r7, =__NR_clock_adjtime + swi #0 + mov r7, ip + cmn r0, #(MAX_ERRNO + 1) + bxls lr + neg r0, r0 + b __set_errno_internal +END(clock_adjtime) diff --git a/libc/arch-arm64/syscalls/clock_adjtime.S b/libc/arch-arm64/syscalls/clock_adjtime.S new file mode 100644 index 000000000..c2c191ed1 --- /dev/null +++ b/libc/arch-arm64/syscalls/clock_adjtime.S @@ -0,0 +1,14 @@ +/* Generated by gensyscalls.py. Do not edit. */ + +#include + +ENTRY(clock_adjtime) + mov x8, __NR_clock_adjtime + svc #0 + + cmn x0, #(MAX_ERRNO + 1) + cneg x0, x0, hi + b.hi __set_errno_internal + + ret +END(clock_adjtime) diff --git a/libc/arch-mips/syscalls/clock_adjtime.S b/libc/arch-mips/syscalls/clock_adjtime.S new file mode 100644 index 000000000..f8a4ce22d --- /dev/null +++ b/libc/arch-mips/syscalls/clock_adjtime.S @@ -0,0 +1,19 @@ +/* Generated by gensyscalls.py. Do not edit. */ + +#include + +ENTRY(clock_adjtime) + .set noreorder + .cpload t9 + li v0, __NR_clock_adjtime + syscall + bnez a3, 1f + move a0, v0 + j ra + nop +1: + la t9,__set_errno_internal + j t9 + nop + .set reorder +END(clock_adjtime) diff --git a/libc/arch-mips64/syscalls/clock_adjtime.S b/libc/arch-mips64/syscalls/clock_adjtime.S new file mode 100644 index 000000000..206e9fdd9 --- /dev/null +++ b/libc/arch-mips64/syscalls/clock_adjtime.S @@ -0,0 +1,25 @@ +/* Generated by gensyscalls.py. Do not edit. */ + +#include + +ENTRY(clock_adjtime) + .set push + .set noreorder + li v0, __NR_clock_adjtime + 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_internal + .cpreturn + j t9 + move ra, t0 + .set pop +END(clock_adjtime) diff --git a/libc/arch-x86/syscalls/clock_adjtime.S b/libc/arch-x86/syscalls/clock_adjtime.S new file mode 100644 index 000000000..b6e0ac4f8 --- /dev/null +++ b/libc/arch-x86/syscalls/clock_adjtime.S @@ -0,0 +1,26 @@ +/* Generated by gensyscalls.py. Do not edit. */ + +#include + +ENTRY(clock_adjtime) + pushl %ebx + .cfi_def_cfa_offset 8 + .cfi_rel_offset ebx, 0 + pushl %ecx + .cfi_adjust_cfa_offset 4 + .cfi_rel_offset ecx, 0 + mov 12(%esp), %ebx + mov 16(%esp), %ecx + movl $__NR_clock_adjtime, %eax + int $0x80 + cmpl $-MAX_ERRNO, %eax + jb 1f + negl %eax + pushl %eax + call __set_errno_internal + addl $4, %esp +1: + popl %ecx + popl %ebx + ret +END(clock_adjtime) diff --git a/libc/arch-x86_64/syscalls/clock_adjtime.S b/libc/arch-x86_64/syscalls/clock_adjtime.S new file mode 100644 index 000000000..0601930a5 --- /dev/null +++ b/libc/arch-x86_64/syscalls/clock_adjtime.S @@ -0,0 +1,15 @@ +/* Generated by gensyscalls.py. Do not edit. */ + +#include + +ENTRY(clock_adjtime) + movl $__NR_clock_adjtime, %eax + syscall + cmpq $-MAX_ERRNO, %rax + jb 1f + negl %eax + movl %eax, %edi + call __set_errno_internal +1: + ret +END(clock_adjtime) diff --git a/libc/include/sys/timex.h b/libc/include/sys/timex.h index 6138ac499..fade5c375 100644 --- a/libc/include/sys/timex.h +++ b/libc/include/sys/timex.h @@ -30,11 +30,13 @@ #define _SYS_TIMEX_H_ #include +#include #include __BEGIN_DECLS -extern int adjtimex(struct timex *buf); +int adjtimex(struct timex*); +int clock_adjtime(clockid_t, struct timex*); __END_DECLS diff --git a/libc/libc.arm.brillo.map b/libc/libc.arm.brillo.map index 9251de22d..01541a9c0 100644 --- a/libc/libc.arm.brillo.map +++ b/libc/libc.arm.brillo.map @@ -1224,6 +1224,8 @@ LIBC_N { __pwrite_chk; __pwrite64_chk; __write_chk; + adjtimex; + clock_adjtime; fgetpos64; fileno_unlocked; fopen64; diff --git a/libc/libc.arm.map b/libc/libc.arm.map index f5ddfd3e3..25f53c9c6 100644 --- a/libc/libc.arm.map +++ b/libc/libc.arm.map @@ -1224,6 +1224,8 @@ LIBC_N { __pwrite_chk; __pwrite64_chk; __write_chk; + adjtimex; + clock_adjtime; fgetpos64; fileno_unlocked; fopen64; diff --git a/libc/libc.arm64.map b/libc/libc.arm64.map index 271460f80..93bd94cc8 100644 --- a/libc/libc.arm64.map +++ b/libc/libc.arm64.map @@ -1147,6 +1147,8 @@ LIBC_N { __pwrite_chk; __pwrite64_chk; __write_chk; + adjtimex; + clock_adjtime; fgetpos64; fileno_unlocked; fopen64; diff --git a/libc/libc.map.txt b/libc/libc.map.txt index c859d8143..dd0b9c047 100644 --- a/libc/libc.map.txt +++ b/libc/libc.map.txt @@ -1250,6 +1250,8 @@ LIBC_N { __pwrite_chk; __pwrite64_chk; __write_chk; + adjtimex; + clock_adjtime; fgetpos64; fileno_unlocked; fopen64; diff --git a/libc/libc.mips.brillo.map b/libc/libc.mips.brillo.map index e5376bec6..287c21436 100644 --- a/libc/libc.mips.brillo.map +++ b/libc/libc.mips.brillo.map @@ -1208,6 +1208,8 @@ LIBC_N { __pwrite_chk; __pwrite64_chk; __write_chk; + adjtimex; + clock_adjtime; fgetpos64; fileno_unlocked; fopen64; diff --git a/libc/libc.mips.map b/libc/libc.mips.map index 4902f57c2..5c15a4239 100644 --- a/libc/libc.mips.map +++ b/libc/libc.mips.map @@ -1208,6 +1208,8 @@ LIBC_N { __pwrite_chk; __pwrite64_chk; __write_chk; + adjtimex; + clock_adjtime; fgetpos64; fileno_unlocked; fopen64; diff --git a/libc/libc.mips64.map b/libc/libc.mips64.map index 271460f80..93bd94cc8 100644 --- a/libc/libc.mips64.map +++ b/libc/libc.mips64.map @@ -1147,6 +1147,8 @@ LIBC_N { __pwrite_chk; __pwrite64_chk; __write_chk; + adjtimex; + clock_adjtime; fgetpos64; fileno_unlocked; fopen64; diff --git a/libc/libc.x86.brillo.map b/libc/libc.x86.brillo.map index bbf9d57d3..95fd7b8be 100644 --- a/libc/libc.x86.brillo.map +++ b/libc/libc.x86.brillo.map @@ -1207,6 +1207,8 @@ LIBC_N { __pwrite_chk; __pwrite64_chk; __write_chk; + adjtimex; + clock_adjtime; fgetpos64; fileno_unlocked; fopen64; diff --git a/libc/libc.x86.map b/libc/libc.x86.map index fb0f109fa..6a1acba7a 100644 --- a/libc/libc.x86.map +++ b/libc/libc.x86.map @@ -1207,6 +1207,8 @@ LIBC_N { __pwrite_chk; __pwrite64_chk; __write_chk; + adjtimex; + clock_adjtime; fgetpos64; fileno_unlocked; fopen64; diff --git a/libc/libc.x86_64.map b/libc/libc.x86_64.map index 271460f80..93bd94cc8 100644 --- a/libc/libc.x86_64.map +++ b/libc/libc.x86_64.map @@ -1147,6 +1147,8 @@ LIBC_N { __pwrite_chk; __pwrite64_chk; __write_chk; + adjtimex; + clock_adjtime; fgetpos64; fileno_unlocked; fopen64; diff --git a/tests/Android.mk b/tests/Android.mk index fb3c25445..aba0871c5 100644 --- a/tests/Android.mk +++ b/tests/Android.mk @@ -106,6 +106,7 @@ libBionicStandardTests_src_files := \ sys_sysinfo_test.cpp \ sys_sysmacros_test.cpp \ sys_time_test.cpp \ + sys_timex_test.cpp \ sys_types_test.cpp \ sys_uio_test.cpp \ sys_vfs_test.cpp \ diff --git a/tests/sys_timex_test.cpp b/tests/sys_timex_test.cpp new file mode 100644 index 000000000..1340ea42d --- /dev/null +++ b/tests/sys_timex_test.cpp @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2016 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 + +#include + +#include + +TEST(sys_timex, adjtimex_smoke) { + timex t; + memset(&t, 0, sizeof(t)); + // adjtimex/clock_adjtime return the clock state on success, -1 on failure. + ASSERT_NE(-1, adjtimex(&t)); +} + +TEST(sys_timex, adjtimex_EFAULT) { + errno = 0; + ASSERT_EQ(-1, adjtimex(nullptr)); + ASSERT_EQ(EFAULT, errno); +} + +TEST(sys_timex, clock_adjtime_smoke) { + timex t; + memset(&t, 0, sizeof(t)); + // adjtimex/clock_adjtime return the clock state on success, -1 on failure. + ASSERT_NE(-1, clock_adjtime(CLOCK_REALTIME, &t)); +} + +TEST(sys_timex, clock_adjtime_EFAULT) { + errno = 0; + ASSERT_EQ(-1, clock_adjtime(CLOCK_REALTIME, nullptr)); + ASSERT_EQ(EFAULT, errno); +}