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>
11 #include <bits/kernel-features.h>
13 #ifdef __NR_socketcall
14 /* Various socketcall numbers */
20 #define SYS_GETSOCKNAME 6
21 #define SYS_GETPEERNAME 7
22 #define SYS_SOCKETPAIR 8
26 #define SYS_RECVFROM 12
27 #define SYS_SHUTDOWN 13
28 #define SYS_SETSOCKOPT 14
29 #define SYS_GETSOCKOPT 15
30 #define SYS_SENDMSG 16
31 #define SYS_RECVMSG 17
32 #define SYS_ACCEPT4 18
33 #define SYS_RECVMMSG 19
34 #define SYS_SENDMMSG 20
37 /* exposed on x86 since Linux commit 9dea5dc921b5f4045a18c63eb92e84dc274d17eb */
38 #if defined(__sparc__) || defined(__i386__)
43 #undef __NR_getpeername
44 #undef __NR_getsockname
45 #undef __NR_getsockopt
53 #undef __NR_setsockopt
56 #undef __NR_socketpair
60 static int __NC(accept
)(int sockfd
, struct sockaddr
*addr
, socklen_t
*addrlen
)
63 return INLINE_SYSCALL(accept
, 3, sockfd
, addr
, addrlen
);
64 # elif defined(__NR_socketcall)
65 unsigned long args
[3];
68 args
[1] = (unsigned long) addr
;
69 args
[2] = (unsigned long) addrlen
;
71 return __socketcall(SYS_ACCEPT
, args
);
74 CANCELLABLE_SYSCALL(int, accept
, (int sockfd
, struct sockaddr
*addr
, socklen_t
*addrlen
),
75 (sockfd
, addr
, addrlen
))
76 lt_libc_hidden(accept
)
80 static int __NC(accept4
)(int fd
, struct sockaddr
*addr
, socklen_t
*addrlen
, int flags
)
83 return INLINE_SYSCALL(accept4
, 4, fd
, addr
, addrlen
, flags
);
84 # elif defined(__NR_socketcall)
85 unsigned long args
[4];
88 args
[1] = (unsigned long) addr
;
89 args
[2] = (unsigned long) addrlen
;
92 return __socketcall(SYS_ACCEPT4
, args
);
95 CANCELLABLE_SYSCALL(int, accept4
, (int fd
, struct sockaddr
*addr
, socklen_t
*addrlen
, int flags
),
96 (fd
, addr
, addrlen
, flags
))
97 lt_libc_hidden(accept4
)
101 int bind(int sockfd
, const struct sockaddr
*myaddr
, socklen_t addrlen
)
104 return INLINE_SYSCALL(bind
, 3, sockfd
, myaddr
, addrlen
);
105 # elif defined(__NR_socketcall)
106 unsigned long args
[3];
109 args
[1] = (unsigned long) myaddr
;
111 return __socketcall(SYS_BIND
, args
);
114 libc_hidden_def(bind
)
118 static int __NC(connect
)(int sockfd
, const struct sockaddr
*saddr
, socklen_t addrlen
)
121 return INLINE_SYSCALL(connect
, 3, sockfd
, saddr
, addrlen
);
122 # elif defined(__NR_socketcall)
123 unsigned long args
[3];
126 args
[1] = (unsigned long) saddr
;
128 return __socketcall(SYS_CONNECT
, args
);
131 CANCELLABLE_SYSCALL(int, connect
, (int sockfd
, const struct sockaddr
*saddr
, socklen_t addrlen
),
132 (sockfd
, saddr
, addrlen
))
133 lt_libc_hidden(connect
)
137 int getpeername(int sockfd
, struct sockaddr
*addr
, socklen_t
*paddrlen
)
139 # ifdef __NR_getpeername
140 return INLINE_SYSCALL(getpeername
, 3, sockfd
, addr
, paddrlen
);
141 # elif defined(__NR_socketcall)
142 unsigned long args
[3];
145 args
[1] = (unsigned long) addr
;
146 args
[2] = (unsigned long) paddrlen
;
147 return __socketcall(SYS_GETPEERNAME
, args
);
153 int getsockname(int sockfd
, struct sockaddr
*addr
, socklen_t
* paddrlen
)
155 # ifdef __NR_getsockname
156 return INLINE_SYSCALL(getsockname
, 3, sockfd
, addr
, paddrlen
);
157 # elif defined(__NR_socketcall)
158 unsigned long args
[3];
161 args
[1] = (unsigned long) addr
;
162 args
[2] = (unsigned long) paddrlen
;
163 return __socketcall(SYS_GETSOCKNAME
, args
);
166 libc_hidden_def(getsockname
)
170 int getsockopt(int fd
, int level
, int optname
, void *optval
,
173 # ifdef __NR_getsockopt
174 return INLINE_SYSCALL(getsockopt
, 5, fd
, level
, optname
, optval
, optlen
);
175 # elif defined(__NR_socketcall)
176 unsigned long args
[5];
181 args
[3] = (unsigned long) optval
;
182 args
[4] = (unsigned long) optlen
;
183 return (__socketcall(SYS_GETSOCKOPT
, args
));
189 int listen(int sockfd
, int backlog
)
192 return INLINE_SYSCALL(listen
, 2, sockfd
, backlog
);
193 # elif defined(__NR_socketcall)
194 unsigned long args
[2];
198 return __socketcall(SYS_LISTEN
, args
);
201 libc_hidden_def(listen
)
205 static ssize_t
__NC(recv
)(int sockfd
, void *buffer
, size_t len
, int flags
)
208 return (ssize_t
)INLINE_SYSCALL(recv
, 4, sockfd
, buffer
, len
, flags
);
209 # elif defined __NR_recvfrom && defined _syscall6
210 return __NC(recvfrom
)(sockfd
, buffer
, len
, flags
, NULL
, NULL
);
211 # elif defined(__NR_socketcall)
212 unsigned long args
[4];
215 args
[1] = (unsigned long) buffer
;
218 return (ssize_t
)__socketcall(SYS_RECV
, args
);
221 CANCELLABLE_SYSCALL(ssize_t
, recv
, (int sockfd
, void *buffer
, size_t len
, int flags
),
222 (sockfd
, buffer
, len
, flags
))
227 ssize_t
__NC(recvfrom
)(int sockfd
, void *buffer
, size_t len
, int flags
,
228 struct sockaddr
*to
, socklen_t
*tolen
)
230 # if defined __NR_recvfrom && defined _syscall6
231 return (ssize_t
)INLINE_SYSCALL(recvfrom
, 6, sockfd
, buffer
, len
,
233 # elif defined(__NR_socketcall)
234 unsigned long args
[6];
237 args
[1] = (unsigned long) buffer
;
240 args
[4] = (unsigned long) to
;
241 args
[5] = (unsigned long) tolen
;
242 return (ssize_t
)__socketcall(SYS_RECVFROM
, args
);
245 CANCELLABLE_SYSCALL(ssize_t
, recvfrom
, (int sockfd
, void *buffer
, size_t len
,
246 int flags
, struct sockaddr
*to
, socklen_t
*tolen
),
247 (sockfd
, buffer
, len
, flags
, to
, tolen
))
248 lt_libc_hidden(recvfrom
)
252 static ssize_t
__NC(recvmsg
)(int sockfd
, struct msghdr
*msg
, int flags
)
255 return (ssize_t
)INLINE_SYSCALL(recvmsg
, 3, sockfd
, msg
, flags
);
256 # elif defined(__NR_socketcall)
257 unsigned long args
[3];
260 args
[1] = (unsigned long) msg
;
262 return (ssize_t
)__socketcall(SYS_RECVMSG
, args
);
265 CANCELLABLE_SYSCALL(ssize_t
, recvmsg
, (int sockfd
, struct msghdr
*msg
, int flags
),
266 (sockfd
, msg
, flags
))
267 lt_libc_hidden(recvmsg
)
271 #ifdef __ASSUME_RECVMMSG_SYSCALL
272 static ssize_t
__NC(recvmmsg
)(int sockfd
, struct mmsghdr
*msg
, size_t vlen
,
273 int flags
, struct timespec
*tmo
)
275 # if defined(__UCLIBC_USE_TIME64__) && defined(__NR_recvmmsg_time64)
276 return (ssize_t
)INLINE_SYSCALL(recvmmsg_time64
, 5, sockfd
, msg
, vlen
, flags
, tmo
);
277 # elif defined(__NR_recvmmsg)
278 return (ssize_t
)INLINE_SYSCALL(recvmmsg
, 5, sockfd
, msg
, vlen
, flags
, tmo
);
279 # elif __NR_socketcall
280 unsigned long args
[5];
283 args
[1] = (unsigned long) msg
;
286 args
[4] = (unsigned long) tmo
;
287 return (ssize_t
)__socketcall(SYS_RECVMMSG
, args
);
290 CANCELLABLE_SYSCALL(ssize_t
, recvmmsg
,
291 (int sockfd
, struct mmsghdr
*msg
, size_t vlen
, int flags
,
292 struct timespec
*tmo
),
293 (sockfd
, msg
, vlen
, flags
, tmo
))
294 lt_libc_hidden(recvmmsg
)
299 static ssize_t
__NC(send
)(int sockfd
, const void *buffer
, size_t len
, int flags
)
302 return (ssize_t
)INLINE_SYSCALL(send
, 4, sockfd
, buffer
, len
, flags
);
303 # elif defined __NR_sendto && defined _syscall6
304 return __NC(sendto
)(sockfd
, buffer
, len
, flags
, NULL
, 0);
305 # elif defined(__NR_socketcall)
306 unsigned long args
[4];
309 args
[1] = (unsigned long) buffer
;
312 return (ssize_t
)__socketcall(SYS_SEND
, args
);
315 CANCELLABLE_SYSCALL(ssize_t
, send
, (int sockfd
, const void *buffer
, size_t len
, int flags
),
316 (sockfd
, buffer
, len
, flags
))
321 static ssize_t
__NC(sendmsg
)(int sockfd
, const struct msghdr
*msg
, int flags
)
324 return (ssize_t
)INLINE_SYSCALL(sendmsg
, 3, sockfd
, msg
, flags
);
325 # elif defined(__NR_socketcall)
326 unsigned long args
[3];
329 args
[1] = (unsigned long) msg
;
331 return (ssize_t
)__socketcall(SYS_SENDMSG
, args
);
334 CANCELLABLE_SYSCALL(ssize_t
, sendmsg
, (int sockfd
, const struct msghdr
*msg
, int flags
),
335 (sockfd
, msg
, flags
))
336 lt_libc_hidden(sendmsg
)
340 #ifdef __ASSUME_SENDMMSG_SYSCALL
341 static ssize_t
__NC(sendmmsg
)(int sockfd
, struct mmsghdr
*msg
, size_t vlen
,
344 # ifdef __NR_sendmmsg
345 return (ssize_t
)INLINE_SYSCALL(sendmmsg
, 4, sockfd
, msg
, vlen
, flags
);
346 # elif __NR_socketcall
347 unsigned long args
[4];
350 args
[1] = (unsigned long) msg
;
353 return (ssize_t
)__socketcall(SYS_SENDMMSG
, args
);
356 CANCELLABLE_SYSCALL(ssize_t
, sendmmsg
,
357 (int sockfd
, struct mmsghdr
*msg
, size_t vlen
, int flags
),
358 (sockfd
, msg
, vlen
, flags
))
359 lt_libc_hidden(sendmmsg
)
364 ssize_t
__NC(sendto
)(int sockfd
, const void *buffer
, size_t len
, int flags
,
365 const struct sockaddr
*to
, socklen_t tolen
)
367 # if defined __NR_sendto && defined _syscall6
368 return (ssize_t
)INLINE_SYSCALL(sendto
, 6, sockfd
, buffer
, len
, flags
, to
, tolen
);
369 # elif defined(__NR_socketcall)
370 unsigned long args
[6];
373 args
[1] = (unsigned long) buffer
;
376 args
[4] = (unsigned long) to
;
378 return (ssize_t
)__socketcall(SYS_SENDTO
, args
);
381 CANCELLABLE_SYSCALL(ssize_t
, sendto
, (int sockfd
, const void *buffer
, size_t len
,
382 int flags
, const struct sockaddr
*to
, socklen_t tolen
),
383 (sockfd
, buffer
, len
, flags
, to
, tolen
))
384 lt_libc_hidden(sendto
)
388 int setsockopt(int fd
, int level
, int optname
, const void *optval
, socklen_t optlen
)
390 # ifdef __NR_setsockopt
391 return INLINE_SYSCALL(setsockopt
, 5, fd
, level
, optname
, optval
, optlen
);
392 # elif defined(__NR_socketcall)
393 unsigned long args
[5];
398 args
[3] = (unsigned long) optval
;
400 return __socketcall(SYS_SETSOCKOPT
, args
);
403 libc_hidden_def(setsockopt
)
407 int shutdown(int sockfd
, int how
)
409 # ifdef __NR_shutdown
410 return INLINE_SYSCALL(shutdown
, 2, sockfd
, how
);
411 # elif defined(__NR_socketcall)
412 unsigned long args
[2];
416 return __socketcall(SYS_SHUTDOWN
, args
);
422 int socket(int family
, int type
, int protocol
)
425 return INLINE_SYSCALL(socket
, 3, family
, type
, protocol
);
426 # elif defined(__NR_socketcall)
427 unsigned long args
[3];
431 args
[2] = (unsigned long) protocol
;
432 return __socketcall(SYS_SOCKET
, args
);
435 libc_hidden_def(socket
)
439 int socketpair(int family
, int type
, int protocol
, int sockvec
[2])
441 # ifdef __NR_socketpair
442 return INLINE_SYSCALL(socketpair
, 4, family
, type
, protocol
, sockvec
);
443 # elif defined(__NR_socketcall)
444 unsigned long args
[4];
449 args
[3] = (unsigned long) sockvec
;
450 return __socketcall(SYS_SOCKETPAIR
, args
);