Use weak __thread declarations in parlib-compat (XCC)
[akaros.git] / tools / compilers / gcc-glibc / glibc-2.19-akaros / sysdeps / akaros / socket.c
1 /* 
2  * This file is part of the UCB release of Plan 9. It is subject to the license
3  * terms in the LICENSE file found in the top-level directory of this
4  * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
5  * part of the UCB release of Plan 9, including this file, may be copied,
6  * modified, propagated, or distributed except according to the terms contained
7  * in the LICENSE file.
8  */
9 /* posix */
10 #include <sys/types.h>
11 #include <unistd.h>
12 #include <stdlib.h>
13 #include <stdio.h>
14 #include <errno.h>
15 #include <string.h>
16 #include <fcntl.h>
17 #include <sys/stat.h>
18 #include <sys/close_cb.h>
19 #include <ros/common.h>
20 #include <parlib/parlib.h>
21
22 /* bsd extensions */
23 #include <sys/uio.h>
24 #include <sys/socket.h>
25 #include <netinet/in.h>
26
27 #include <sys/plan9_helpers.h>
28
29 static void socket_init(void *arg)
30 {
31         static struct close_cb _sock_close_cb = {.func = _sock_fd_closed};
32
33         register_close_cb(&_sock_close_cb);
34 }
35
36 /* Create a new socket of type TYPE in domain DOMAIN, using
37    protocol PROTOCOL.  If PROTOCOL is zero, one is chosen automatically.
38    Returns a file descriptor for the new socket, or -1 for errors.  */
39 int __socket(int domain, int type, int protocol)
40 {
41         Rock *r;
42         int cfd, n;
43         int pfd[2];
44         const char *net;
45         char msg[128];
46         int open_flags;
47         static parlib_once_t once = PARLIB_ONCE_INIT;
48
49         parlib_run_once(&once, socket_init, NULL);
50
51         switch (domain) {
52                 case PF_INET:
53                         open_flags = O_RDWR;
54                         open_flags |= (type & SOCK_CLOEXEC ? O_CLOEXEC : 0);
55                         /* get a free network directory */
56                         switch (_sock_strip_opts(type)) {
57                                 case SOCK_DGRAM:
58                                         net = "udp";
59                                         cfd = open("/net/udp/clone", open_flags);
60                                         /* All BSD UDP sockets are in 'headers' mode, where each
61                                          * packet has the remote addr:port, local addr:port and
62                                          * other info. */
63                                         if (!(cfd < 0)) {
64                                                 n = snprintf(msg, sizeof(msg), "headers");
65                                                 n = write(cfd, msg, n);
66                                                 if (n < 0) {
67                                                         perror("UDP socket headers failed");
68                                                         return -1;
69                                                 }
70                                                 if (lseek(cfd, 0, SEEK_SET) != 0) {
71                                                         perror("UDP socket seek failed");
72                                                         return -1;
73                                                 }
74                                         }
75                                         break;
76                                 case SOCK_STREAM:
77                                         net = "tcp";
78                                         cfd = open("/net/tcp/clone", open_flags);
79                                         break;
80                                 default:
81                                         errno = EPROTONOSUPPORT;
82                                         return -1;
83                         }
84                         if (cfd < 0) {
85                                 return -1;
86                         }
87                         return _sock_data(cfd, net, domain, type, protocol, 0);
88                 case PF_UNIX:
89                         open_flags = 0;
90                         open_flags |= (type & SOCK_CLOEXEC ? O_CLOEXEC : 0);
91                         open_flags |= (type & SOCK_NONBLOCK ? O_CLOEXEC : 0);
92                         if (pipe2(pfd, open_flags) < 0)
93                                 return -1;
94                         r = _sock_newrock(pfd[0]);
95                         r->domain = domain;
96                         r->stype = _sock_strip_opts(type);
97                         r->sopts = _sock_get_opts(type);
98                         r->protocol = protocol;
99                         r->other = pfd[1];
100                         return pfd[0];
101                 default:
102                         errno = EPROTONOSUPPORT;
103                         return -1;
104         }
105 }
106
107 weak_alias(__socket, socket)