NPTL/arc: notify kernel of the TP value
[uClibc.git] / libc / inet / socketcalls.c
blob6f4054b7dd8317df875b80404d2648b8edc1d8f6
1 /*
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.
5 */
7 #include <stddef.h>
8 #include <sys/syscall.h>
9 #include <sys/socket.h>
10 #include <cancel.h>
12 #ifdef __NR_socketcall
13 /* Various socketcall numbers */
14 #define SYS_SOCKET 1
15 #define SYS_BIND 2
16 #define SYS_CONNECT 3
17 #define SYS_LISTEN 4
18 #define SYS_ACCEPT 5
19 #define SYS_GETSOCKNAME 6
20 #define SYS_GETPEERNAME 7
21 #define SYS_SOCKETPAIR 8
22 #define SYS_SEND 9
23 #define SYS_RECV 10
24 #define SYS_SENDTO 11
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
32 #endif
34 #ifdef __sparc__
35 #undef __NR_accept
36 #undef __NR_accept4
37 #undef __NR_bind
38 #undef __NR_connect
39 #undef __NR_getpeername
40 #undef __NR_getsockname
41 #undef __NR_getsockopt
42 #undef __NR_listen
43 #undef __NR_recv
44 #undef __NR_recvfrom
45 #undef __NR_recvmsg
46 #undef __NR_send
47 #undef __NR_sendmsg
48 #undef __NR_sendto
49 #undef __NR_setsockopt
50 #undef __NR_shutdown
51 #undef __NR_socket
52 #undef __NR_socketpair
53 #endif
55 #ifdef L_accept
56 static int __NC(accept)(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
58 # ifdef __NR_accept
59 return INLINE_SYSCALL(accept, 3, sockfd, addr, addrlen);
60 # else
61 unsigned long args[3];
63 args[0] = sockfd;
64 args[1] = (unsigned long) addr;
65 args[2] = (unsigned long) addrlen;
67 return __socketcall(SYS_ACCEPT, args);
68 # endif
70 CANCELLABLE_SYSCALL(int, accept, (int sockfd, struct sockaddr *addr, socklen_t *addrlen),
71 (sockfd, addr, addrlen))
72 lt_libc_hidden(accept)
73 #endif
75 #ifdef L_accept4
76 #ifdef __NR_accept4
77 # define __NR___sys_accept4 __NR_accept4
78 static _syscall4(int, __sys_accept4, int, fd, struct sockaddr *, addr, socklen_t *, addrlen, int, flags)
79 int accept4(int fd, struct sockaddr *addr, socklen_t * addrlen, int flags)
81 if (SINGLE_THREAD_P)
82 return __sys_accept4(fd, addr, addrlen, flags);
83 #ifdef __UCLIBC_HAS_THREADS_NATIVE__
84 else {
85 int oldtype = LIBC_CANCEL_ASYNC ();
86 int result = __sys_accept4(fd, addr, addrlen, flags);
87 LIBC_CANCEL_RESET (oldtype);
88 return result;
90 #endif
92 #elif defined(__NR_socketcall)
93 int accept4(int fd, struct sockaddr *addr, socklen_t *addrlen, int flags)
95 unsigned long args[4];
97 args[0] = fd;
98 args[1] = (unsigned long) addr;
99 args[2] = (unsigned long) addrlen;
100 args[3] = flags;
101 if (SINGLE_THREAD_P)
102 return __socketcall(SYS_ACCEPT4, args);
103 #ifdef __UCLIBC_HAS_THREADS_NATIVE__
104 else {
105 int oldtype = LIBC_CANCEL_ASYNC ();
106 int result = __socketcall(SYS_ACCEPT4, args);
107 LIBC_CANCEL_RESET (oldtype);
108 return result;
110 #endif
112 #endif
113 #endif
115 #ifdef L_bind
116 int bind(int sockfd, const struct sockaddr *myaddr, socklen_t addrlen)
118 # ifdef __NR_bind
119 return INLINE_SYSCALL(bind, 3, sockfd, myaddr, addrlen);
120 # else
121 unsigned long args[3];
123 args[0] = sockfd;
124 args[1] = (unsigned long) myaddr;
125 args[2] = addrlen;
126 return __socketcall(SYS_BIND, args);
127 # endif
129 libc_hidden_def(bind)
130 #endif
132 #ifdef L_connect
133 static int __NC(connect)(int sockfd, const struct sockaddr *saddr, socklen_t addrlen)
135 # ifdef __NR_connect
136 return INLINE_SYSCALL(connect, 3, sockfd, saddr, addrlen);
137 # else
138 unsigned long args[3];
140 args[0] = sockfd;
141 args[1] = (unsigned long) saddr;
142 args[2] = addrlen;
143 return __socketcall(SYS_CONNECT, args);
144 # endif
146 CANCELLABLE_SYSCALL(int, connect, (int sockfd, const struct sockaddr *saddr, socklen_t addrlen),
147 (sockfd, saddr, addrlen))
148 lt_libc_hidden(connect)
149 #endif
151 #ifdef L_getpeername
152 int getpeername(int sockfd, struct sockaddr *addr, socklen_t *paddrlen)
154 # ifdef __NR_getpeername
155 return INLINE_SYSCALL(getpeername, 3, sockfd, addr, paddrlen);
156 # else
157 unsigned long args[3];
159 args[0] = sockfd;
160 args[1] = (unsigned long) addr;
161 args[2] = (unsigned long) paddrlen;
162 return __socketcall(SYS_GETPEERNAME, args);
163 # endif
165 #endif
167 #ifdef L_getsockname
168 int getsockname(int sockfd, struct sockaddr *addr, socklen_t * paddrlen)
170 # ifdef __NR_getsockname
171 return INLINE_SYSCALL(getsockname, 3, sockfd, addr, paddrlen);
172 # else
173 unsigned long args[3];
175 args[0] = sockfd;
176 args[1] = (unsigned long) addr;
177 args[2] = (unsigned long) paddrlen;
178 return __socketcall(SYS_GETSOCKNAME, args);
179 # endif
181 libc_hidden_def(getsockname)
182 #endif
184 #ifdef L_getsockopt
185 int getsockopt(int fd, int level, int optname, void *optval,
186 socklen_t *optlen)
188 # ifdef __NR_getsockopt
189 return INLINE_SYSCALL(getsockopt, 5, fd, level, optname, optval, optlen);
190 # else
191 unsigned long args[5];
193 args[0] = fd;
194 args[1] = level;
195 args[2] = optname;
196 args[3] = (unsigned long) optval;
197 args[4] = (unsigned long) optlen;
198 return (__socketcall(SYS_GETSOCKOPT, args));
199 # endif
201 #endif
203 #ifdef L_listen
204 int listen(int sockfd, int backlog)
206 # ifdef __NR_listen
207 return INLINE_SYSCALL(listen, 2, sockfd, backlog);
208 # else
209 unsigned long args[2];
211 args[0] = sockfd;
212 args[1] = backlog;
213 return __socketcall(SYS_LISTEN, args);
214 # endif
216 libc_hidden_def(listen)
217 #endif
219 #ifdef L_recv
220 static ssize_t __NC(recv)(int sockfd, void *buffer, size_t len, int flags)
222 # ifdef __NR_recv
223 return (ssize_t)INLINE_SYSCALL(recv, 4, sockfd, buffer, len, flags);
224 # elif defined __NR_recvfrom && defined _syscall6
225 return __NC(recvfrom)(sockfd, buffer, len, flags, NULL, NULL);
226 # else
227 unsigned long args[4];
229 args[0] = sockfd;
230 args[1] = (unsigned long) buffer;
231 args[2] = len;
232 args[3] = flags;
233 return (ssize_t)__socketcall(SYS_RECV, args);
234 # endif
236 CANCELLABLE_SYSCALL(ssize_t, recv, (int sockfd, void *buffer, size_t len, int flags),
237 (sockfd, buffer, len, flags))
238 lt_libc_hidden(recv)
239 #endif
241 #ifdef L_recvfrom
242 ssize_t __NC(recvfrom)(int sockfd, void *buffer, size_t len, int flags,
243 struct sockaddr *to, socklen_t *tolen)
245 # if defined __NR_recvfrom && defined _syscall6
246 return (ssize_t)INLINE_SYSCALL(recvfrom, 6, sockfd, buffer, len,
247 flags, to, tolen);
248 # else
249 unsigned long args[6];
251 args[0] = sockfd;
252 args[1] = (unsigned long) buffer;
253 args[2] = len;
254 args[3] = flags;
255 args[4] = (unsigned long) to;
256 args[5] = (unsigned long) tolen;
257 return (ssize_t)__socketcall(SYS_RECVFROM, args);
258 # endif
260 CANCELLABLE_SYSCALL(ssize_t, recvfrom, (int sockfd, void *buffer, size_t len,
261 int flags, struct sockaddr *to, socklen_t *tolen),
262 (sockfd, buffer, len, flags, to, tolen))
263 lt_libc_hidden(recvfrom)
264 #endif
266 #ifdef L_recvmsg
267 static ssize_t __NC(recvmsg)(int sockfd, struct msghdr *msg, int flags)
269 # ifdef __NR_recvmsg
270 return (ssize_t)INLINE_SYSCALL(recvmsg, 3, sockfd, msg, flags);
271 # else
272 unsigned long args[3];
274 args[0] = sockfd;
275 args[1] = (unsigned long) msg;
276 args[2] = flags;
277 return (ssize_t)__socketcall(SYS_RECVMSG, args);
278 # endif
280 CANCELLABLE_SYSCALL(ssize_t, recvmsg, (int sockfd, struct msghdr *msg, int flags),
281 (sockfd, msg, flags))
282 lt_libc_hidden(recvmsg)
283 #endif
285 #ifdef L_send
286 static ssize_t __NC(send)(int sockfd, const void *buffer, size_t len, int flags)
288 # ifdef __NR_send
289 return (ssize_t)INLINE_SYSCALL(send, 4, sockfd, buffer, len, flags);
290 # elif defined __NR_sendto && defined _syscall6
291 return __NC(sendto)(sockfd, buffer, len, flags, NULL, 0);
292 # else
293 unsigned long args[4];
295 args[0] = sockfd;
296 args[1] = (unsigned long) buffer;
297 args[2] = len;
298 args[3] = flags;
299 return (ssize_t)__socketcall(SYS_SEND, args);
300 # endif
302 CANCELLABLE_SYSCALL(ssize_t, send, (int sockfd, const void *buffer, size_t len, int flags),
303 (sockfd, buffer, len, flags))
304 lt_libc_hidden(send)
305 #endif
307 #ifdef L_sendmsg
308 static ssize_t __NC(sendmsg)(int sockfd, const struct msghdr *msg, int flags)
310 # ifdef __NR_sendmsg
311 return (ssize_t)INLINE_SYSCALL(sendmsg, 3, sockfd, msg, flags);
312 # else
313 unsigned long args[3];
315 args[0] = sockfd;
316 args[1] = (unsigned long) msg;
317 args[2] = flags;
318 return (ssize_t)__socketcall(SYS_SENDMSG, args);
319 # endif
321 CANCELLABLE_SYSCALL(ssize_t, sendmsg, (int sockfd, const struct msghdr *msg, int flags),
322 (sockfd, msg, flags))
323 lt_libc_hidden(sendmsg)
324 #endif
326 #ifdef L_sendto
327 ssize_t __NC(sendto)(int sockfd, const void *buffer, size_t len, int flags,
328 const struct sockaddr *to, socklen_t tolen)
330 # if defined __NR_sendto && defined _syscall6
331 return (ssize_t)INLINE_SYSCALL(sendto, 6, sockfd, buffer, len, flags, to, tolen);
332 # else
333 unsigned long args[6];
335 args[0] = sockfd;
336 args[1] = (unsigned long) buffer;
337 args[2] = len;
338 args[3] = flags;
339 args[4] = (unsigned long) to;
340 args[5] = tolen;
341 return (ssize_t)__socketcall(SYS_SENDTO, args);
342 # endif
344 CANCELLABLE_SYSCALL(ssize_t, sendto, (int sockfd, const void *buffer, size_t len,
345 int flags, const struct sockaddr *to, socklen_t tolen),
346 (sockfd, buffer, len, flags, to, tolen))
347 lt_libc_hidden(sendto)
348 #endif
350 #ifdef L_setsockopt
351 int setsockopt(int fd, int level, int optname, const void *optval, socklen_t optlen)
353 # ifdef __NR_setsockopt
354 return INLINE_SYSCALL(setsockopt, 5, fd, level, optname, optval, optlen);
355 # else
356 unsigned long args[5];
358 args[0] = fd;
359 args[1] = level;
360 args[2] = optname;
361 args[3] = (unsigned long) optval;
362 args[4] = optlen;
363 return __socketcall(SYS_SETSOCKOPT, args);
364 # endif
366 libc_hidden_def(setsockopt)
367 #endif
369 #ifdef L_shutdown
370 int shutdown(int sockfd, int how)
372 # ifdef __NR_shutdown
373 return INLINE_SYSCALL(shutdown, 2, sockfd, how);
374 # else
375 unsigned long args[2];
377 args[0] = sockfd;
378 args[1] = how;
379 return __socketcall(SYS_SHUTDOWN, args);
380 # endif
382 #endif
384 #ifdef L_socket
385 int socket(int family, int type, int protocol)
387 # ifdef __NR_socket
388 return INLINE_SYSCALL(socket, 3, family, type, protocol);
389 # else
390 unsigned long args[3];
392 args[0] = family;
393 args[1] = type;
394 args[2] = (unsigned long) protocol;
395 return __socketcall(SYS_SOCKET, args);
396 # endif
398 libc_hidden_def(socket)
399 #endif
401 #ifdef L_socketpair
402 int socketpair(int family, int type, int protocol, int sockvec[2])
404 # ifdef __NR_socketpair
405 return INLINE_SYSCALL(socketpair, 4, family, type, protocol, sockvec);
406 # else
407 unsigned long args[4];
409 args[0] = family;
410 args[1] = type;
411 args[2] = protocol;
412 args[3] = (unsigned long) sockvec;
413 return __socketcall(SYS_SOCKETPAIR, args);
414 # endif
416 #endif