diff --git a/libc/Android.mk b/libc/Android.mk index fea2680a5..287a28cc0 100644 --- a/libc/Android.mk +++ b/libc/Android.mk @@ -108,7 +108,6 @@ libc_common_src_files := \ bionic/pathconf.c \ bionic/perror.c \ bionic/pread.c \ - bionic/pselect.c \ bionic/ptsname.c \ bionic/ptsname_r.c \ bionic/pututline.c \ @@ -212,12 +211,15 @@ libc_bionic_src_files := \ bionic/abort.cpp \ bionic/access.cpp \ bionic/assert.cpp \ + bionic/bionic_time_conversions.cpp \ bionic/brk.cpp \ bionic/chmod.cpp \ bionic/chown.cpp \ bionic/dirent.cpp \ bionic/dup2.cpp \ bionic/epoll_create.cpp \ + bionic/epoll_wait.cpp \ + bionic/epoll_pwait.cpp \ bionic/__errno.cpp \ bionic/eventfd_read.cpp \ bionic/eventfd_write.cpp \ @@ -236,7 +238,9 @@ libc_bionic_src_files := \ bionic/mkfifo.cpp \ bionic/mknod.cpp \ bionic/open.cpp \ + bionic/pause.cpp \ bionic/pipe.cpp \ + bionic/poll.cpp \ bionic/pthread_attr.cpp \ bionic/pthread_detach.cpp \ bionic/pthread_equal.cpp \ diff --git a/libc/SYSCALLS.TXT b/libc/SYSCALLS.TXT index 2caacf61e..8dc2b8af3 100644 --- a/libc/SYSCALLS.TXT +++ b/libc/SYSCALLS.TXT @@ -27,14 +27,9 @@ # process management void _exit:exit_group(int) all void _exit_thread:exit(int) all -pid_t __fork:fork(void) all -pid_t wait4(pid_t pid, int* status, int options, struct rusage* rusage) all -# NOTE: these stubs are unused. -pid_t __sys_clone:clone(int, void*, int*, void*, int*) all -pid_t _waitpid:waitpid(pid_t, int*, int, struct rusage*) mips,x86 -int __waitid:waitid(int, pid_t, struct siginfo_t*, int, void*) all -int __open:open(const char*, int, mode_t) arm,mips,x86 +pid_t wait4(pid_t, int*, int, struct rusage*) all +int __waitid:waitid(int, pid_t, struct siginfo_t*, int, void*) all int execve(const char*, char* const*, char* const*) all @@ -126,8 +121,6 @@ int fchmod(int, mode_t) all int dup(int) all int pipe2(int*, int) all int dup3(int, int, int) all -int select:_newselect(int, struct fd_set*, struct fd_set*, struct fd_set*, struct timeval*) arm,x86,mips -int select(int, struct fd_set*, struct fd_set*, struct fd_set*, struct timeval*) x86_64 int getdents:getdents64(unsigned int, struct dirent*, unsigned int) all int fsync(int) all int fdatasync(int) all @@ -197,7 +190,6 @@ int swapon(const char*, int) all int swapoff(const char*) all # time -int pause() all int gettimeofday(struct timeval*, struct timezone*) all int settimeofday(const struct timeval*, const struct timezone*) all clock_t times(struct tms*) all @@ -289,9 +281,11 @@ int sysinfo(struct sysinfo*) all int personality(unsigned long) all long perf_event_open(struct perf_event_attr* attr_uptr, pid_t pid, int cpu, int group_fd, unsigned long flags) all +pid_t __clone:clone(int, void*, int*, void*, int*) all + int epoll_create1(int) all int epoll_ctl(int, int op, int, struct epoll_event*) all -int epoll_wait(int, struct epoll_event*, int, int) all +int __epoll_pwait:epoll_pwait(int, struct epoll_event*, int, int, const sigset_t*, size_t) all int eventfd:eventfd2(unsigned int, int) all @@ -301,7 +295,8 @@ int inotify_init1(int) all int inotify_add_watch(int, const char*, unsigned int) all int inotify_rm_watch(int, unsigned int) all -int poll(struct pollfd*, unsigned int, long) all +int __pselect6:pselect6(int, fd_set*, fd_set*, fd_set*, timespec*, void*) all +int __ppoll:ppoll(pollfd*, unsigned int, timespec*, const sigset_t*, size_t) all # ARM-specific int __set_tls:__ARM_NR_set_tls(void*) arm diff --git a/libc/arch-arm/syscalls.mk b/libc/arch-arm/syscalls.mk index 959dfeb78..e8b67595b 100644 --- a/libc/arch-arm/syscalls.mk +++ b/libc/arch-arm/syscalls.mk @@ -1,9 +1,10 @@ # Generated by gensyscalls.py. Do not edit. syscall_src := syscall_src += arch-arm/syscalls/__brk.S +syscall_src += arch-arm/syscalls/__clone.S +syscall_src += arch-arm/syscalls/__epoll_pwait.S syscall_src += arch-arm/syscalls/__fcntl.S syscall_src += arch-arm/syscalls/__fcntl64.S -syscall_src += arch-arm/syscalls/__fork.S syscall_src += arch-arm/syscalls/__fstatfs64.S syscall_src += arch-arm/syscalls/__getcpu.S syscall_src += arch-arm/syscalls/__getcwd.S @@ -11,8 +12,9 @@ syscall_src += arch-arm/syscalls/__getpriority.S syscall_src += arch-arm/syscalls/__ioctl.S syscall_src += arch-arm/syscalls/__llseek.S syscall_src += arch-arm/syscalls/__mmap2.S -syscall_src += arch-arm/syscalls/__open.S syscall_src += arch-arm/syscalls/__openat.S +syscall_src += arch-arm/syscalls/__ppoll.S +syscall_src += arch-arm/syscalls/__pselect6.S syscall_src += arch-arm/syscalls/__ptrace.S syscall_src += arch-arm/syscalls/__reboot.S syscall_src += arch-arm/syscalls/__rt_sigaction.S @@ -24,7 +26,6 @@ syscall_src += arch-arm/syscalls/__sched_getaffinity.S syscall_src += arch-arm/syscalls/__set_tls.S syscall_src += arch-arm/syscalls/__sigaction.S syscall_src += arch-arm/syscalls/__statfs64.S -syscall_src += arch-arm/syscalls/__sys_clone.S syscall_src += arch-arm/syscalls/__syslog.S syscall_src += arch-arm/syscalls/__timer_create.S syscall_src += arch-arm/syscalls/__timer_delete.S @@ -53,7 +54,6 @@ syscall_src += arch-arm/syscalls/dup.S syscall_src += arch-arm/syscalls/dup3.S syscall_src += arch-arm/syscalls/epoll_create1.S syscall_src += arch-arm/syscalls/epoll_ctl.S -syscall_src += arch-arm/syscalls/epoll_wait.S syscall_src += arch-arm/syscalls/eventfd.S syscall_src += arch-arm/syscalls/execve.S syscall_src += arch-arm/syscalls/faccessat.S @@ -124,11 +124,9 @@ syscall_src += arch-arm/syscalls/munlock.S syscall_src += arch-arm/syscalls/munlockall.S syscall_src += arch-arm/syscalls/munmap.S syscall_src += arch-arm/syscalls/nanosleep.S -syscall_src += arch-arm/syscalls/pause.S syscall_src += arch-arm/syscalls/perf_event_open.S syscall_src += arch-arm/syscalls/personality.S syscall_src += arch-arm/syscalls/pipe2.S -syscall_src += arch-arm/syscalls/poll.S syscall_src += arch-arm/syscalls/prctl.S syscall_src += arch-arm/syscalls/pread64.S syscall_src += arch-arm/syscalls/pwrite64.S @@ -149,7 +147,6 @@ syscall_src += arch-arm/syscalls/sched_setaffinity.S syscall_src += arch-arm/syscalls/sched_setparam.S syscall_src += arch-arm/syscalls/sched_setscheduler.S syscall_src += arch-arm/syscalls/sched_yield.S -syscall_src += arch-arm/syscalls/select.S syscall_src += arch-arm/syscalls/sendfile.S syscall_src += arch-arm/syscalls/sendfile64.S syscall_src += arch-arm/syscalls/sendmsg.S diff --git a/libc/arch-arm/syscalls/__sys_clone.S b/libc/arch-arm/syscalls/__clone.S similarity index 91% rename from libc/arch-arm/syscalls/__sys_clone.S rename to libc/arch-arm/syscalls/__clone.S index d6b20f22d..b7ff23bcc 100644 --- a/libc/arch-arm/syscalls/__sys_clone.S +++ b/libc/arch-arm/syscalls/__clone.S @@ -4,7 +4,7 @@ #include #include -ENTRY(__sys_clone) +ENTRY(__clone) mov ip, sp .save {r4, r5, r6, r7} stmfd sp!, {r4, r5, r6, r7} @@ -16,4 +16,4 @@ ENTRY(__sys_clone) bxls lr neg r0, r0 b __set_errno -END(__sys_clone) +END(__clone) diff --git a/libc/arch-arm/syscalls/epoll_wait.S b/libc/arch-arm/syscalls/__epoll_pwait.S similarity index 51% rename from libc/arch-arm/syscalls/epoll_wait.S rename to libc/arch-arm/syscalls/__epoll_pwait.S index b2b1fef36..5eb3dab65 100644 --- a/libc/arch-arm/syscalls/epoll_wait.S +++ b/libc/arch-arm/syscalls/__epoll_pwait.S @@ -4,13 +4,16 @@ #include #include -ENTRY(epoll_wait) - mov ip, r7 - ldr r7, =__NR_epoll_wait +ENTRY(__epoll_pwait) + mov ip, sp + .save {r4, r5, r6, r7} + stmfd sp!, {r4, r5, r6, r7} + ldmfd ip, {r4, r5, r6} + ldr r7, =__NR_epoll_pwait swi #0 - mov r7, ip + ldmfd sp!, {r4, r5, r6, r7} cmn r0, #(MAX_ERRNO + 1) bxls lr neg r0, r0 b __set_errno -END(epoll_wait) +END(__epoll_pwait) diff --git a/libc/arch-arm/syscalls/__fork.S b/libc/arch-arm/syscalls/__fork.S deleted file mode 100644 index 99d795d79..000000000 --- a/libc/arch-arm/syscalls/__fork.S +++ /dev/null @@ -1,16 +0,0 @@ -/* Generated by gensyscalls.py. Do not edit. */ - -#include -#include -#include - -ENTRY(__fork) - mov ip, r7 - ldr r7, =__NR_fork - swi #0 - mov r7, ip - cmn r0, #(MAX_ERRNO + 1) - bxls lr - neg r0, r0 - b __set_errno -END(__fork) diff --git a/libc/arch-arm/syscalls/select.S b/libc/arch-arm/syscalls/__ppoll.S similarity index 86% rename from libc/arch-arm/syscalls/select.S rename to libc/arch-arm/syscalls/__ppoll.S index 26ded746d..7b833ac1b 100644 --- a/libc/arch-arm/syscalls/select.S +++ b/libc/arch-arm/syscalls/__ppoll.S @@ -4,16 +4,16 @@ #include #include -ENTRY(select) +ENTRY(__ppoll) mov ip, sp .save {r4, r5, r6, r7} stmfd sp!, {r4, r5, r6, r7} ldmfd ip, {r4, r5, r6} - ldr r7, =__NR__newselect + ldr r7, =__NR_ppoll swi #0 ldmfd sp!, {r4, r5, r6, r7} cmn r0, #(MAX_ERRNO + 1) bxls lr neg r0, r0 b __set_errno -END(select) +END(__ppoll) diff --git a/libc/arch-arm/syscalls/__open.S b/libc/arch-arm/syscalls/__pselect6.S similarity index 52% rename from libc/arch-arm/syscalls/__open.S rename to libc/arch-arm/syscalls/__pselect6.S index 20469df69..44e22eecb 100644 --- a/libc/arch-arm/syscalls/__open.S +++ b/libc/arch-arm/syscalls/__pselect6.S @@ -4,13 +4,16 @@ #include #include -ENTRY(__open) - mov ip, r7 - ldr r7, =__NR_open +ENTRY(__pselect6) + mov ip, sp + .save {r4, r5, r6, r7} + stmfd sp!, {r4, r5, r6, r7} + ldmfd ip, {r4, r5, r6} + ldr r7, =__NR_pselect6 swi #0 - mov r7, ip + ldmfd sp!, {r4, r5, r6, r7} cmn r0, #(MAX_ERRNO + 1) bxls lr neg r0, r0 b __set_errno -END(__open) +END(__pselect6) diff --git a/libc/arch-arm/syscalls/pause.S b/libc/arch-arm/syscalls/pause.S deleted file mode 100644 index 3a4b38477..000000000 --- a/libc/arch-arm/syscalls/pause.S +++ /dev/null @@ -1,16 +0,0 @@ -/* Generated by gensyscalls.py. Do not edit. */ - -#include -#include -#include - -ENTRY(pause) - mov ip, r7 - ldr r7, =__NR_pause - swi #0 - mov r7, ip - cmn r0, #(MAX_ERRNO + 1) - bxls lr - neg r0, r0 - b __set_errno -END(pause) diff --git a/libc/arch-arm/syscalls/poll.S b/libc/arch-arm/syscalls/poll.S deleted file mode 100644 index 655aced3f..000000000 --- a/libc/arch-arm/syscalls/poll.S +++ /dev/null @@ -1,16 +0,0 @@ -/* Generated by gensyscalls.py. Do not edit. */ - -#include -#include -#include - -ENTRY(poll) - mov ip, r7 - ldr r7, =__NR_poll - swi #0 - mov r7, ip - cmn r0, #(MAX_ERRNO + 1) - bxls lr - neg r0, r0 - b __set_errno -END(poll) diff --git a/libc/arch-mips/syscalls.mk b/libc/arch-mips/syscalls.mk index 34361fedb..e1c106c62 100644 --- a/libc/arch-mips/syscalls.mk +++ b/libc/arch-mips/syscalls.mk @@ -1,9 +1,10 @@ # Generated by gensyscalls.py. Do not edit. syscall_src := syscall_src += arch-mips/syscalls/__brk.S +syscall_src += arch-mips/syscalls/__clone.S +syscall_src += arch-mips/syscalls/__epoll_pwait.S syscall_src += arch-mips/syscalls/__fcntl.S syscall_src += arch-mips/syscalls/__fcntl64.S -syscall_src += arch-mips/syscalls/__fork.S syscall_src += arch-mips/syscalls/__fstatfs64.S syscall_src += arch-mips/syscalls/__getcpu.S syscall_src += arch-mips/syscalls/__getcwd.S @@ -11,8 +12,9 @@ syscall_src += arch-mips/syscalls/__getpriority.S syscall_src += arch-mips/syscalls/__ioctl.S syscall_src += arch-mips/syscalls/__llseek.S syscall_src += arch-mips/syscalls/__mmap2.S -syscall_src += arch-mips/syscalls/__open.S syscall_src += arch-mips/syscalls/__openat.S +syscall_src += arch-mips/syscalls/__ppoll.S +syscall_src += arch-mips/syscalls/__pselect6.S syscall_src += arch-mips/syscalls/__ptrace.S syscall_src += arch-mips/syscalls/__reboot.S syscall_src += arch-mips/syscalls/__rt_sigaction.S @@ -24,7 +26,6 @@ syscall_src += arch-mips/syscalls/__sched_getaffinity.S syscall_src += arch-mips/syscalls/__set_thread_area.S syscall_src += arch-mips/syscalls/__sigaction.S syscall_src += arch-mips/syscalls/__statfs64.S -syscall_src += arch-mips/syscalls/__sys_clone.S syscall_src += arch-mips/syscalls/__syslog.S syscall_src += arch-mips/syscalls/__timer_create.S syscall_src += arch-mips/syscalls/__timer_delete.S @@ -35,7 +36,6 @@ syscall_src += arch-mips/syscalls/__waitid.S syscall_src += arch-mips/syscalls/_exit.S syscall_src += arch-mips/syscalls/_exit_thread.S syscall_src += arch-mips/syscalls/_flush_cache.S -syscall_src += arch-mips/syscalls/_waitpid.S syscall_src += arch-mips/syscalls/accept.S syscall_src += arch-mips/syscalls/acct.S syscall_src += arch-mips/syscalls/bind.S @@ -54,7 +54,6 @@ syscall_src += arch-mips/syscalls/dup.S syscall_src += arch-mips/syscalls/dup3.S syscall_src += arch-mips/syscalls/epoll_create1.S syscall_src += arch-mips/syscalls/epoll_ctl.S -syscall_src += arch-mips/syscalls/epoll_wait.S syscall_src += arch-mips/syscalls/eventfd.S syscall_src += arch-mips/syscalls/execve.S syscall_src += arch-mips/syscalls/faccessat.S @@ -126,11 +125,9 @@ syscall_src += arch-mips/syscalls/munlock.S syscall_src += arch-mips/syscalls/munlockall.S syscall_src += arch-mips/syscalls/munmap.S syscall_src += arch-mips/syscalls/nanosleep.S -syscall_src += arch-mips/syscalls/pause.S syscall_src += arch-mips/syscalls/perf_event_open.S syscall_src += arch-mips/syscalls/personality.S syscall_src += arch-mips/syscalls/pipe2.S -syscall_src += arch-mips/syscalls/poll.S syscall_src += arch-mips/syscalls/prctl.S syscall_src += arch-mips/syscalls/pread64.S syscall_src += arch-mips/syscalls/pwrite64.S @@ -151,7 +148,6 @@ syscall_src += arch-mips/syscalls/sched_setaffinity.S syscall_src += arch-mips/syscalls/sched_setparam.S syscall_src += arch-mips/syscalls/sched_setscheduler.S syscall_src += arch-mips/syscalls/sched_yield.S -syscall_src += arch-mips/syscalls/select.S syscall_src += arch-mips/syscalls/sendfile.S syscall_src += arch-mips/syscalls/sendfile64.S syscall_src += arch-mips/syscalls/sendmsg.S diff --git a/libc/arch-mips/syscalls/__sys_clone.S b/libc/arch-mips/syscalls/__clone.S similarity index 78% rename from libc/arch-mips/syscalls/__sys_clone.S rename to libc/arch-mips/syscalls/__clone.S index e8b914931..5ad14897f 100644 --- a/libc/arch-mips/syscalls/__sys_clone.S +++ b/libc/arch-mips/syscalls/__clone.S @@ -2,11 +2,11 @@ #include .text - .globl __sys_clone + .globl __clone .align 4 - .ent __sys_clone + .ent __clone -__sys_clone: +__clone: .set noreorder .cpload $t9 li $v0, __NR_clone @@ -20,4 +20,4 @@ __sys_clone: j $t9 nop .set reorder - .end __sys_clone + .end __clone diff --git a/libc/arch-mips/syscalls/_waitpid.S b/libc/arch-mips/syscalls/__epoll_pwait.S similarity index 69% rename from libc/arch-mips/syscalls/_waitpid.S rename to libc/arch-mips/syscalls/__epoll_pwait.S index 6f4327d3f..0a5fdae1e 100644 --- a/libc/arch-mips/syscalls/_waitpid.S +++ b/libc/arch-mips/syscalls/__epoll_pwait.S @@ -2,14 +2,14 @@ #include .text - .globl _waitpid + .globl __epoll_pwait .align 4 - .ent _waitpid + .ent __epoll_pwait -_waitpid: +__epoll_pwait: .set noreorder .cpload $t9 - li $v0, __NR_waitpid + li $v0, __NR_epoll_pwait syscall bnez $a3, 1f move $a0, $v0 @@ -20,4 +20,4 @@ _waitpid: j $t9 nop .set reorder - .end _waitpid + .end __epoll_pwait diff --git a/libc/arch-mips/syscalls/__fork.S b/libc/arch-mips/syscalls/__ppoll.S similarity index 75% rename from libc/arch-mips/syscalls/__fork.S rename to libc/arch-mips/syscalls/__ppoll.S index a6f6e2e6e..ef6d34380 100644 --- a/libc/arch-mips/syscalls/__fork.S +++ b/libc/arch-mips/syscalls/__ppoll.S @@ -2,14 +2,14 @@ #include .text - .globl __fork + .globl __ppoll .align 4 - .ent __fork + .ent __ppoll -__fork: +__ppoll: .set noreorder .cpload $t9 - li $v0, __NR_fork + li $v0, __NR_ppoll syscall bnez $a3, 1f move $a0, $v0 @@ -20,4 +20,4 @@ __fork: j $t9 nop .set reorder - .end __fork + .end __ppoll diff --git a/libc/arch-mips/syscalls/__open.S b/libc/arch-mips/syscalls/__pselect6.S similarity index 72% rename from libc/arch-mips/syscalls/__open.S rename to libc/arch-mips/syscalls/__pselect6.S index abd046545..26af92a10 100644 --- a/libc/arch-mips/syscalls/__open.S +++ b/libc/arch-mips/syscalls/__pselect6.S @@ -2,14 +2,14 @@ #include .text - .globl __open + .globl __pselect6 .align 4 - .ent __open + .ent __pselect6 -__open: +__pselect6: .set noreorder .cpload $t9 - li $v0, __NR_open + li $v0, __NR_pselect6 syscall bnez $a3, 1f move $a0, $v0 @@ -20,4 +20,4 @@ __open: j $t9 nop .set reorder - .end __open + .end __pselect6 diff --git a/libc/arch-mips/syscalls/epoll_wait.S b/libc/arch-mips/syscalls/epoll_wait.S deleted file mode 100644 index bbe7419cf..000000000 --- a/libc/arch-mips/syscalls/epoll_wait.S +++ /dev/null @@ -1,23 +0,0 @@ -/* Generated by gensyscalls.py. Do not edit. */ - -#include - .text - .globl epoll_wait - .align 4 - .ent epoll_wait - -epoll_wait: - .set noreorder - .cpload $t9 - li $v0, __NR_epoll_wait - syscall - bnez $a3, 1f - move $a0, $v0 - j $ra - nop -1: - la $t9,__set_errno - j $t9 - nop - .set reorder - .end epoll_wait diff --git a/libc/arch-mips/syscalls/pause.S b/libc/arch-mips/syscalls/pause.S deleted file mode 100644 index 4f0a2a3d7..000000000 --- a/libc/arch-mips/syscalls/pause.S +++ /dev/null @@ -1,23 +0,0 @@ -/* Generated by gensyscalls.py. Do not edit. */ - -#include - .text - .globl pause - .align 4 - .ent pause - -pause: - .set noreorder - .cpload $t9 - li $v0, __NR_pause - syscall - bnez $a3, 1f - move $a0, $v0 - j $ra - nop -1: - la $t9,__set_errno - j $t9 - nop - .set reorder - .end pause diff --git a/libc/arch-mips/syscalls/poll.S b/libc/arch-mips/syscalls/poll.S deleted file mode 100644 index 6a1ebf802..000000000 --- a/libc/arch-mips/syscalls/poll.S +++ /dev/null @@ -1,23 +0,0 @@ -/* Generated by gensyscalls.py. Do not edit. */ - -#include - .text - .globl poll - .align 4 - .ent poll - -poll: - .set noreorder - .cpload $t9 - li $v0, __NR_poll - syscall - bnez $a3, 1f - move $a0, $v0 - j $ra - nop -1: - la $t9,__set_errno - j $t9 - nop - .set reorder - .end poll diff --git a/libc/arch-mips/syscalls/select.S b/libc/arch-mips/syscalls/select.S deleted file mode 100644 index d7cfea7e3..000000000 --- a/libc/arch-mips/syscalls/select.S +++ /dev/null @@ -1,23 +0,0 @@ -/* Generated by gensyscalls.py. Do not edit. */ - -#include - .text - .globl select - .align 4 - .ent select - -select: - .set noreorder - .cpload $t9 - li $v0, __NR__newselect - syscall - bnez $a3, 1f - move $a0, $v0 - j $ra - nop -1: - la $t9,__set_errno - j $t9 - nop - .set reorder - .end select diff --git a/libc/arch-x86/syscalls.mk b/libc/arch-x86/syscalls.mk index 471dbb973..3b8586b22 100644 --- a/libc/arch-x86/syscalls.mk +++ b/libc/arch-x86/syscalls.mk @@ -1,9 +1,10 @@ # Generated by gensyscalls.py. Do not edit. syscall_src := syscall_src += arch-x86/syscalls/__brk.S +syscall_src += arch-x86/syscalls/__clone.S +syscall_src += arch-x86/syscalls/__epoll_pwait.S syscall_src += arch-x86/syscalls/__fcntl.S syscall_src += arch-x86/syscalls/__fcntl64.S -syscall_src += arch-x86/syscalls/__fork.S syscall_src += arch-x86/syscalls/__fstatfs64.S syscall_src += arch-x86/syscalls/__getcpu.S syscall_src += arch-x86/syscalls/__getcwd.S @@ -11,8 +12,9 @@ syscall_src += arch-x86/syscalls/__getpriority.S syscall_src += arch-x86/syscalls/__ioctl.S syscall_src += arch-x86/syscalls/__llseek.S syscall_src += arch-x86/syscalls/__mmap2.S -syscall_src += arch-x86/syscalls/__open.S syscall_src += arch-x86/syscalls/__openat.S +syscall_src += arch-x86/syscalls/__ppoll.S +syscall_src += arch-x86/syscalls/__pselect6.S syscall_src += arch-x86/syscalls/__ptrace.S syscall_src += arch-x86/syscalls/__reboot.S syscall_src += arch-x86/syscalls/__rt_sigaction.S @@ -24,7 +26,6 @@ syscall_src += arch-x86/syscalls/__sched_getaffinity.S syscall_src += arch-x86/syscalls/__set_thread_area.S syscall_src += arch-x86/syscalls/__sigaction.S syscall_src += arch-x86/syscalls/__statfs64.S -syscall_src += arch-x86/syscalls/__sys_clone.S syscall_src += arch-x86/syscalls/__syslog.S syscall_src += arch-x86/syscalls/__timer_create.S syscall_src += arch-x86/syscalls/__timer_delete.S @@ -34,7 +35,6 @@ syscall_src += arch-x86/syscalls/__timer_settime.S syscall_src += arch-x86/syscalls/__waitid.S syscall_src += arch-x86/syscalls/_exit.S syscall_src += arch-x86/syscalls/_exit_thread.S -syscall_src += arch-x86/syscalls/_waitpid.S syscall_src += arch-x86/syscalls/accept.S syscall_src += arch-x86/syscalls/acct.S syscall_src += arch-x86/syscalls/bind.S @@ -53,7 +53,6 @@ syscall_src += arch-x86/syscalls/dup.S syscall_src += arch-x86/syscalls/dup3.S syscall_src += arch-x86/syscalls/epoll_create1.S syscall_src += arch-x86/syscalls/epoll_ctl.S -syscall_src += arch-x86/syscalls/epoll_wait.S syscall_src += arch-x86/syscalls/eventfd.S syscall_src += arch-x86/syscalls/execve.S syscall_src += arch-x86/syscalls/faccessat.S @@ -125,11 +124,9 @@ syscall_src += arch-x86/syscalls/munlock.S syscall_src += arch-x86/syscalls/munlockall.S syscall_src += arch-x86/syscalls/munmap.S syscall_src += arch-x86/syscalls/nanosleep.S -syscall_src += arch-x86/syscalls/pause.S syscall_src += arch-x86/syscalls/perf_event_open.S syscall_src += arch-x86/syscalls/personality.S syscall_src += arch-x86/syscalls/pipe2.S -syscall_src += arch-x86/syscalls/poll.S syscall_src += arch-x86/syscalls/prctl.S syscall_src += arch-x86/syscalls/pread64.S syscall_src += arch-x86/syscalls/pwrite64.S @@ -150,7 +147,6 @@ syscall_src += arch-x86/syscalls/sched_setaffinity.S syscall_src += arch-x86/syscalls/sched_setparam.S syscall_src += arch-x86/syscalls/sched_setscheduler.S syscall_src += arch-x86/syscalls/sched_yield.S -syscall_src += arch-x86/syscalls/select.S syscall_src += arch-x86/syscalls/sendfile.S syscall_src += arch-x86/syscalls/sendfile64.S syscall_src += arch-x86/syscalls/sendmsg.S diff --git a/libc/arch-x86/syscalls/__sys_clone.S b/libc/arch-x86/syscalls/__clone.S similarity index 94% rename from libc/arch-x86/syscalls/__sys_clone.S rename to libc/arch-x86/syscalls/__clone.S index 3080a8762..c2e8ed8b0 100644 --- a/libc/arch-x86/syscalls/__sys_clone.S +++ b/libc/arch-x86/syscalls/__clone.S @@ -4,7 +4,7 @@ #include #include -ENTRY(__sys_clone) +ENTRY(__clone) pushl %ebx pushl %ecx pushl %edx @@ -31,4 +31,4 @@ ENTRY(__sys_clone) popl %ecx popl %ebx ret -END(__sys_clone) +END(__clone) diff --git a/libc/arch-x86/syscalls/_waitpid.S b/libc/arch-x86/syscalls/__epoll_pwait.S similarity index 58% rename from libc/arch-x86/syscalls/_waitpid.S rename to libc/arch-x86/syscalls/__epoll_pwait.S index b83b986c9..9dc07f64e 100644 --- a/libc/arch-x86/syscalls/_waitpid.S +++ b/libc/arch-x86/syscalls/__epoll_pwait.S @@ -4,16 +4,20 @@ #include #include -ENTRY(_waitpid) +ENTRY(__epoll_pwait) pushl %ebx pushl %ecx pushl %edx pushl %esi - mov 20(%esp), %ebx - mov 24(%esp), %ecx - mov 28(%esp), %edx - mov 32(%esp), %esi - movl $__NR_waitpid, %eax + pushl %edi + pushl %ebp + mov 28(%esp), %ebx + mov 32(%esp), %ecx + mov 36(%esp), %edx + mov 40(%esp), %esi + mov 44(%esp), %edi + mov 48(%esp), %ebp + movl $__NR_epoll_pwait, %eax int $0x80 cmpl $-MAX_ERRNO, %eax jb 1f @@ -23,9 +27,11 @@ ENTRY(_waitpid) addl $4, %esp orl $-1, %eax 1: + popl %ebp + popl %edi popl %esi popl %edx popl %ecx popl %ebx ret -END(_waitpid) +END(__epoll_pwait) diff --git a/libc/arch-x86/syscalls/__fork.S b/libc/arch-x86/syscalls/__fork.S deleted file mode 100644 index af737c7c9..000000000 --- a/libc/arch-x86/syscalls/__fork.S +++ /dev/null @@ -1,22 +0,0 @@ -/* Generated by gensyscalls.py. Do not edit. */ - -#include -#include -#include - -ENTRY(__fork) - pushl %ebx - mov 8(%esp), %ebx - movl $__NR_fork, %eax - int $0x80 - cmpl $-MAX_ERRNO, %eax - jb 1f - negl %eax - pushl %eax - call __set_errno - addl $4, %esp - orl $-1, %eax -1: - popl %ebx - ret -END(__fork) diff --git a/libc/arch-x86/syscalls/__open.S b/libc/arch-x86/syscalls/__open.S deleted file mode 100644 index be286d279..000000000 --- a/libc/arch-x86/syscalls/__open.S +++ /dev/null @@ -1,28 +0,0 @@ -/* Generated by gensyscalls.py. Do not edit. */ - -#include -#include -#include - -ENTRY(__open) - pushl %ebx - pushl %ecx - pushl %edx - mov 16(%esp), %ebx - mov 20(%esp), %ecx - mov 24(%esp), %edx - movl $__NR_open, %eax - int $0x80 - cmpl $-MAX_ERRNO, %eax - jb 1f - negl %eax - pushl %eax - call __set_errno - addl $4, %esp - orl $-1, %eax -1: - popl %edx - popl %ecx - popl %ebx - ret -END(__open) diff --git a/libc/arch-x86/syscalls/select.S b/libc/arch-x86/syscalls/__ppoll.S similarity index 90% rename from libc/arch-x86/syscalls/select.S rename to libc/arch-x86/syscalls/__ppoll.S index a67ffa509..6445fb51e 100644 --- a/libc/arch-x86/syscalls/select.S +++ b/libc/arch-x86/syscalls/__ppoll.S @@ -4,7 +4,7 @@ #include #include -ENTRY(select) +ENTRY(__ppoll) pushl %ebx pushl %ecx pushl %edx @@ -15,7 +15,7 @@ ENTRY(select) mov 32(%esp), %edx mov 36(%esp), %esi mov 40(%esp), %edi - movl $__NR__newselect, %eax + movl $__NR_ppoll, %eax int $0x80 cmpl $-MAX_ERRNO, %eax jb 1f @@ -31,4 +31,4 @@ ENTRY(select) popl %ecx popl %ebx ret -END(select) +END(__ppoll) diff --git a/libc/arch-x86/syscalls/epoll_wait.S b/libc/arch-x86/syscalls/__pselect6.S similarity index 59% rename from libc/arch-x86/syscalls/epoll_wait.S rename to libc/arch-x86/syscalls/__pselect6.S index e0c7a6dcf..8faa2dacb 100644 --- a/libc/arch-x86/syscalls/epoll_wait.S +++ b/libc/arch-x86/syscalls/__pselect6.S @@ -4,16 +4,20 @@ #include #include -ENTRY(epoll_wait) +ENTRY(__pselect6) pushl %ebx pushl %ecx pushl %edx pushl %esi - mov 20(%esp), %ebx - mov 24(%esp), %ecx - mov 28(%esp), %edx - mov 32(%esp), %esi - movl $__NR_epoll_wait, %eax + pushl %edi + pushl %ebp + mov 28(%esp), %ebx + mov 32(%esp), %ecx + mov 36(%esp), %edx + mov 40(%esp), %esi + mov 44(%esp), %edi + mov 48(%esp), %ebp + movl $__NR_pselect6, %eax int $0x80 cmpl $-MAX_ERRNO, %eax jb 1f @@ -23,9 +27,11 @@ ENTRY(epoll_wait) addl $4, %esp orl $-1, %eax 1: + popl %ebp + popl %edi popl %esi popl %edx popl %ecx popl %ebx ret -END(epoll_wait) +END(__pselect6) diff --git a/libc/arch-x86/syscalls/pause.S b/libc/arch-x86/syscalls/pause.S deleted file mode 100644 index 3ce05d525..000000000 --- a/libc/arch-x86/syscalls/pause.S +++ /dev/null @@ -1,19 +0,0 @@ -/* Generated by gensyscalls.py. Do not edit. */ - -#include -#include -#include - -ENTRY(pause) - movl $__NR_pause, %eax - int $0x80 - cmpl $-MAX_ERRNO, %eax - jb 1f - negl %eax - pushl %eax - call __set_errno - addl $4, %esp - orl $-1, %eax -1: - ret -END(pause) diff --git a/libc/arch-x86/syscalls/poll.S b/libc/arch-x86/syscalls/poll.S deleted file mode 100644 index 273062a49..000000000 --- a/libc/arch-x86/syscalls/poll.S +++ /dev/null @@ -1,28 +0,0 @@ -/* Generated by gensyscalls.py. Do not edit. */ - -#include -#include -#include - -ENTRY(poll) - pushl %ebx - pushl %ecx - pushl %edx - mov 16(%esp), %ebx - mov 20(%esp), %ecx - mov 24(%esp), %edx - movl $__NR_poll, %eax - int $0x80 - cmpl $-MAX_ERRNO, %eax - jb 1f - negl %eax - pushl %eax - call __set_errno - addl $4, %esp - orl $-1, %eax -1: - popl %edx - popl %ecx - popl %ebx - ret -END(poll) diff --git a/libc/arch-x86_64/syscalls.mk b/libc/arch-x86_64/syscalls.mk index 44ef7299a..1ec3e0981 100644 --- a/libc/arch-x86_64/syscalls.mk +++ b/libc/arch-x86_64/syscalls.mk @@ -2,12 +2,15 @@ syscall_src := syscall_src += arch-x86_64/syscalls/__arch_prctl.S syscall_src += arch-x86_64/syscalls/__brk.S -syscall_src += arch-x86_64/syscalls/__fork.S +syscall_src += arch-x86_64/syscalls/__clone.S +syscall_src += arch-x86_64/syscalls/__epoll_pwait.S syscall_src += arch-x86_64/syscalls/__getcpu.S syscall_src += arch-x86_64/syscalls/__getcwd.S syscall_src += arch-x86_64/syscalls/__getpriority.S syscall_src += arch-x86_64/syscalls/__ioctl.S syscall_src += arch-x86_64/syscalls/__openat.S +syscall_src += arch-x86_64/syscalls/__ppoll.S +syscall_src += arch-x86_64/syscalls/__pselect6.S syscall_src += arch-x86_64/syscalls/__ptrace.S syscall_src += arch-x86_64/syscalls/__reboot.S syscall_src += arch-x86_64/syscalls/__rt_sigaction.S @@ -16,7 +19,6 @@ syscall_src += arch-x86_64/syscalls/__rt_sigprocmask.S syscall_src += arch-x86_64/syscalls/__rt_sigsuspend.S syscall_src += arch-x86_64/syscalls/__rt_sigtimedwait.S syscall_src += arch-x86_64/syscalls/__sched_getaffinity.S -syscall_src += arch-x86_64/syscalls/__sys_clone.S syscall_src += arch-x86_64/syscalls/__syslog.S syscall_src += arch-x86_64/syscalls/__timer_create.S syscall_src += arch-x86_64/syscalls/__timer_delete.S @@ -44,7 +46,6 @@ syscall_src += arch-x86_64/syscalls/dup.S syscall_src += arch-x86_64/syscalls/dup3.S syscall_src += arch-x86_64/syscalls/epoll_create1.S syscall_src += arch-x86_64/syscalls/epoll_ctl.S -syscall_src += arch-x86_64/syscalls/epoll_wait.S syscall_src += arch-x86_64/syscalls/eventfd.S syscall_src += arch-x86_64/syscalls/execve.S syscall_src += arch-x86_64/syscalls/faccessat.S @@ -118,11 +119,9 @@ syscall_src += arch-x86_64/syscalls/munlock.S syscall_src += arch-x86_64/syscalls/munlockall.S syscall_src += arch-x86_64/syscalls/munmap.S syscall_src += arch-x86_64/syscalls/nanosleep.S -syscall_src += arch-x86_64/syscalls/pause.S syscall_src += arch-x86_64/syscalls/perf_event_open.S syscall_src += arch-x86_64/syscalls/personality.S syscall_src += arch-x86_64/syscalls/pipe2.S -syscall_src += arch-x86_64/syscalls/poll.S syscall_src += arch-x86_64/syscalls/prctl.S syscall_src += arch-x86_64/syscalls/pread64.S syscall_src += arch-x86_64/syscalls/pwrite64.S @@ -143,7 +142,6 @@ syscall_src += arch-x86_64/syscalls/sched_setaffinity.S syscall_src += arch-x86_64/syscalls/sched_setparam.S syscall_src += arch-x86_64/syscalls/sched_setscheduler.S syscall_src += arch-x86_64/syscalls/sched_yield.S -syscall_src += arch-x86_64/syscalls/select.S syscall_src += arch-x86_64/syscalls/sendfile.S syscall_src += arch-x86_64/syscalls/sendmsg.S syscall_src += arch-x86_64/syscalls/sendto.S diff --git a/libc/arch-x86_64/syscalls/__sys_clone.S b/libc/arch-x86_64/syscalls/__clone.S similarity index 90% rename from libc/arch-x86_64/syscalls/__sys_clone.S rename to libc/arch-x86_64/syscalls/__clone.S index 314440bc6..c10402acf 100644 --- a/libc/arch-x86_64/syscalls/__sys_clone.S +++ b/libc/arch-x86_64/syscalls/__clone.S @@ -4,7 +4,7 @@ #include #include -ENTRY(__sys_clone) +ENTRY(__clone) movq %rcx, %r10 movl $__NR_clone, %eax syscall @@ -16,4 +16,4 @@ ENTRY(__sys_clone) orq $-1, %rax 1: ret -END(__sys_clone) +END(__clone) diff --git a/libc/arch-x86_64/syscalls/pause.S b/libc/arch-x86_64/syscalls/__epoll_pwait.S similarity index 73% rename from libc/arch-x86_64/syscalls/pause.S rename to libc/arch-x86_64/syscalls/__epoll_pwait.S index 9f0332706..98f34657e 100644 --- a/libc/arch-x86_64/syscalls/pause.S +++ b/libc/arch-x86_64/syscalls/__epoll_pwait.S @@ -4,8 +4,9 @@ #include #include -ENTRY(pause) - movl $__NR_pause, %eax +ENTRY(__epoll_pwait) + movq %rcx, %r10 + movl $__NR_epoll_pwait, %eax syscall cmpq $-MAX_ERRNO, %rax jb 1f @@ -15,4 +16,4 @@ ENTRY(pause) orq $-1, %rax 1: ret -END(pause) +END(__epoll_pwait) diff --git a/libc/arch-x86_64/syscalls/__fork.S b/libc/arch-x86_64/syscalls/__fork.S deleted file mode 100644 index dcadec34b..000000000 --- a/libc/arch-x86_64/syscalls/__fork.S +++ /dev/null @@ -1,18 +0,0 @@ -/* Generated by gensyscalls.py. Do not edit. */ - -#include -#include -#include - -ENTRY(__fork) - movl $__NR_fork, %eax - syscall - cmpq $-MAX_ERRNO, %rax - jb 1f - negl %eax - movl %eax, %edi - call __set_errno - orq $-1, %rax -1: - ret -END(__fork) diff --git a/libc/arch-x86_64/syscalls/select.S b/libc/arch-x86_64/syscalls/__ppoll.S similarity index 83% rename from libc/arch-x86_64/syscalls/select.S rename to libc/arch-x86_64/syscalls/__ppoll.S index 1cea5c687..c6c055ba9 100644 --- a/libc/arch-x86_64/syscalls/select.S +++ b/libc/arch-x86_64/syscalls/__ppoll.S @@ -4,9 +4,9 @@ #include #include -ENTRY(select) +ENTRY(__ppoll) movq %rcx, %r10 - movl $__NR_select, %eax + movl $__NR_ppoll, %eax syscall cmpq $-MAX_ERRNO, %rax jb 1f @@ -16,4 +16,4 @@ ENTRY(select) orq $-1, %rax 1: ret -END(select) +END(__ppoll) diff --git a/libc/arch-x86_64/syscalls/epoll_wait.S b/libc/arch-x86_64/syscalls/__pselect6.S similarity index 81% rename from libc/arch-x86_64/syscalls/epoll_wait.S rename to libc/arch-x86_64/syscalls/__pselect6.S index d3e6a6f83..b0bb8bafe 100644 --- a/libc/arch-x86_64/syscalls/epoll_wait.S +++ b/libc/arch-x86_64/syscalls/__pselect6.S @@ -4,9 +4,9 @@ #include #include -ENTRY(epoll_wait) +ENTRY(__pselect6) movq %rcx, %r10 - movl $__NR_epoll_wait, %eax + movl $__NR_pselect6, %eax syscall cmpq $-MAX_ERRNO, %rax jb 1f @@ -16,4 +16,4 @@ ENTRY(epoll_wait) orq $-1, %rax 1: ret -END(epoll_wait) +END(__pselect6) diff --git a/libc/arch-x86_64/syscalls/poll.S b/libc/arch-x86_64/syscalls/poll.S deleted file mode 100644 index 48130c33d..000000000 --- a/libc/arch-x86_64/syscalls/poll.S +++ /dev/null @@ -1,18 +0,0 @@ -/* Generated by gensyscalls.py. Do not edit. */ - -#include -#include -#include - -ENTRY(poll) - movl $__NR_poll, %eax - syscall - cmpq $-MAX_ERRNO, %rax - jb 1f - negl %eax - movl %eax, %edi - call __set_errno - orq $-1, %rax -1: - ret -END(poll) diff --git a/libc/bionic/pselect.c b/libc/bionic/bionic_time_conversions.cpp similarity index 60% rename from libc/bionic/pselect.c rename to libc/bionic/bionic_time_conversions.cpp index 76ce2c084..7f3c026e2 100644 --- a/libc/bionic/pselect.c +++ b/libc/bionic/bionic_time_conversions.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 The Android Open Source Project + * Copyright (C) 2013 The Android Open Source Project * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -25,35 +25,27 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -#include -#include -#include -int -pselect(int n, fd_set* readfds, fd_set* writefds, fd_set* errfds, - const struct timespec* timeout, const sigset_t* sigmask) -{ - sigset_t oldmask; - int result; - struct timeval tv, *tv_timeout = NULL; +#include "private/bionic_time_conversions.h" - if (sigmask != NULL) - pthread_sigmask( SIG_SETMASK, sigmask, &oldmask ); +bool timespec_from_timeval(timespec& ts, const timeval& tv) { + // Whole seconds can just be copied. + ts.tv_sec = tv.tv_sec; - if (timeout != NULL) { - tv_timeout = &tv; - tv.tv_sec = timeout->tv_sec; - tv.tv_usec = (timeout->tv_nsec + 999)/1000; // round up - if (tv.tv_usec >= 1000000) { - tv.tv_sec += 1; - tv.tv_usec -= 1000000; - } - } - - result = select( n, readfds, writefds, errfds, tv_timeout ); - - if (sigmask != NULL) - pthread_sigmask( SIG_SETMASK, &oldmask, NULL ); - - return result; + // But we might overflow when converting microseconds to nanoseconds. + if (tv.tv_usec >= 1000000 || tv.tv_usec < 0) { + return false; + } + ts.tv_nsec = tv.tv_usec * 1000; + return true; +} + +void timespec_from_ms(timespec& ts, const int ms) { + ts.tv_sec = ms / 1000; + ts.tv_nsec = (ms % 1000) * 1000000; +} + +void timeval_from_timespec(timeval& tv, const timespec& ts) { + tv.tv_sec = ts.tv_sec; + tv.tv_usec = ts.tv_nsec / 1000; } diff --git a/libc/bionic/epoll_pwait.cpp b/libc/bionic/epoll_pwait.cpp new file mode 100644 index 000000000..f3af93ef2 --- /dev/null +++ b/libc/bionic/epoll_pwait.cpp @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include + +#include "private/kernel_sigset_t.h" + +extern "C" int __epoll_pwait(int, epoll_event*, int, int, const kernel_sigset_t*, size_t); + +int epoll_pwait(int fd, epoll_event* events, int max_events, int timeout, const sigset_t* ss) { + kernel_sigset_t kernel_ss; + kernel_sigset_t* kernel_ss_ptr = NULL; + if (ss != NULL) { + kernel_ss.set(ss); + kernel_ss_ptr = &kernel_ss; + } + return __epoll_pwait(fd, events, max_events, timeout, kernel_ss_ptr, sizeof(kernel_ss)); +} diff --git a/libc/bionic/epoll_wait.cpp b/libc/bionic/epoll_wait.cpp new file mode 100644 index 000000000..deb19daf2 --- /dev/null +++ b/libc/bionic/epoll_wait.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include + +int epoll_wait(int fd, struct epoll_event* events, int max_events, int timeout) { + return epoll_pwait(fd, events, max_events, timeout, NULL); +} diff --git a/libc/bionic/fork.cpp b/libc/bionic/fork.cpp index a3bea2094..339a0e830 100644 --- a/libc/bionic/fork.cpp +++ b/libc/bionic/fork.cpp @@ -31,7 +31,7 @@ #include "private/bionic_pthread.h" -extern "C" int __fork(); +extern "C" int __clone(int, void*, int*, void*, int*); int fork() { // POSIX mandates that the timers of a fork child process be @@ -41,7 +41,7 @@ int fork() { __timer_table_start_stop(1); __bionic_atfork_run_prepare(); - int result = __fork(); + int result = __clone(SIGCHLD, NULL, NULL, NULL, NULL); if (result != 0) { // Not a child process. __timer_table_start_stop(0); __bionic_atfork_run_parent(); diff --git a/libc/bionic/pause.cpp b/libc/bionic/pause.cpp new file mode 100644 index 000000000..94a16fbfa --- /dev/null +++ b/libc/bionic/pause.cpp @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include + +#include "private/kernel_sigset_t.h" + +extern "C" int __rt_sigprocmask(int, const kernel_sigset_t*, kernel_sigset_t*, size_t); +extern "C" int __rt_sigsuspend(const kernel_sigset_t*, size_t); + +int pause() { + kernel_sigset_t mask; + if (__rt_sigprocmask(SIG_SETMASK, NULL, &mask, sizeof(mask)) == -1) { + return -1; + } + return __rt_sigsuspend(&mask, sizeof(mask)); +} diff --git a/libc/bionic/poll.cpp b/libc/bionic/poll.cpp new file mode 100644 index 000000000..ebb318d92 --- /dev/null +++ b/libc/bionic/poll.cpp @@ -0,0 +1,110 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include + +#include "private/bionic_time_conversions.h" +#include "private/kernel_sigset_t.h" + +extern "C" int __ppoll(pollfd*, unsigned int, timespec*, const kernel_sigset_t*, size_t); +extern "C" int __pselect6(int, fd_set*, fd_set*, fd_set*, timespec*, void*); + +int poll(pollfd* fds, nfds_t fd_count, int ms) { + timespec ts; + timespec* ts_ptr = NULL; + if (ms >= 0) { + timespec_from_ms(ts, ms); + ts_ptr = &ts; + } + return __ppoll(fds, fd_count, ts_ptr, NULL, 0); +} + +int ppoll(pollfd* fds, nfds_t fd_count, const timespec* ts, const sigset_t* ss) { + timespec mutable_ts; + timespec* mutable_ts_ptr = NULL; + if (ts != NULL) { + mutable_ts = *ts; + mutable_ts_ptr = &mutable_ts; + } + + kernel_sigset_t kernel_ss; + kernel_sigset_t* kernel_ss_ptr = NULL; + if (ss != NULL) { + kernel_ss.set(ss); + kernel_ss_ptr = &kernel_ss; + } + + return __ppoll(fds, fd_count, mutable_ts_ptr, kernel_ss_ptr, sizeof(kernel_ss)); +} + +int select(int fd_count, fd_set* read_fds, fd_set* write_fds, fd_set* error_fds, timeval* tv) { + timespec ts; + timespec* ts_ptr = NULL; + if (tv != NULL) { + if (!timespec_from_timeval(ts, *tv)) { + errno = EINVAL; + return -1; + } + ts_ptr = &ts; + } + int result = __pselect6(fd_count, read_fds, write_fds, error_fds, ts_ptr, NULL); + if (tv != NULL) { + timeval_from_timespec(*tv, ts); + } + return result; +} + +int pselect(int fd_count, fd_set* read_fds, fd_set* write_fds, fd_set* error_fds, + const timespec* ts, const sigset_t* ss) { + timespec mutable_ts; + timespec* mutable_ts_ptr = NULL; + if (ts != NULL) { + mutable_ts = *ts; + mutable_ts_ptr = &mutable_ts; + } + + kernel_sigset_t kernel_ss; + kernel_sigset_t* kernel_ss_ptr = NULL; + if (ss != NULL) { + kernel_ss.set(ss); + kernel_ss_ptr = &kernel_ss; + } + + // The Linux kernel only handles 6 arguments and this system call really needs 7, + // so the last argument is a void* pointing to: + struct pselect6_extra_data_t { + uintptr_t ss_addr; + size_t ss_len; + }; + pselect6_extra_data_t extra_data; + extra_data.ss_addr = reinterpret_cast(kernel_ss_ptr); + extra_data.ss_len = sizeof(kernel_ss); + + return __pselect6(fd_count, read_fds, write_fds, error_fds, mutable_ts_ptr, &extra_data); +} diff --git a/libc/bionic/pthread.c b/libc/bionic/pthread.c index 7081445a8..4a4676aec 100644 --- a/libc/bionic/pthread.c +++ b/libc/bionic/pthread.c @@ -1176,13 +1176,10 @@ int pthread_cond_timedwait_relative_np(pthread_cond_t *cond, int pthread_cond_timeout_np(pthread_cond_t *cond, pthread_mutex_t * mutex, - unsigned msecs) + unsigned ms) { struct timespec ts; - - ts.tv_sec = msecs / 1000; - ts.tv_nsec = (msecs % 1000) * 1000000; - + timespec_from_ms(ts, ms); return __pthread_cond_timedwait_relative(cond, mutex, &ts); } diff --git a/libc/bionic/utimes.cpp b/libc/bionic/utimes.cpp index 315765ac6..8950972a6 100644 --- a/libc/bionic/utimes.cpp +++ b/libc/bionic/utimes.cpp @@ -30,21 +30,13 @@ #include #include +#include "private/bionic_time_conversions.h" + int utimes(const char* path, const timeval tv[2]) { timespec ts[2]; - - // Whole seconds can just be copied. - ts[0].tv_sec = tv[0].tv_sec; - ts[1].tv_sec = tv[1].tv_sec; - - // But we might overflow when converting microseconds to nanoseconds. - if (tv[0].tv_usec >= 1000000 || tv[0].tv_usec < 0 || - tv[1].tv_usec >= 1000000 || tv[1].tv_usec < 0) { + if (!timespec_from_timeval(ts[0], tv[0]) || !timespec_from_timeval(ts[1], tv[1])) { errno = EINVAL; return -1; } - ts[0].tv_nsec = tv[0].tv_usec * 1000; - ts[1].tv_nsec = tv[1].tv_usec * 1000; - return utimensat(AT_FDCWD, path, ts, 0); } diff --git a/libc/bionic/wait.cpp b/libc/bionic/wait.cpp index 7dbcec29a..27453bbc3 100644 --- a/libc/bionic/wait.cpp +++ b/libc/bionic/wait.cpp @@ -44,7 +44,7 @@ pid_t waitpid(pid_t pid, int* status, int options) { } int waitid(idtype_t which, id_t id, siginfo_t* info, int options) { - /* the system call takes an option struct rusage that we don't need */ + // The system call takes an optional struct rusage that we don't need. return __waitid(which, id, info, options, NULL); } diff --git a/libc/include/poll.h b/libc/include/poll.h index 560be8979..0199cab2c 100644 --- a/libc/include/poll.h +++ b/libc/include/poll.h @@ -25,18 +25,21 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ + #ifndef _POLL_H_ #define _POLL_H_ #include #include +#include /* For sigset_t. */ +#include /* For timespec. */ __BEGIN_DECLS -typedef unsigned int nfds_t; +typedef unsigned int nfds_t; -/* POSIX specifies "int" for the timeout, Linux seems to use long... */ -extern int poll(struct pollfd *, nfds_t, long); +extern int poll(struct pollfd*, nfds_t, int); +extern int ppoll(struct pollfd*, nfds_t, const struct timespec*, const sigset_t*); __END_DECLS diff --git a/libc/include/sys/epoll.h b/libc/include/sys/epoll.h index 1e207d856..c06a081f0 100644 --- a/libc/include/sys/epoll.h +++ b/libc/include/sys/epoll.h @@ -31,7 +31,8 @@ #include #include -#include /* For O_CLOEXEC. */ +#include /* For O_CLOEXEC. */ +#include /* For sigset_t. */ __BEGIN_DECLS @@ -56,24 +57,23 @@ __BEGIN_DECLS #define EPOLL_CLOEXEC O_CLOEXEC -typedef union epoll_data -{ - void *ptr; - int fd; - unsigned int u32; - unsigned long long u64; +typedef union epoll_data { + void* ptr; + int fd; + uint32_t u32; + uint64_t u64; } epoll_data_t; -struct epoll_event -{ - unsigned int events; - epoll_data_t data; +struct epoll_event { + uint32_t events; + epoll_data_t data; }; -int epoll_create(int size); -int epoll_create1(int flags); -int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event); -int epoll_wait(int epfd, struct epoll_event *events, int max, int timeout); +int epoll_create(int); +int epoll_create1(int); +int epoll_ctl(int, int, int, struct epoll_event*); +int epoll_wait(int, struct epoll_event*, int, int); +int epoll_pwait(int, struct epoll_event*, int, int, const sigset_t*); __END_DECLS diff --git a/libc/private/bionic_time_conversions.h b/libc/private/bionic_time_conversions.h new file mode 100644 index 000000000..51f543f5d --- /dev/null +++ b/libc/private/bionic_time_conversions.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _BIONIC_TIME_CONVERSIONS_H +#define _BIONIC_TIME_CONVERSIONS_H + +#include +#include + +__BEGIN_DECLS + +__LIBC_HIDDEN__ bool timespec_from_timeval(timespec& ts, const timeval& tv); +__LIBC_HIDDEN__ void timespec_from_ms(timespec& ts, const int ms); + +__LIBC_HIDDEN__ void timeval_from_timespec(timeval& tv, const timespec& ts); + +__END_DECLS + +#endif diff --git a/libc/private/kernel_sigset_t.h b/libc/private/kernel_sigset_t.h index 733a84256..b2d6386f3 100644 --- a/libc/private/kernel_sigset_t.h +++ b/libc/private/kernel_sigset_t.h @@ -32,7 +32,7 @@ union kernel_sigset_t { } void clear() { - memset(this, 0, sizeof(*this)); + __builtin_memset(this, 0, sizeof(*this)); } void set(const sigset_t* value) { diff --git a/tests/Android.mk b/tests/Android.mk index 5bcf996c4..f1174808c 100644 --- a/tests/Android.mk +++ b/tests/Android.mk @@ -81,6 +81,7 @@ test_src_files = \ string_test.cpp \ strings_test.cpp \ stubs_test.cpp \ + sys_epoll_test.cpp \ sys_select_test.cpp \ sys_sendfile_test.cpp \ sys_stat_test.cpp \ diff --git a/tests/signal_test.cpp b/tests/signal_test.cpp index 3070747c1..7705e2c49 100644 --- a/tests/signal_test.cpp +++ b/tests/signal_test.cpp @@ -170,8 +170,6 @@ static void SigSuspendTestHelper(int) { } TEST(signal, sigsuspend_sigpending) { - ScopedSignalHandler ssh(SIGALRM, SigSuspendTestHelper); - // Block SIGALRM. sigset_t just_SIGALRM; sigemptyset(&just_SIGALRM); @@ -179,6 +177,8 @@ TEST(signal, sigsuspend_sigpending) { sigset_t original_set; ASSERT_EQ(0, sigprocmask(SIG_BLOCK, &just_SIGALRM, &original_set)); + ScopedSignalHandler ssh(SIGALRM, SigSuspendTestHelper); + // There should be no pending signals. sigset_t pending; sigemptyset(&pending); @@ -208,7 +208,7 @@ TEST(signal, sigsuspend_sigpending) { ASSERT_EQ(1, gSigSuspendTestHelperCallCount); // Restore the original set. - assert(0 == sigprocmask(SIG_SETMASK, &original_set, NULL)); + ASSERT_EQ(0, sigprocmask(SIG_SETMASK, &original_set, NULL)); } static void EmptySignalHandler(int) {} @@ -216,14 +216,15 @@ static void EmptySignalAction(int, siginfo_t*, void*) {} TEST(signal, sigaction) { // See what's currently set for SIGALRM. - struct sigaction sa; - memset(&sa, 0, sizeof(sa)); - ASSERT_EQ(0, sigaction(SIGALRM, NULL, &sa)); - ASSERT_TRUE(sa.sa_handler == NULL); - ASSERT_TRUE(sa.sa_sigaction == NULL); - ASSERT_TRUE(sa.sa_flags == 0); + struct sigaction original_sa; + memset(&original_sa, 0, sizeof(original_sa)); + ASSERT_EQ(0, sigaction(SIGALRM, NULL, &original_sa)); + ASSERT_TRUE(original_sa.sa_handler == NULL); + ASSERT_TRUE(original_sa.sa_sigaction == NULL); + ASSERT_TRUE(original_sa.sa_flags == 0); // Set a traditional sa_handler signal handler. + struct sigaction sa; memset(&sa, 0, sizeof(sa)); sigaddset(&sa.sa_mask, SIGALRM); sa.sa_flags = SA_ONSTACK; @@ -250,4 +251,7 @@ TEST(signal, sigaction) { ASSERT_TRUE(sa.sa_sigaction == EmptySignalAction); ASSERT_TRUE((void*) sa.sa_sigaction == (void*) sa.sa_handler); ASSERT_TRUE(sa.sa_flags == (SA_ONSTACK | SA_SIGINFO)); + + // Put everything back how it was. + ASSERT_EQ(0, sigaction(SIGALRM, &original_sa, NULL)); } diff --git a/tests/sys_epoll_test.cpp b/tests/sys_epoll_test.cpp new file mode 100644 index 000000000..e4e047b2a --- /dev/null +++ b/tests/sys_epoll_test.cpp @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2013 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_epoll, smoke) { + int epoll_fd = epoll_create(1); + ASSERT_NE(-1, epoll_fd) << strerror(errno); + epoll_event events[1]; + + // Regular epoll_wait. + ASSERT_EQ(0, epoll_wait(epoll_fd, events, 1, 1)); + + // epoll_pwait without a sigset (which is equivalent to epoll_wait). + ASSERT_EQ(0, epoll_pwait(epoll_fd, events, 1, 1, NULL)); + + // epoll_pwait with a sigset. + sigset_t ss; + sigemptyset(&ss); + sigaddset(&ss, SIGPIPE); + ASSERT_EQ(0, epoll_pwait(epoll_fd, events, 1, 1, &ss)); +} diff --git a/tests/sys_select_test.cpp b/tests/sys_select_test.cpp index 36f01b386..57afc9b8d 100644 --- a/tests/sys_select_test.cpp +++ b/tests/sys_select_test.cpp @@ -41,3 +41,73 @@ TEST(sys_select, fd_set_smoke) { EXPECT_FALSE(FD_ISSET(0, &fds)); EXPECT_FALSE(FD_ISSET(1, &fds)); } + +TEST(sys_select, select_smoke) { + fd_set r; + FD_ZERO(&r); + fd_set w; + FD_ZERO(&w); + fd_set e; + FD_ZERO(&e); + + FD_SET(STDIN_FILENO, &r); + FD_SET(STDOUT_FILENO, &w); + FD_SET(STDERR_FILENO, &w); + + int max = STDERR_FILENO + 1; + + // Invalid max fd. + ASSERT_EQ(-1, select(-1, &r, &w, &e, NULL)); + ASSERT_EQ(EINVAL, errno); + + ASSERT_EQ(2, select(max, &r, &w, &e, NULL)); + + // Invalid timeout. + timeval tv; + tv.tv_sec = -1; + tv.tv_usec = 0; + ASSERT_EQ(-1, select(max, &r, &w, &e, &tv)); + ASSERT_EQ(EINVAL, errno); + + // Valid timeout... + tv.tv_sec = 1; + ASSERT_EQ(2, select(max, &r, &w, &e, &tv)); + ASSERT_NE(0, tv.tv_usec); // ...which got updated. +} + +TEST(sys_select, pselect_smoke) { + sigset_t ss; + sigemptyset(&ss); + sigaddset(&ss, SIGPIPE); + + fd_set r; + FD_ZERO(&r); + fd_set w; + FD_ZERO(&w); + fd_set e; + FD_ZERO(&e); + + FD_SET(STDIN_FILENO, &r); + FD_SET(STDOUT_FILENO, &w); + FD_SET(STDERR_FILENO, &w); + + int max = STDERR_FILENO + 1; + + // Invalid max fd. + ASSERT_EQ(-1, pselect(-1, &r, &w, &e, NULL, &ss)); + ASSERT_EQ(EINVAL, errno); + + ASSERT_EQ(2, pselect(max, &r, &w, &e, NULL, &ss)); + + // Invalid timeout. + timespec tv; + tv.tv_sec = -1; + tv.tv_nsec = 0; + ASSERT_EQ(-1, pselect(max, &r, &w, &e, &tv, &ss)); + ASSERT_EQ(EINVAL, errno); + + // Valid timeout... + tv.tv_sec = 1; + ASSERT_EQ(2, pselect(max, &r, &w, &e, &tv, &ss)); + ASSERT_EQ(0, tv.tv_nsec); // ...which did _not_ get updated. +} diff --git a/tests/unistd_test.cpp b/tests/unistd_test.cpp index 319308360..7d0af7c7e 100644 --- a/tests/unistd_test.cpp +++ b/tests/unistd_test.cpp @@ -73,3 +73,16 @@ TEST(unistd, ftruncate64) { ASSERT_EQ(0, stat(tf.filename, &sb)); ASSERT_EQ(123, sb.st_size); } + +static bool gPauseTestFlag = false; +static void PauseTestSignalHandler(int) { + gPauseTestFlag = true; +} + +TEST(unistd, pause) { + signal(SIGALRM, PauseTestSignalHandler); + alarm(1); + ASSERT_FALSE(gPauseTestFlag); + ASSERT_EQ(-1, pause()); + ASSERT_TRUE(gPauseTestFlag); +}