1 |
/* Socket-specific operations |
/* Socket-specific operations |
2 |
|
|
3 |
Copyright (C) 1995 Free Software Foundation, Inc. |
Copyright (C) 1995, 2005 Free Software Foundation, Inc. |
4 |
|
|
5 |
Written by Miles Bader <miles@gnu.ai.mit.edu> |
Written by Miles Bader <miles@gnu.ai.mit.edu> |
6 |
|
|
110 |
else if (sock->flags & SOCK_CONNECTED) |
else if (sock->flags & SOCK_CONNECTED) |
111 |
/* SOCK_CONNECTED is only set for connection-oriented sockets, |
/* SOCK_CONNECTED is only set for connection-oriented sockets, |
112 |
which can only ever connect once. [If we didn't do this test |
which can only ever connect once. [If we didn't do this test |
113 |
here, it would eventually fail when it the listening socket |
here, it would eventually fail when the listening socket |
114 |
tried to accept our connection request.] */ |
tried to accept our connection request.] */ |
115 |
err = EISCONN; |
err = EISCONN; |
116 |
else |
else |
118 |
/* Assert that we're trying to connect, so anyone else trying |
/* Assert that we're trying to connect, so anyone else trying |
119 |
to do so will fail with EALREADY. */ |
to do so will fail with EALREADY. */ |
120 |
sock->connect_queue = cq; |
sock->connect_queue = cq; |
121 |
mutex_unlock (&sock->lock); /* Unlock SOCK while waiting. */ |
/* Unlock SOCK while waiting. */ |
122 |
|
mutex_unlock (&sock->lock); |
123 |
|
|
124 |
/* Try to connect. */ |
err = connq_connect (peer->listen_queue, |
125 |
err = connq_connect (cq, sock->flags & SOCK_NONBLOCK, sock); |
sock->flags & SOCK_NONBLOCK); |
126 |
|
if (!err) |
127 |
|
{ |
128 |
|
struct sock *server; |
129 |
|
|
130 |
|
err = sock_clone (peer, &server); |
131 |
|
if (!err) |
132 |
|
{ |
133 |
|
err = sock_connect (sock, server); |
134 |
|
if (!err) |
135 |
|
connq_connect_complete (peer->listen_queue, server); |
136 |
|
else |
137 |
|
sock_free (server); |
138 |
|
} |
139 |
|
|
140 |
|
mutex_lock (&sock->lock); |
141 |
|
if (err) |
142 |
|
connq_connect_cancel (peer->listen_queue); |
143 |
|
} |
144 |
|
|
145 |
/* We can safely set CONNECT_QUEUE to NULL, as no one else can |
/* We must set CONNECT_QUEUE to NULL, as no one else can |
146 |
set it until we've done so. */ |
set it until we've done so. */ |
|
mutex_lock (&sock->lock); |
|
147 |
sock->connect_queue = NULL; |
sock->connect_queue = NULL; |
148 |
} |
} |
149 |
|
|
150 |
mutex_unlock (&sock->lock); |
mutex_unlock (&sock->lock); |
151 |
} |
} |
152 |
else |
else |
176 |
err = ensure_connq (sock); |
err = ensure_connq (sock); |
177 |
if (!err) |
if (!err) |
178 |
{ |
{ |
|
struct connq_request *req; |
|
179 |
struct sock *peer_sock; |
struct sock *peer_sock; |
180 |
|
|
181 |
err = |
err = connq_listen (sock->listen_queue, sock->flags & SOCK_NONBLOCK, |
182 |
connq_listen (sock->listen_queue, sock->flags & SOCK_NONBLOCK, |
&peer_sock); |
|
&req, &peer_sock); |
|
183 |
if (!err) |
if (!err) |
184 |
{ |
{ |
185 |
struct sock *conn_sock; |
struct addr *peer_addr; |
186 |
|
*port_type = MACH_MSG_TYPE_MAKE_SEND; |
187 |
err = sock_clone (sock, &conn_sock); |
err = sock_create_port (peer_sock, port); |
188 |
|
if (!err) |
189 |
|
err = sock_get_addr (peer_sock, &peer_addr); |
190 |
if (!err) |
if (!err) |
191 |
{ |
{ |
192 |
err = sock_connect (conn_sock, peer_sock); |
*peer_addr_port = ports_get_right (peer_addr); |
193 |
if (!err) |
*peer_addr_port_type = MACH_MSG_TYPE_MAKE_SEND; |
194 |
{ |
ports_port_deref (peer_addr); |
|
struct addr *peer_addr; |
|
|
*port_type = MACH_MSG_TYPE_MAKE_SEND; |
|
|
err = sock_create_port (conn_sock, port); |
|
|
if (!err) |
|
|
err = sock_get_addr (peer_sock, &peer_addr); |
|
|
if (!err) |
|
|
{ |
|
|
*peer_addr_port = ports_get_right (peer_addr); |
|
|
*peer_addr_port_type = MACH_MSG_TYPE_MAKE_SEND; |
|
|
ports_port_deref (peer_addr); |
|
|
} |
|
|
else |
|
|
/* TEAR DOWN THE CONNECTION XXX */; |
|
|
} |
|
|
if (err) |
|
|
sock_free (conn_sock); |
|
195 |
} |
} |
196 |
|
else |
197 |
/* Communicate any error (or success) to the connecting thread. */ |
/* TEAR DOWN THE CONNECTION XXX */; |
|
connq_request_complete (req, err); |
|
198 |
} |
} |
199 |
} |
} |
200 |
|
|