socketcalls.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562
  1. /*
  2. * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
  3. *
  4. * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
  5. */
  6. #define __FORCE_GLIBC
  7. #include <features.h>
  8. #include <errno.h>
  9. #include <syscall.h>
  10. #include <sys/socket.h>
  11. #ifdef __NR_socketcall
  12. extern int __socketcall(int call, unsigned long *args) attribute_hidden;
  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. #endif
  32. #ifdef __UCLIBC_HAS_THREADS_NATIVE__
  33. #include <sysdep-cancel.h>
  34. #include <pthreadP.h>
  35. #else
  36. #define SINGLE_THREAD_P 1
  37. #endif
  38. #ifdef L_accept
  39. extern __typeof(accept) __libc_accept;
  40. #ifdef __NR_accept
  41. #define __NR___sys_accept __NR_accept
  42. static
  43. _syscall3(int, __sys_accept, int, call, struct sockaddr *, addr, socklen_t *,addrlen)
  44. int __libc_accept(int s, struct sockaddr *addr, socklen_t * addrlen)
  45. {
  46. if (SINGLE_THREAD_P)
  47. return __sys_accept(s, addr, addrlen);
  48. #ifdef __UCLIBC_HAS_THREADS_NATIVE__
  49. int oldtype = LIBC_CANCEL_ASYNC ();
  50. int result = __sys_accept(s, addr, addrlen);
  51. LIBC_CANCEL_RESET (oldtype);
  52. return result;
  53. #endif
  54. }
  55. #elif defined(__NR_socketcall)
  56. int __libc_accept(int s, struct sockaddr *addr, socklen_t * addrlen)
  57. {
  58. unsigned long args[3];
  59. args[0] = s;
  60. args[1] = (unsigned long) addr;
  61. args[2] = (unsigned long) addrlen;
  62. if (SINGLE_THREAD_P)
  63. return __socketcall(SYS_ACCEPT, args);
  64. #ifdef __UCLIBC_HAS_THREADS_NATIVE__
  65. int oldtype = LIBC_CANCEL_ASYNC ();
  66. int result = __socketcall(SYS_ACCEPT, args);
  67. LIBC_CANCEL_RESET (oldtype);
  68. return result;
  69. #endif
  70. }
  71. #endif
  72. weak_alias(__libc_accept,accept)
  73. libc_hidden_weak(accept)
  74. #endif
  75. #ifdef L_bind
  76. #ifdef __NR_bind
  77. _syscall3(int, bind, int, sockfd, const struct sockaddr *, myaddr, socklen_t, addrlen)
  78. #elif defined(__NR_socketcall)
  79. int bind(int sockfd, const struct sockaddr *myaddr, socklen_t addrlen)
  80. {
  81. unsigned long args[3];
  82. args[0] = sockfd;
  83. args[1] = (unsigned long) myaddr;
  84. args[2] = addrlen;
  85. return __socketcall(SYS_BIND, args);
  86. }
  87. #endif
  88. libc_hidden_def(bind)
  89. #endif
  90. #ifdef L_connect
  91. extern __typeof(connect) __libc_connect;
  92. #ifdef __NR_connect
  93. #define __NR___sys_connect __NR_connect
  94. static
  95. _syscall3(int, __sys_connect, int, sockfd, const struct sockaddr *, saddr, socklen_t, addrlen)
  96. int __libc_connect(int sockfd, const struct sockaddr *saddr, socklen_t addrlen)
  97. {
  98. if (SINGLE_THREAD_P)
  99. return __sys_connect(sockfd, saddr, addrlen);
  100. #ifdef __UCLIBC_HAS_THREADS_NATIVE__
  101. int oldtype = LIBC_CANCEL_ASYNC ();
  102. int result = __sys_connect(sockfd, saddr, addrlen);
  103. LIBC_CANCEL_RESET (oldtype);
  104. return result;
  105. #endif
  106. }
  107. #elif defined(__NR_socketcall)
  108. int __libc_connect(int sockfd, const struct sockaddr *saddr, socklen_t addrlen)
  109. {
  110. unsigned long args[3];
  111. args[0] = sockfd;
  112. args[1] = (unsigned long) saddr;
  113. args[2] = addrlen;
  114. if (SINGLE_THREAD_P)
  115. return __socketcall(SYS_CONNECT, args);
  116. #ifdef __UCLIBC_HAS_THREADS_NATIVE__
  117. int oldtype = LIBC_CANCEL_ASYNC ();
  118. int result = __socketcall(SYS_CONNECT, args);
  119. LIBC_CANCEL_RESET (oldtype);
  120. return result;
  121. #endif
  122. }
  123. #endif
  124. weak_alias(__libc_connect,connect)
  125. libc_hidden_weak(connect)
  126. #endif
  127. #ifdef L_getpeername
  128. #ifdef __NR_getpeername
  129. _syscall3(int, getpeername, int, sockfd, struct sockaddr *, addr, socklen_t *,paddrlen)
  130. #elif defined(__NR_socketcall)
  131. int getpeername(int sockfd, struct sockaddr *addr, socklen_t * paddrlen)
  132. {
  133. unsigned long args[3];
  134. args[0] = sockfd;
  135. args[1] = (unsigned long) addr;
  136. args[2] = (unsigned long) paddrlen;
  137. return __socketcall(SYS_GETPEERNAME, args);
  138. }
  139. #endif
  140. #endif
  141. #ifdef L_getsockname
  142. #ifdef __NR_getsockname
  143. _syscall3(int, getsockname, int, sockfd, struct sockaddr *, addr, socklen_t *,paddrlen)
  144. #elif defined(__NR_socketcall)
  145. int getsockname(int sockfd, struct sockaddr *addr, socklen_t * paddrlen)
  146. {
  147. unsigned long args[3];
  148. args[0] = sockfd;
  149. args[1] = (unsigned long) addr;
  150. args[2] = (unsigned long) paddrlen;
  151. return __socketcall(SYS_GETSOCKNAME, args);
  152. }
  153. #endif
  154. libc_hidden_def(getsockname)
  155. #endif
  156. #ifdef L_getsockopt
  157. #ifdef __NR_getsockopt
  158. _syscall5(int, getsockopt, int, fd, int, level, int, optname, __ptr_t, optval, socklen_t *, optlen)
  159. #elif defined(__NR_socketcall)
  160. int getsockopt(int fd, int level, int optname, __ptr_t optval,
  161. socklen_t * optlen)
  162. {
  163. unsigned long args[5];
  164. args[0] = fd;
  165. args[1] = level;
  166. args[2] = optname;
  167. args[3] = (unsigned long) optval;
  168. args[4] = (unsigned long) optlen;
  169. return (__socketcall(SYS_GETSOCKOPT, args));
  170. }
  171. #endif
  172. #endif
  173. #ifdef L_listen
  174. #ifdef __NR_listen
  175. _syscall2(int, listen, int, sockfd, int, backlog)
  176. #elif defined(__NR_socketcall)
  177. int listen(int sockfd, int backlog)
  178. {
  179. unsigned long args[2];
  180. args[0] = sockfd;
  181. args[1] = backlog;
  182. return __socketcall(SYS_LISTEN, args);
  183. }
  184. #endif
  185. libc_hidden_def(listen)
  186. #endif
  187. #ifdef L_recv
  188. extern __typeof(recv) __libc_recv;
  189. #ifdef __NR_recv
  190. #define __NR___sys_recv __NR_recv
  191. static
  192. _syscall4(ssize_t, __sys_recv, int, sockfd, __ptr_t, buffer, size_t, len,
  193. int, flags)
  194. ssize_t __libc_recv(int sockfd, __ptr_t buffer, size_t len, int flags)
  195. {
  196. if (SINGLE_THREAD_P)
  197. return __sys_recv(sockfd, buffer, len, flags);
  198. #ifdef __UCLIBC_HAS_THREADS_NATIVE__
  199. int oldtype = LIBC_CANCEL_ASYNC ();
  200. int result = __sys_recv(sockfd, buffer, len, flags);
  201. LIBC_CANCEL_RESET (oldtype);
  202. return result;
  203. #endif
  204. }
  205. #elif defined(__NR_socketcall)
  206. /* recv, recvfrom added by bir7@leland.stanford.edu */
  207. ssize_t __libc_recv(int sockfd, __ptr_t buffer, size_t len, int flags)
  208. {
  209. unsigned long args[4];
  210. args[0] = sockfd;
  211. args[1] = (unsigned long) buffer;
  212. args[2] = len;
  213. args[3] = flags;
  214. if (SINGLE_THREAD_P)
  215. return (__socketcall(SYS_RECV, args));
  216. #ifdef __UCLIBC_HAS_THREADS_NATIVE__
  217. int oldtype = LIBC_CANCEL_ASYNC ();
  218. int result = __socketcall(SYS_RECV, args);
  219. LIBC_CANCEL_RESET (oldtype);
  220. return result;
  221. #endif
  222. }
  223. #elif defined(__NR_recvfrom)
  224. ssize_t __libc_recv(int sockfd, __ptr_t buffer, size_t len, int flags)
  225. {
  226. return (recvfrom(sockfd, buffer, len, flags, NULL, NULL));
  227. }
  228. #endif
  229. weak_alias(__libc_recv,recv)
  230. libc_hidden_weak(recv)
  231. #endif
  232. #ifdef L_recvfrom
  233. extern __typeof(recvfrom) __libc_recvfrom;
  234. #ifdef __NR_recvfrom
  235. #define __NR___sys_recvfrom __NR_recvfrom
  236. static
  237. _syscall6(ssize_t, __sys_recvfrom, int, sockfd, __ptr_t, buffer, size_t, len,
  238. int, flags, struct sockaddr *, to, socklen_t *, tolen)
  239. ssize_t __libc_recvfrom(int sockfd, __ptr_t buffer, size_t len, int flags,
  240. struct sockaddr *to, socklen_t * tolen)
  241. {
  242. if (SINGLE_THREAD_P)
  243. return __sys_recvfrom(sockfd, buffer, len, flags, to, tolen);
  244. #ifdef __UCLIBC_HAS_THREADS_NATIVE__
  245. int oldtype = LIBC_CANCEL_ASYNC ();
  246. int result = __sys_recvfrom(sockfd, buffer, len, flags, to, tolen);
  247. LIBC_CANCEL_RESET (oldtype);
  248. return result;
  249. #endif
  250. }
  251. #elif defined(__NR_socketcall)
  252. /* recv, recvfrom added by bir7@leland.stanford.edu */
  253. ssize_t __libc_recvfrom(int sockfd, __ptr_t buffer, size_t len, int flags,
  254. struct sockaddr *to, socklen_t * tolen)
  255. {
  256. unsigned long args[6];
  257. args[0] = sockfd;
  258. args[1] = (unsigned long) buffer;
  259. args[2] = len;
  260. args[3] = flags;
  261. args[4] = (unsigned long) to;
  262. args[5] = (unsigned long) tolen;
  263. if (SINGLE_THREAD_P)
  264. return (__socketcall(SYS_RECVFROM, args));
  265. #ifdef __UCLIBC_HAS_THREADS_NATIVE__
  266. int oldtype = LIBC_CANCEL_ASYNC ();
  267. int result = __socketcall(SYS_RECVFROM, args);
  268. LIBC_CANCEL_RESET (oldtype);
  269. return result;
  270. #endif
  271. }
  272. #endif
  273. weak_alias(__libc_recvfrom,recvfrom)
  274. libc_hidden_weak(recvfrom)
  275. #endif
  276. #ifdef L_recvmsg
  277. extern __typeof(recvmsg) __libc_recvmsg;
  278. #ifdef __NR_recvmsg
  279. #define __NR___sys_recvmsg __NR_recvmsg
  280. static
  281. _syscall3(ssize_t, __sys_recvmsg, int, sockfd, struct msghdr *, msg, int, flags)
  282. ssize_t __libc_recvmsg(int sockfd, struct msghdr *msg, int flags)
  283. {
  284. if (SINGLE_THREAD_P)
  285. return __sys_recvmsg(sockfd, msg, flags);
  286. #ifdef __UCLIBC_HAS_THREADS_NATIVE__
  287. int oldtype = LIBC_CANCEL_ASYNC ();
  288. int result = __sys_recvmsg(sockfd, msg, flags);
  289. LIBC_CANCEL_RESET (oldtype);
  290. return result;
  291. #endif
  292. }
  293. #elif defined(__NR_socketcall)
  294. ssize_t __libc_recvmsg(int sockfd, struct msghdr *msg, int flags)
  295. {
  296. unsigned long args[3];
  297. args[0] = sockfd;
  298. args[1] = (unsigned long) msg;
  299. args[2] = flags;
  300. if (SINGLE_THREAD_P)
  301. return (__socketcall(SYS_RECVMSG, args));
  302. #ifdef __UCLIBC_HAS_THREADS_NATIVE__
  303. int oldtype = LIBC_CANCEL_ASYNC ();
  304. int result = __socketcall(SYS_RECVMSG, args);
  305. LIBC_CANCEL_RESET (oldtype);
  306. return result;
  307. #endif
  308. }
  309. #endif
  310. weak_alias(__libc_recvmsg,recvmsg)
  311. libc_hidden_weak(recvmsg)
  312. #endif
  313. #ifdef L_send
  314. extern __typeof(send) __libc_send;
  315. #ifdef __NR_send
  316. #define __NR___sys_send __NR_send
  317. static
  318. _syscall4(ssize_t, __sys_send, int, sockfd, const void *, buffer, size_t, len, int, flags)
  319. ssize_t __libc_send(int sockfd, const void *buffer, size_t len, int flags)
  320. {
  321. if (SINGLE_THREAD_P)
  322. return __sys_send(sockfd, buffer, len, flags);
  323. #ifdef __UCLIBC_HAS_THREADS_NATIVE__
  324. int oldtype = LIBC_CANCEL_ASYNC ();
  325. int result = __sys_send(sockfd, buffer, len, flags);
  326. LIBC_CANCEL_RESET (oldtype);
  327. return result;
  328. #endif
  329. }
  330. #elif defined(__NR_socketcall)
  331. /* send, sendto added by bir7@leland.stanford.edu */
  332. ssize_t __libc_send(int sockfd, const void *buffer, size_t len, int flags)
  333. {
  334. unsigned long args[4];
  335. args[0] = sockfd;
  336. args[1] = (unsigned long) buffer;
  337. args[2] = len;
  338. args[3] = flags;
  339. if (SINGLE_THREAD_P)
  340. return (__socketcall(SYS_SEND, args));
  341. #ifdef __UCLIBC_HAS_THREADS_NATIVE__
  342. int oldtype = LIBC_CANCEL_ASYNC ();
  343. int result = __socketcall(SYS_SEND, args);
  344. LIBC_CANCEL_RESET (oldtype);
  345. return result;
  346. #endif
  347. }
  348. #elif defined(__NR_sendto)
  349. ssize_t __libc_send(int sockfd, const void *buffer, size_t len, int flags)
  350. {
  351. return (sendto(sockfd, buffer, len, flags, NULL, 0));
  352. }
  353. #endif
  354. weak_alias(__libc_send,send)
  355. libc_hidden_weak(send)
  356. #endif
  357. #ifdef L_sendmsg
  358. extern __typeof(sendmsg) __libc_sendmsg;
  359. #ifdef __NR_sendmsg
  360. #define __NR___sys_sendmsg __NR_sendmsg
  361. static
  362. _syscall3(ssize_t, __sys_sendmsg, int, sockfd, const struct msghdr *, msg, int, flags)
  363. ssize_t __libc_sendmsg(int sockfd, const struct msghdr *msg, int flags)
  364. {
  365. if (SINGLE_THREAD_P)
  366. return __sys_sendmsg(sockfd, msg, flags);
  367. #ifdef __UCLIBC_HAS_THREADS_NATIVE__
  368. int oldtype = LIBC_CANCEL_ASYNC ();
  369. int result = __sys_sendmsg(sockfd, msg, flags);
  370. LIBC_CANCEL_RESET (oldtype);
  371. return result;
  372. #endif
  373. }
  374. #elif defined(__NR_socketcall)
  375. ssize_t __libc_sendmsg(int sockfd, const struct msghdr *msg, int flags)
  376. {
  377. unsigned long args[3];
  378. args[0] = sockfd;
  379. args[1] = (unsigned long) msg;
  380. args[2] = flags;
  381. if (SINGLE_THREAD_P)
  382. return (__socketcall(SYS_SENDMSG, args));
  383. #ifdef __UCLIBC_HAS_THREADS_NATIVE__
  384. int oldtype = LIBC_CANCEL_ASYNC ();
  385. int result = __socketcall(SYS_SENDMSG, args);
  386. LIBC_CANCEL_RESET (oldtype);
  387. return result;
  388. #endif
  389. }
  390. #endif
  391. weak_alias(__libc_sendmsg,sendmsg)
  392. libc_hidden_weak(sendmsg)
  393. #endif
  394. #ifdef L_sendto
  395. extern __typeof(sendto) __libc_sendto;
  396. #ifdef __NR_sendto
  397. #define __NR___sys_sendto __NR_sendto
  398. static
  399. _syscall6(ssize_t, __sys_sendto, int, sockfd, const void *, buffer,
  400. size_t, len, int, flags, const struct sockaddr *, to, socklen_t, tolen)
  401. ssize_t __libc_sendto(int sockfd, const void *buffer, size_t len, int flags,const struct sockaddr *to, socklen_t tolen)
  402. {
  403. if (SINGLE_THREAD_P)
  404. return __sys_sendto(sockfd, buffer, len, flags, to, tolen);
  405. #ifdef __UCLIBC_HAS_THREADS_NATIVE__
  406. int oldtype = LIBC_CANCEL_ASYNC ();
  407. int result = __sys_sendto(sockfd, buffer, len, flags, to, tolen);
  408. LIBC_CANCEL_RESET (oldtype);
  409. return result;
  410. #endif
  411. }
  412. #elif defined(__NR_socketcall)
  413. /* send, sendto added by bir7@leland.stanford.edu */
  414. ssize_t __libc_sendto(int sockfd, const void *buffer, size_t len, int flags,
  415. const struct sockaddr *to, socklen_t tolen)
  416. {
  417. unsigned long args[6];
  418. args[0] = sockfd;
  419. args[1] = (unsigned long) buffer;
  420. args[2] = len;
  421. args[3] = flags;
  422. args[4] = (unsigned long) to;
  423. args[5] = tolen;
  424. if (SINGLE_THREAD_P)
  425. return (__socketcall(SYS_SENDTO, args));
  426. #ifdef __UCLIBC_HAS_THREADS_NATIVE__
  427. int oldtype = LIBC_CANCEL_ASYNC ();
  428. int result = __socketcall(SYS_SENDTO, args);
  429. LIBC_CANCEL_RESET (oldtype);
  430. return result;
  431. #endif
  432. }
  433. #endif
  434. weak_alias(__libc_sendto,sendto)
  435. libc_hidden_weak(sendto)
  436. #endif
  437. #ifdef L_setsockopt
  438. #ifdef __NR_setsockopt
  439. _syscall5(int, setsockopt, int, fd, int, level, int, optname, const void *, optval, socklen_t, optlen)
  440. #elif defined(__NR_socketcall)
  441. /* [sg]etsockoptions by bir7@leland.stanford.edu */
  442. int setsockopt(int fd, int level, int optname, const void *optval,
  443. socklen_t optlen)
  444. {
  445. unsigned long args[5];
  446. args[0] = fd;
  447. args[1] = level;
  448. args[2] = optname;
  449. args[3] = (unsigned long) optval;
  450. args[4] = optlen;
  451. return (__socketcall(SYS_SETSOCKOPT, args));
  452. }
  453. #endif
  454. libc_hidden_def(setsockopt)
  455. #endif
  456. #ifdef L_shutdown
  457. #ifdef __NR_shutdown
  458. _syscall2(int, shutdown, int, sockfd, int, how)
  459. #elif defined(__NR_socketcall)
  460. /* shutdown by bir7@leland.stanford.edu */
  461. int shutdown(int sockfd, int how)
  462. {
  463. unsigned long args[2];
  464. args[0] = sockfd;
  465. args[1] = how;
  466. return (__socketcall(SYS_SHUTDOWN, args));
  467. }
  468. #endif
  469. #endif
  470. #ifdef L_socket
  471. #ifdef __NR_socket
  472. _syscall3(int, socket, int, family, int, type, int, protocol)
  473. #elif defined(__NR_socketcall)
  474. int socket(int family, int type, int protocol)
  475. {
  476. unsigned long args[3];
  477. args[0] = family;
  478. args[1] = type;
  479. args[2] = (unsigned long) protocol;
  480. return __socketcall(SYS_SOCKET, args);
  481. }
  482. #endif
  483. libc_hidden_def(socket)
  484. #endif
  485. #ifdef L_socketpair
  486. #ifdef __NR_socketpair
  487. _syscall4(int, socketpair, int, family, int, type, int, protocol, int *, sockvec)
  488. #elif defined(__NR_socketcall)
  489. int socketpair(int family, int type, int protocol, int sockvec[2])
  490. {
  491. unsigned long args[4];
  492. args[0] = family;
  493. args[1] = type;
  494. args[2] = protocol;
  495. args[3] = (unsigned long) sockvec;
  496. return __socketcall(SYS_SOCKETPAIR, args);
  497. }
  498. #endif
  499. #endif