123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457 |
- /*
- * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
- *
- * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
- */
- #include <stddef.h>
- #include <sys/syscall.h>
- #include <sys/socket.h>
- #include <cancel.h>
- #include <bits/kernel-features.h>
- #if defined(__UCLIBC_USE_TIME64__)
- #include "internal/time64_helpers.h"
- #endif
- #ifdef __NR_socketcall
- /* Various socketcall numbers */
- #define SYS_SOCKET 1
- #define SYS_BIND 2
- #define SYS_CONNECT 3
- #define SYS_LISTEN 4
- #define SYS_ACCEPT 5
- #define SYS_GETSOCKNAME 6
- #define SYS_GETPEERNAME 7
- #define SYS_SOCKETPAIR 8
- #define SYS_SEND 9
- #define SYS_RECV 10
- #define SYS_SENDTO 11
- #define SYS_RECVFROM 12
- #define SYS_SHUTDOWN 13
- #define SYS_SETSOCKOPT 14
- #define SYS_GETSOCKOPT 15
- #define SYS_SENDMSG 16
- #define SYS_RECVMSG 17
- #define SYS_ACCEPT4 18
- #define SYS_RECVMMSG 19
- #define SYS_SENDMMSG 20
- #endif
- /* exposed on x86 since Linux commit 9dea5dc921b5f4045a18c63eb92e84dc274d17eb */
- #if defined(__sparc__) || defined(__i386__)
- #undef __NR_accept
- #undef __NR_accept4
- #undef __NR_bind
- #undef __NR_connect
- #undef __NR_getpeername
- #undef __NR_getsockname
- #undef __NR_getsockopt
- #undef __NR_listen
- #undef __NR_recv
- #undef __NR_recvfrom
- #undef __NR_recvmsg
- #undef __NR_send
- #undef __NR_sendmsg
- #undef __NR_sendto
- #undef __NR_setsockopt
- #undef __NR_shutdown
- #undef __NR_socket
- #undef __NR_socketpair
- #endif
- #ifdef L_accept
- static int __NC(accept)(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
- {
- # ifdef __NR_accept
- return INLINE_SYSCALL(accept, 3, sockfd, addr, addrlen);
- # elif defined(__NR_socketcall)
- unsigned long args[3];
- args[0] = sockfd;
- args[1] = (unsigned long) addr;
- args[2] = (unsigned long) addrlen;
- return __socketcall(SYS_ACCEPT, args);
- # endif
- }
- CANCELLABLE_SYSCALL(int, accept, (int sockfd, struct sockaddr *addr, socklen_t *addrlen),
- (sockfd, addr, addrlen))
- lt_libc_hidden(accept)
- #endif
- #ifdef L_accept4
- static int __NC(accept4)(int fd, struct sockaddr *addr, socklen_t *addrlen, int flags)
- {
- # ifdef __NR_accept4
- return INLINE_SYSCALL(accept4, 4, fd, addr, addrlen, flags);
- # elif defined(__NR_socketcall)
- unsigned long args[4];
- args[0] = fd;
- args[1] = (unsigned long) addr;
- args[2] = (unsigned long) addrlen;
- args[3] = flags;
- return __socketcall(SYS_ACCEPT4, args);
- #endif
- }
- CANCELLABLE_SYSCALL(int, accept4, (int fd, struct sockaddr *addr, socklen_t *addrlen, int flags),
- (fd, addr, addrlen, flags))
- lt_libc_hidden(accept4)
- #endif
- #ifdef L_bind
- int bind(int sockfd, const struct sockaddr *myaddr, socklen_t addrlen)
- {
- # ifdef __NR_bind
- return INLINE_SYSCALL(bind, 3, sockfd, myaddr, addrlen);
- # elif defined(__NR_socketcall)
- unsigned long args[3];
- args[0] = sockfd;
- args[1] = (unsigned long) myaddr;
- args[2] = addrlen;
- return __socketcall(SYS_BIND, args);
- # endif
- }
- libc_hidden_def(bind)
- #endif
- #ifdef L_connect
- static int __NC(connect)(int sockfd, const struct sockaddr *saddr, socklen_t addrlen)
- {
- # ifdef __NR_connect
- return INLINE_SYSCALL(connect, 3, sockfd, saddr, addrlen);
- # elif defined(__NR_socketcall)
- unsigned long args[3];
- args[0] = sockfd;
- args[1] = (unsigned long) saddr;
- args[2] = addrlen;
- return __socketcall(SYS_CONNECT, args);
- # endif
- }
- CANCELLABLE_SYSCALL(int, connect, (int sockfd, const struct sockaddr *saddr, socklen_t addrlen),
- (sockfd, saddr, addrlen))
- lt_libc_hidden(connect)
- #endif
- #ifdef L_getpeername
- int getpeername(int sockfd, struct sockaddr *addr, socklen_t *paddrlen)
- {
- # ifdef __NR_getpeername
- return INLINE_SYSCALL(getpeername, 3, sockfd, addr, paddrlen);
- # elif defined(__NR_socketcall)
- unsigned long args[3];
- args[0] = sockfd;
- args[1] = (unsigned long) addr;
- args[2] = (unsigned long) paddrlen;
- return __socketcall(SYS_GETPEERNAME, args);
- # endif
- }
- #endif
- #ifdef L_getsockname
- int getsockname(int sockfd, struct sockaddr *addr, socklen_t * paddrlen)
- {
- # ifdef __NR_getsockname
- return INLINE_SYSCALL(getsockname, 3, sockfd, addr, paddrlen);
- # elif defined(__NR_socketcall)
- unsigned long args[3];
- args[0] = sockfd;
- args[1] = (unsigned long) addr;
- args[2] = (unsigned long) paddrlen;
- return __socketcall(SYS_GETSOCKNAME, args);
- # endif
- }
- libc_hidden_def(getsockname)
- #endif
- #ifdef L_getsockopt
- int getsockopt(int fd, int level, int optname, void *optval,
- socklen_t *optlen)
- {
- # ifdef __NR_getsockopt
- return INLINE_SYSCALL(getsockopt, 5, fd, level, optname, optval, optlen);
- # elif defined(__NR_socketcall)
- unsigned long args[5];
- args[0] = fd;
- args[1] = level;
- args[2] = optname;
- args[3] = (unsigned long) optval;
- args[4] = (unsigned long) optlen;
- return (__socketcall(SYS_GETSOCKOPT, args));
- # endif
- }
- #endif
- #ifdef L_listen
- int listen(int sockfd, int backlog)
- {
- # ifdef __NR_listen
- return INLINE_SYSCALL(listen, 2, sockfd, backlog);
- # elif defined(__NR_socketcall)
- unsigned long args[2];
- args[0] = sockfd;
- args[1] = backlog;
- return __socketcall(SYS_LISTEN, args);
- # endif
- }
- libc_hidden_def(listen)
- #endif
- #ifdef L_recv
- static ssize_t __NC(recv)(int sockfd, void *buffer, size_t len, int flags)
- {
- # ifdef __NR_recv
- return (ssize_t)INLINE_SYSCALL(recv, 4, sockfd, buffer, len, flags);
- # elif defined __NR_recvfrom && defined _syscall6
- return __NC(recvfrom)(sockfd, buffer, len, flags, NULL, NULL);
- # elif defined(__NR_socketcall)
- unsigned long args[4];
- args[0] = sockfd;
- args[1] = (unsigned long) buffer;
- args[2] = len;
- args[3] = flags;
- return (ssize_t)__socketcall(SYS_RECV, args);
- # endif
- }
- CANCELLABLE_SYSCALL(ssize_t, recv, (int sockfd, void *buffer, size_t len, int flags),
- (sockfd, buffer, len, flags))
- lt_libc_hidden(recv)
- #endif
- #ifdef L_recvfrom
- ssize_t __NC(recvfrom)(int sockfd, void *buffer, size_t len, int flags,
- struct sockaddr *to, socklen_t *tolen)
- {
- # if defined __NR_recvfrom && defined _syscall6
- return (ssize_t)INLINE_SYSCALL(recvfrom, 6, sockfd, buffer, len,
- flags, to, tolen);
- # elif defined(__NR_socketcall)
- unsigned long args[6];
- args[0] = sockfd;
- args[1] = (unsigned long) buffer;
- args[2] = len;
- args[3] = flags;
- args[4] = (unsigned long) to;
- args[5] = (unsigned long) tolen;
- return (ssize_t)__socketcall(SYS_RECVFROM, args);
- # endif
- }
- CANCELLABLE_SYSCALL(ssize_t, recvfrom, (int sockfd, void *buffer, size_t len,
- int flags, struct sockaddr *to, socklen_t *tolen),
- (sockfd, buffer, len, flags, to, tolen))
- lt_libc_hidden(recvfrom)
- #endif
- #ifdef L_recvmsg
- static ssize_t __NC(recvmsg)(int sockfd, struct msghdr *msg, int flags)
- {
- # ifdef __NR_recvmsg
- return (ssize_t)INLINE_SYSCALL(recvmsg, 3, sockfd, msg, flags);
- # elif defined(__NR_socketcall)
- unsigned long args[3];
- args[0] = sockfd;
- args[1] = (unsigned long) msg;
- args[2] = flags;
- return (ssize_t)__socketcall(SYS_RECVMSG, args);
- # endif
- }
- CANCELLABLE_SYSCALL(ssize_t, recvmsg, (int sockfd, struct msghdr *msg, int flags),
- (sockfd, msg, flags))
- lt_libc_hidden(recvmsg)
- #endif
- #ifdef L_recvmmsg
- #ifdef __ASSUME_RECVMMSG_SYSCALL
- static ssize_t __NC(recvmmsg)(int sockfd, struct mmsghdr *msg, size_t vlen,
- int flags, struct timespec *tmo)
- {
- # if defined(__UCLIBC_USE_TIME64__) && defined(__NR_recvmmsg_time64)
- return (ssize_t)INLINE_SYSCALL(recvmmsg_time64, 5, sockfd, msg, vlen, flags, TO_TS64_P(tmo));
- # elif defined(__NR_recvmmsg)
- return (ssize_t)INLINE_SYSCALL(recvmmsg, 5, sockfd, msg, vlen, flags, tmo);
- # elif __NR_socketcall
- unsigned long args[5];
- args[0] = sockfd;
- args[1] = (unsigned long) msg;
- args[2] = vlen;
- args[3] = flags;
- args[4] = (unsigned long) tmo;
- return (ssize_t)__socketcall(SYS_RECVMMSG, args);
- # endif
- }
- CANCELLABLE_SYSCALL(ssize_t, recvmmsg,
- (int sockfd, struct mmsghdr *msg, size_t vlen, int flags,
- struct timespec *tmo),
- (sockfd, msg, vlen, flags, tmo))
- lt_libc_hidden(recvmmsg)
- #endif
- #endif
- #ifdef L_send
- static ssize_t __NC(send)(int sockfd, const void *buffer, size_t len, int flags)
- {
- # ifdef __NR_send
- return (ssize_t)INLINE_SYSCALL(send, 4, sockfd, buffer, len, flags);
- # elif defined __NR_sendto && defined _syscall6
- return __NC(sendto)(sockfd, buffer, len, flags, NULL, 0);
- # elif defined(__NR_socketcall)
- unsigned long args[4];
- args[0] = sockfd;
- args[1] = (unsigned long) buffer;
- args[2] = len;
- args[3] = flags;
- return (ssize_t)__socketcall(SYS_SEND, args);
- # endif
- }
- CANCELLABLE_SYSCALL(ssize_t, send, (int sockfd, const void *buffer, size_t len, int flags),
- (sockfd, buffer, len, flags))
- lt_libc_hidden(send)
- #endif
- #ifdef L_sendmsg
- static ssize_t __NC(sendmsg)(int sockfd, const struct msghdr *msg, int flags)
- {
- # ifdef __NR_sendmsg
- return (ssize_t)INLINE_SYSCALL(sendmsg, 3, sockfd, msg, flags);
- # elif defined(__NR_socketcall)
- unsigned long args[3];
- args[0] = sockfd;
- args[1] = (unsigned long) msg;
- args[2] = flags;
- return (ssize_t)__socketcall(SYS_SENDMSG, args);
- # endif
- }
- CANCELLABLE_SYSCALL(ssize_t, sendmsg, (int sockfd, const struct msghdr *msg, int flags),
- (sockfd, msg, flags))
- lt_libc_hidden(sendmsg)
- #endif
- #ifdef L_sendmmsg
- #ifdef __ASSUME_SENDMMSG_SYSCALL
- static ssize_t __NC(sendmmsg)(int sockfd, struct mmsghdr *msg, size_t vlen,
- int flags)
- {
- # ifdef __NR_sendmmsg
- return (ssize_t)INLINE_SYSCALL(sendmmsg, 4, sockfd, msg, vlen, flags);
- # elif __NR_socketcall
- unsigned long args[4];
- args[0] = sockfd;
- args[1] = (unsigned long) msg;
- args[2] = vlen;
- args[3] = flags;
- return (ssize_t)__socketcall(SYS_SENDMMSG, args);
- # endif
- }
- CANCELLABLE_SYSCALL(ssize_t, sendmmsg,
- (int sockfd, struct mmsghdr *msg, size_t vlen, int flags),
- (sockfd, msg, vlen, flags))
- lt_libc_hidden(sendmmsg)
- #endif
- #endif
- #ifdef L_sendto
- ssize_t __NC(sendto)(int sockfd, const void *buffer, size_t len, int flags,
- const struct sockaddr *to, socklen_t tolen)
- {
- # if defined __NR_sendto && defined _syscall6
- return (ssize_t)INLINE_SYSCALL(sendto, 6, sockfd, buffer, len, flags, to, tolen);
- # elif defined(__NR_socketcall)
- unsigned long args[6];
- args[0] = sockfd;
- args[1] = (unsigned long) buffer;
- args[2] = len;
- args[3] = flags;
- args[4] = (unsigned long) to;
- args[5] = tolen;
- return (ssize_t)__socketcall(SYS_SENDTO, args);
- # endif
- }
- CANCELLABLE_SYSCALL(ssize_t, sendto, (int sockfd, const void *buffer, size_t len,
- int flags, const struct sockaddr *to, socklen_t tolen),
- (sockfd, buffer, len, flags, to, tolen))
- lt_libc_hidden(sendto)
- #endif
- #ifdef L_setsockopt
- int setsockopt(int fd, int level, int optname, const void *optval, socklen_t optlen)
- {
- # ifdef __NR_setsockopt
- return INLINE_SYSCALL(setsockopt, 5, fd, level, optname, optval, optlen);
- # elif defined(__NR_socketcall)
- unsigned long args[5];
- args[0] = fd;
- args[1] = level;
- args[2] = optname;
- args[3] = (unsigned long) optval;
- args[4] = optlen;
- return __socketcall(SYS_SETSOCKOPT, args);
- # endif
- }
- libc_hidden_def(setsockopt)
- #endif
- #ifdef L_shutdown
- int shutdown(int sockfd, int how)
- {
- # ifdef __NR_shutdown
- return INLINE_SYSCALL(shutdown, 2, sockfd, how);
- # elif defined(__NR_socketcall)
- unsigned long args[2];
- args[0] = sockfd;
- args[1] = how;
- return __socketcall(SYS_SHUTDOWN, args);
- # endif
- }
- #endif
- #ifdef L_socket
- int socket(int family, int type, int protocol)
- {
- # ifdef __NR_socket
- return INLINE_SYSCALL(socket, 3, family, type, protocol);
- # elif defined(__NR_socketcall)
- unsigned long args[3];
- args[0] = family;
- args[1] = type;
- args[2] = (unsigned long) protocol;
- return __socketcall(SYS_SOCKET, args);
- # endif
- }
- libc_hidden_def(socket)
- #endif
- #ifdef L_socketpair
- int socketpair(int family, int type, int protocol, int sockvec[2])
- {
- # ifdef __NR_socketpair
- return INLINE_SYSCALL(socketpair, 4, family, type, protocol, sockvec);
- # elif defined(__NR_socketcall)
- unsigned long args[4];
- args[0] = family;
- args[1] = type;
- args[2] = protocol;
- args[3] = (unsigned long) sockvec;
- return __socketcall(SYS_SOCKETPAIR, args);
- # endif
- }
- #endif
|