2 * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
4 * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
8 #include <sys/syscall.h>
9 #include <sys/socket.h>
12 #ifdef __NR_socketcall
13 /* Various socketcall numbers */
19 #define SYS_GETSOCKNAME 6
20 #define SYS_GETPEERNAME 7
21 #define SYS_SOCKETPAIR 8
25 #define SYS_RECVFROM 12
26 #define SYS_SHUTDOWN 13
27 #define SYS_SETSOCKOPT 14
28 #define SYS_GETSOCKOPT 15
29 #define SYS_SENDMSG 16
30 #define SYS_RECVMSG 17
31 #define SYS_ACCEPT4 18
34 /* exposed on x86 since Linux commit 9dea5dc921b5f4045a18c63eb92e84dc274d17eb */
35 #if defined(__sparc__) || defined(__i386__)
40 #undef __NR_getpeername
41 #undef __NR_getsockname
42 #undef __NR_getsockopt
50 #undef __NR_setsockopt
53 #undef __NR_socketpair
57 static int __NC(accept
)(int sockfd
, struct sockaddr
*addr
, socklen_t
*addrlen
)
60 return INLINE_SYSCALL(accept
, 3, sockfd
, addr
, addrlen
);
62 unsigned long args
[3];
65 args
[1] = (unsigned long) addr
;
66 args
[2] = (unsigned long) addrlen
;
68 return __socketcall(SYS_ACCEPT
, args
);
71 CANCELLABLE_SYSCALL(int, accept
, (int sockfd
, struct sockaddr
*addr
, socklen_t
*addrlen
),
72 (sockfd
, addr
, addrlen
))
73 lt_libc_hidden(accept
)
78 # define __NR___sys_accept4 __NR_accept4
79 static _syscall4(int, __sys_accept4
, int, fd
, struct sockaddr
*, addr
, socklen_t
*, addrlen
, int, flags
)
80 int accept4(int fd
, struct sockaddr
*addr
, socklen_t
* addrlen
, int flags
)
83 return __sys_accept4(fd
, addr
, addrlen
, flags
);
84 #ifdef __UCLIBC_HAS_THREADS_NATIVE__
86 int oldtype
= LIBC_CANCEL_ASYNC ();
87 int result
= __sys_accept4(fd
, addr
, addrlen
, flags
);
88 LIBC_CANCEL_RESET (oldtype
);
93 #elif defined(__NR_socketcall)
94 int accept4(int fd
, struct sockaddr
*addr
, socklen_t
*addrlen
, int flags
)
96 unsigned long args
[4];
99 args
[1] = (unsigned long) addr
;
100 args
[2] = (unsigned long) addrlen
;
103 return __socketcall(SYS_ACCEPT4
, args
);
104 #ifdef __UCLIBC_HAS_THREADS_NATIVE__
106 int oldtype
= LIBC_CANCEL_ASYNC ();
107 int result
= __socketcall(SYS_ACCEPT4
, args
);
108 LIBC_CANCEL_RESET (oldtype
);
117 int bind(int sockfd
, const struct sockaddr
*myaddr
, socklen_t addrlen
)
120 return INLINE_SYSCALL(bind
, 3, sockfd
, myaddr
, addrlen
);
122 unsigned long args
[3];
125 args
[1] = (unsigned long) myaddr
;
127 return __socketcall(SYS_BIND
, args
);
130 libc_hidden_def(bind
)
134 static int __NC(connect
)(int sockfd
, const struct sockaddr
*saddr
, socklen_t addrlen
)
137 return INLINE_SYSCALL(connect
, 3, sockfd
, saddr
, addrlen
);
139 unsigned long args
[3];
142 args
[1] = (unsigned long) saddr
;
144 return __socketcall(SYS_CONNECT
, args
);
147 CANCELLABLE_SYSCALL(int, connect
, (int sockfd
, const struct sockaddr
*saddr
, socklen_t addrlen
),
148 (sockfd
, saddr
, addrlen
))
149 lt_libc_hidden(connect
)
153 int getpeername(int sockfd
, struct sockaddr
*addr
, socklen_t
*paddrlen
)
155 # ifdef __NR_getpeername
156 return INLINE_SYSCALL(getpeername
, 3, sockfd
, addr
, paddrlen
);
158 unsigned long args
[3];
161 args
[1] = (unsigned long) addr
;
162 args
[2] = (unsigned long) paddrlen
;
163 return __socketcall(SYS_GETPEERNAME
, args
);
169 int getsockname(int sockfd
, struct sockaddr
*addr
, socklen_t
* paddrlen
)
171 # ifdef __NR_getsockname
172 return INLINE_SYSCALL(getsockname
, 3, sockfd
, addr
, paddrlen
);
174 unsigned long args
[3];
177 args
[1] = (unsigned long) addr
;
178 args
[2] = (unsigned long) paddrlen
;
179 return __socketcall(SYS_GETSOCKNAME
, args
);
182 libc_hidden_def(getsockname
)
186 int getsockopt(int fd
, int level
, int optname
, void *optval
,
189 # ifdef __NR_getsockopt
190 return INLINE_SYSCALL(getsockopt
, 5, fd
, level
, optname
, optval
, optlen
);
192 unsigned long args
[5];
197 args
[3] = (unsigned long) optval
;
198 args
[4] = (unsigned long) optlen
;
199 return (__socketcall(SYS_GETSOCKOPT
, args
));
205 int listen(int sockfd
, int backlog
)
208 return INLINE_SYSCALL(listen
, 2, sockfd
, backlog
);
210 unsigned long args
[2];
214 return __socketcall(SYS_LISTEN
, args
);
217 libc_hidden_def(listen
)
221 static ssize_t
__NC(recv
)(int sockfd
, void *buffer
, size_t len
, int flags
)
224 return (ssize_t
)INLINE_SYSCALL(recv
, 4, sockfd
, buffer
, len
, flags
);
225 # elif defined __NR_recvfrom && defined _syscall6
226 return __NC(recvfrom
)(sockfd
, buffer
, len
, flags
, NULL
, NULL
);
228 unsigned long args
[4];
231 args
[1] = (unsigned long) buffer
;
234 return (ssize_t
)__socketcall(SYS_RECV
, args
);
237 CANCELLABLE_SYSCALL(ssize_t
, recv
, (int sockfd
, void *buffer
, size_t len
, int flags
),
238 (sockfd
, buffer
, len
, flags
))
243 ssize_t
__NC(recvfrom
)(int sockfd
, void *buffer
, size_t len
, int flags
,
244 struct sockaddr
*to
, socklen_t
*tolen
)
246 # if defined __NR_recvfrom && defined _syscall6
247 return (ssize_t
)INLINE_SYSCALL(recvfrom
, 6, sockfd
, buffer
, len
,
250 unsigned long args
[6];
253 args
[1] = (unsigned long) buffer
;
256 args
[4] = (unsigned long) to
;
257 args
[5] = (unsigned long) tolen
;
258 return (ssize_t
)__socketcall(SYS_RECVFROM
, args
);
261 CANCELLABLE_SYSCALL(ssize_t
, recvfrom
, (int sockfd
, void *buffer
, size_t len
,
262 int flags
, struct sockaddr
*to
, socklen_t
*tolen
),
263 (sockfd
, buffer
, len
, flags
, to
, tolen
))
264 lt_libc_hidden(recvfrom
)
268 static ssize_t
__NC(recvmsg
)(int sockfd
, struct msghdr
*msg
, int flags
)
271 return (ssize_t
)INLINE_SYSCALL(recvmsg
, 3, sockfd
, msg
, flags
);
273 unsigned long args
[3];
276 args
[1] = (unsigned long) msg
;
278 return (ssize_t
)__socketcall(SYS_RECVMSG
, args
);
281 CANCELLABLE_SYSCALL(ssize_t
, recvmsg
, (int sockfd
, struct msghdr
*msg
, int flags
),
282 (sockfd
, msg
, flags
))
283 lt_libc_hidden(recvmsg
)
287 static ssize_t
__NC(send
)(int sockfd
, const void *buffer
, size_t len
, int flags
)
290 return (ssize_t
)INLINE_SYSCALL(send
, 4, sockfd
, buffer
, len
, flags
);
291 # elif defined __NR_sendto && defined _syscall6
292 return __NC(sendto
)(sockfd
, buffer
, len
, flags
, NULL
, 0);
294 unsigned long args
[4];
297 args
[1] = (unsigned long) buffer
;
300 return (ssize_t
)__socketcall(SYS_SEND
, args
);
303 CANCELLABLE_SYSCALL(ssize_t
, send
, (int sockfd
, const void *buffer
, size_t len
, int flags
),
304 (sockfd
, buffer
, len
, flags
))
309 static ssize_t
__NC(sendmsg
)(int sockfd
, const struct msghdr
*msg
, int flags
)
312 return (ssize_t
)INLINE_SYSCALL(sendmsg
, 3, sockfd
, msg
, flags
);
314 unsigned long args
[3];
317 args
[1] = (unsigned long) msg
;
319 return (ssize_t
)__socketcall(SYS_SENDMSG
, args
);
322 CANCELLABLE_SYSCALL(ssize_t
, sendmsg
, (int sockfd
, const struct msghdr
*msg
, int flags
),
323 (sockfd
, msg
, flags
))
324 lt_libc_hidden(sendmsg
)
328 ssize_t
__NC(sendto
)(int sockfd
, const void *buffer
, size_t len
, int flags
,
329 const struct sockaddr
*to
, socklen_t tolen
)
331 # if defined __NR_sendto && defined _syscall6
332 return (ssize_t
)INLINE_SYSCALL(sendto
, 6, sockfd
, buffer
, len
, flags
, to
, tolen
);
334 unsigned long args
[6];
337 args
[1] = (unsigned long) buffer
;
340 args
[4] = (unsigned long) to
;
342 return (ssize_t
)__socketcall(SYS_SENDTO
, args
);
345 CANCELLABLE_SYSCALL(ssize_t
, sendto
, (int sockfd
, const void *buffer
, size_t len
,
346 int flags
, const struct sockaddr
*to
, socklen_t tolen
),
347 (sockfd
, buffer
, len
, flags
, to
, tolen
))
348 lt_libc_hidden(sendto
)
352 int setsockopt(int fd
, int level
, int optname
, const void *optval
, socklen_t optlen
)
354 # ifdef __NR_setsockopt
355 return INLINE_SYSCALL(setsockopt
, 5, fd
, level
, optname
, optval
, optlen
);
357 unsigned long args
[5];
362 args
[3] = (unsigned long) optval
;
364 return __socketcall(SYS_SETSOCKOPT
, args
);
367 libc_hidden_def(setsockopt
)
371 int shutdown(int sockfd
, int how
)
373 # ifdef __NR_shutdown
374 return INLINE_SYSCALL(shutdown
, 2, sockfd
, how
);
376 unsigned long args
[2];
380 return __socketcall(SYS_SHUTDOWN
, args
);
386 int socket(int family
, int type
, int protocol
)
389 return INLINE_SYSCALL(socket
, 3, family
, type
, protocol
);
391 unsigned long args
[3];
395 args
[2] = (unsigned long) protocol
;
396 return __socketcall(SYS_SOCKET
, args
);
399 libc_hidden_def(socket
)
403 int socketpair(int family
, int type
, int protocol
, int sockvec
[2])
405 # ifdef __NR_socketpair
406 return INLINE_SYSCALL(socketpair
, 4, family
, type
, protocol
, sockvec
);
408 unsigned long args
[4];
413 args
[3] = (unsigned long) sockvec
;
414 return __socketcall(SYS_SOCKETPAIR
, args
);