am 5b9d3ddf: am 2ec592c3: Merge "Add recvmmsg and sendmmsg syscalls."

* commit '5b9d3ddf372ca47e3065845487a770794021c760':
  Add recvmmsg and sendmmsg syscalls.
This commit is contained in:
Elliott Hughes 2014-03-01 01:24:39 +00:00 committed by Android Git Automerger
commit 79370b2aee
16 changed files with 350 additions and 46 deletions

View File

@ -247,6 +247,8 @@ int setsockopt(int, int, int, const void*, socklen_t) arm,arm64,mips,
int getsockopt(int, int, int, void*, socklen_t*) arm,arm64,mips,mips64,x86_64 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 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 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. # sockets for x86. These are done as an "indexed" call to socketcall syscall.
int socket:socketcall:1(int, int, int) x86 int socket:socketcall:1(int, int, int) x86
@ -264,6 +266,8 @@ int setsockopt:socketcall:14(int, int, int, const void*, socklen_t) x
int getsockopt:socketcall:15(int, int, int, void*, socklen_t*) x86 int getsockopt:socketcall:15(int, int, int, void*, socklen_t*) x86
int sendmsg:socketcall:16(int, const struct msghdr*, unsigned int) x86 int sendmsg:socketcall:16(int, const struct msghdr*, unsigned int) x86
int recvmsg:socketcall:17(int, 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 # scheduler & real-time
int sched_setscheduler(pid_t pid, int policy, const struct sched_param* param) all int sched_setscheduler(pid_t pid, int policy, const struct sched_param* param) all

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -86,16 +86,21 @@ struct linger {
struct msghdr { struct msghdr {
void* msg_name; void* msg_name;
int msg_namelen; socklen_t msg_namelen;
struct iovec* msg_iov; struct iovec* msg_iov;
__kernel_size_t msg_iovlen; size_t msg_iovlen;
void* msg_control; void* msg_control;
__kernel_size_t msg_controllen; size_t msg_controllen;
unsigned msg_flags; int msg_flags;
};
struct mmsghdr {
struct msghdr msg_hdr;
unsigned int msg_len;
}; };
struct cmsghdr { struct cmsghdr {
__kernel_size_t cmsg_len; size_t cmsg_len;
int cmsg_level; int cmsg_level;
int cmsg_type; int cmsg_type;
}; };
@ -118,11 +123,12 @@ struct cmsghdr {
#define __KINLINE static #define __KINLINE static
#endif #endif
__KINLINE struct cmsghdr * __cmsg_nxthdr(void *__ctl, __kernel_size_t __size, struct cmsghdr *__cmsg) { __KINLINE struct cmsghdr* __cmsg_nxthdr(void* __ctl, size_t __size, struct cmsghdr* __cmsg) {
struct cmsghdr* __ptr; struct cmsghdr* __ptr;
__ptr = (struct cmsghdr*)(((unsigned char*) __cmsg) + CMSG_ALIGN(__cmsg->cmsg_len)); __ptr = (struct cmsghdr*)(((unsigned char*) __cmsg) + CMSG_ALIGN(__cmsg->cmsg_len));
if ((unsigned long)((char*)(__ptr+1) - (char *) __ctl) > __size) if ((unsigned long)((char*)(__ptr+1) - (char*) __ctl) > __size) {
return (struct cmsghdr *)0; return NULL;
}
return __ptr; return __ptr;
} }
@ -135,9 +141,9 @@ __KINLINE struct cmsghdr * cmsg_nxthdr (struct msghdr *__msg, struct cmsghdr *__
#define SCM_SECURITY 0x03 #define SCM_SECURITY 0x03
struct ucred { struct ucred {
__u32 pid; pid_t pid;
__u32 uid; uid_t uid;
__u32 gid; gid_t gid;
}; };
#define AF_UNSPEC 0 #define AF_UNSPEC 0
@ -241,6 +247,9 @@ struct ucred {
#define MSG_ERRQUEUE 0x2000 #define MSG_ERRQUEUE 0x2000
#define MSG_NOSIGNAL 0x4000 #define MSG_NOSIGNAL 0x4000
#define MSG_MORE 0x8000 #define MSG_MORE 0x8000
#define MSG_WAITFORONE 0x10000
#define MSG_FASTOPEN 0x20000000
#define MSG_CMSG_CLOEXEC 0x40000000
#define MSG_EOF MSG_FIN #define MSG_EOF MSG_FIN
#define MSG_CMSG_COMPAT 0 #define MSG_CMSG_COMPAT 0
@ -276,19 +285,21 @@ struct ucred {
# define __socketcall extern # define __socketcall extern
#endif #endif
__socketcall int socket(int, int, int); __socketcall int accept(int, struct sockaddr*, socklen_t*);
__socketcall int bind(int, const struct sockaddr*, int); __socketcall int bind(int, const struct sockaddr*, int);
__socketcall int connect(int, const struct sockaddr*, socklen_t); __socketcall int connect(int, const struct sockaddr*, 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 getpeername(int, struct sockaddr*, socklen_t*);
__socketcall int socketpair(int, int, int, int *); __socketcall int getsockname(int, struct sockaddr*, 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 getsockopt(int, int, int, void*, socklen_t*);
__socketcall int sendmsg(int, const struct msghdr *, unsigned int); __socketcall int listen(int, int);
__socketcall int recvmmsg(int, struct mmsghdr*, unsigned int, int, const struct timespec*);
__socketcall int recvmsg(int, struct msghdr*, unsigned int); __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 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 send(int, const void*, size_t, unsigned int);
extern ssize_t recv(int, void*, size_t, unsigned int); extern ssize_t recv(int, void*, size_t, unsigned int);

View File

@ -71,6 +71,7 @@ libBionicStandardTests_src_files := \
sys_resource_test.cpp \ sys_resource_test.cpp \
sys_select_test.cpp \ sys_select_test.cpp \
sys_sendfile_test.cpp \ sys_sendfile_test.cpp \
sys_socket_test.cpp \
sys_stat_test.cpp \ sys_stat_test.cpp \
sys_statvfs_test.cpp \ sys_statvfs_test.cpp \
sys_syscall_test.cpp \ sys_syscall_test.cpp \

34
tests/sys_socket_test.cpp Normal file
View File

@ -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
}