1 /* cygserver_transport_sockets.cc
3 Copyright 2001, 2002 Red Hat Inc.
5 Written by Robert Collins <rbtcollins@hotmail.com>
7 This file is part of Cygwin.
9 This software is a copyrighted work licensed under the terms of the
10 Cygwin license. Please consult the file "CYGWIN_LICENSE" for
13 /* to allow this to link into cygwin and the .dll, a little magic is needed. */
14 #ifdef __OUTSIDE_CYGWIN__
20 #include <sys/types.h>
21 #include <sys/socket.h>
29 #include "cygserver_transport.h"
30 #include "cygserver_transport_sockets.h"
32 /* to allow this to link into cygwin and the .dll, a little magic is needed. */
33 #ifndef __OUTSIDE_CYGWIN__
35 extern "C" int cygwin_accept (int fd, struct sockaddr *, int *len);
36 extern "C" int cygwin_bind (int fd, const struct sockaddr *, int len);
37 extern "C" int cygwin_connect (int fd, const struct sockaddr *, int len);
38 extern "C" int cygwin_listen (int fd, int backlog);
39 extern "C" int cygwin_shutdown (int fd, int how);
40 extern "C" int cygwin_socket (int af, int type, int protocol);
42 #else /* __OUTSIDE_CYGWIN__ */
44 #define cygwin_accept(A,B,C) ::accept (A,B,C)
45 #define cygwin_bind(A,B,C) ::bind (A,B,C)
46 #define cygwin_connect(A,B,C) ::connect (A,B,C)
47 #define cygwin_listen(A,B) ::listen (A,B)
48 #define cygwin_shutdown(A,B) ::shutdown (A,B)
49 #define cygwin_socket(A,B,C) ::socket (A,B,C)
51 #endif /* __OUTSIDE_CYGWIN__ */
55 MAX_CONNECT_RETRY = 64
58 transport_layer_sockets::transport_layer_sockets (const int fd)
61 _is_accepted_endpoint (true),
62 _is_listening_endpoint (false)
66 memset (&_addr, '\0', sizeof (_addr));
69 transport_layer_sockets::transport_layer_sockets ()
72 _is_accepted_endpoint (false),
73 _is_listening_endpoint (false)
75 memset (&_addr, '\0', sizeof (_addr));
77 _addr.sun_family = AF_UNIX;
78 strcpy (_addr.sun_path, "/tmp/cygdaemo"); // FIXME: $TMP?
79 _addr_len = SUN_LEN (&_addr);
82 transport_layer_sockets::~transport_layer_sockets ()
87 #ifndef __INSIDE_CYGWIN__
90 transport_layer_sockets::listen ()
93 assert (!_is_accepted_endpoint);
94 assert (!_is_listening_endpoint);
96 debug_printf ("listen () [this = %p]", this);
100 if (stat (_addr.sun_path, &sbuf) == -1)
104 system_printf ("cannot access socket file `%s': %s",
105 _addr.sun_path, strerror (errno));
109 else if (S_ISSOCK (sbuf.st_mode))
111 // The socket already exists: is a duplicate cygserver running?
113 const int newfd = cygwin_socket (AF_UNIX, SOCK_STREAM, 0);
117 system_printf ("failed to create UNIX domain socket: %s",
122 if (cygwin_connect (newfd, (struct sockaddr *) &_addr, _addr_len) == 0)
124 system_printf ("the daemon is already running");
125 (void) cygwin_shutdown (newfd, SHUT_WR);
127 while (::read (newfd, buf, sizeof (buf)) > 0)
129 (void) ::close (newfd);
133 if (unlink (_addr.sun_path) == -1)
135 system_printf ("failed to remove `%s': %s",
136 _addr.sun_path, strerror (errno));
137 (void) ::close (newfd);
143 system_printf ("cannot create socket `%s': File already exists",
148 _fd = cygwin_socket (AF_UNIX, SOCK_STREAM, 0);
152 system_printf ("failed to create UNIX domain socket: %s",
157 if (cygwin_bind (_fd, (struct sockaddr *) &_addr, _addr_len) == -1)
159 const int saved_errno = errno;
162 system_printf ("failed to bind UNIX domain socket `%s': %s",
163 _addr.sun_path, strerror (errno));
167 _is_listening_endpoint = true; // i.e. this really means "have bound".
169 if (cygwin_listen (_fd, SOMAXCONN) == -1)
171 const int saved_errno = errno;
174 system_printf ("failed to listen on UNIX domain socket `%s': %s",
175 _addr.sun_path, strerror (errno));
179 debug_printf ("0 = listen () [this = %p, fd = %d]", this, _fd);
184 class transport_layer_sockets *
185 transport_layer_sockets::accept (bool *const recoverable)
188 assert (!_is_accepted_endpoint);
189 assert (_is_listening_endpoint);
191 debug_printf ("accept () [this = %p, fd = %d]", this, _fd);
193 struct sockaddr_un client_addr;
194 socklen_t client_addr_len = sizeof (client_addr);
196 const int accept_fd =
197 cygwin_accept (_fd, (struct sockaddr *) &client_addr, &client_addr_len);
201 system_printf ("failed to accept connection: %s", strerror (errno));
214 *recoverable = false;
220 debug_printf ("%d = accept () [this = %p, fd = %d]", accept_fd, this, _fd);
222 return safe_new (transport_layer_sockets, accept_fd);
225 #endif /* !__INSIDE_CYGWIN__ */
228 transport_layer_sockets::close ()
230 debug_printf ("close () [this = %p, fd = %d]", this, _fd);
232 if (_is_listening_endpoint)
233 (void) unlink (_addr.sun_path);
237 (void) cygwin_shutdown (_fd, SHUT_WR);
238 if (!_is_listening_endpoint)
241 while (::read (_fd, buf, sizeof (buf)) > 0)
244 (void) ::close (_fd);
248 _is_listening_endpoint = false;
252 transport_layer_sockets::read (void *const buf, const size_t buf_len)
255 assert (!_is_listening_endpoint);
258 assert (buf_len > 0);
260 // verbose: debug_printf ("read (buf = %p, len = %u) [this = %p, fd = %d]",
261 // buf, buf_len, this, _fd);
263 char *read_buf = static_cast<char *> (buf);
264 size_t read_buf_len = buf_len;
267 while (read_buf_len != 0
268 && (res = ::read (_fd, read_buf, read_buf_len)) > 0)
273 assert (read_buf_len >= 0);
279 errno = EIO; // FIXME?
281 res = buf_len - read_buf_len;
284 if (res != static_cast<ssize_t> (buf_len))
285 debug_printf ("%d = read (buf = %p, len = %u) [this = %p, fd = %d]: %s",
286 res, buf, buf_len, this, _fd,
287 (res == -1 ? strerror (errno) : "EOF"));
290 // verbose: debug_printf ("%d = read (buf = %p, len = %u) [this = %p, fd = %d]",
291 // res, buf, buf_len, this, _fd);
298 transport_layer_sockets::write (void *const buf, const size_t buf_len)
301 assert (!_is_listening_endpoint);
304 assert (buf_len > 0);
306 // verbose: debug_printf ("write (buf = %p, len = %u) [this = %p, fd = %d]",
307 // buf, buf_len, this, _fd);
309 char *write_buf = static_cast<char *> (buf);
310 size_t write_buf_len = buf_len;
313 while (write_buf_len != 0
314 && (res = ::write (_fd, write_buf, write_buf_len)) > 0)
317 write_buf_len -= res;
319 assert (write_buf_len >= 0);
325 errno = EIO; // FIXME?
327 res = buf_len - write_buf_len;
330 if (res != static_cast<ssize_t> (buf_len))
331 debug_printf ("%d = write (buf = %p, len = %u) [this = %p, fd = %d]: %s",
332 res, buf, buf_len, this, _fd,
333 (res == -1 ? strerror (errno) : "EOF"));
336 // verbose: debug_printf ("%d = write (buf = %p, len = %u) [this = %p, fd = %d]",
337 // res, buf, buf_len, this, _fd);
344 transport_layer_sockets::connect ()
347 assert (!_is_accepted_endpoint);
348 assert (!_is_listening_endpoint);
350 static bool assume_cygserver = false;
352 debug_printf ("connect () [this = %p]", this);
354 for (int retries = 0; retries != MAX_CONNECT_RETRY; retries++)
356 _fd = cygwin_socket (AF_UNIX, SOCK_STREAM, 0);
360 system_printf ("failed to create UNIX domain socket: %s",
365 if (cygwin_connect (_fd, (struct sockaddr *) &_addr, _addr_len) == 0)
367 assume_cygserver = true;
368 debug_printf ("0 = connect () [this = %p, fd = %d]", this, _fd);
372 if (!assume_cygserver || errno != ECONNREFUSED)
374 debug_printf ("failed to connect to server: %s", strerror (errno));
375 (void) ::close (_fd);
380 (void) ::close (_fd);
382 Sleep (0); // Give the server a chance.
385 debug_printf ("failed to connect to server: %s", strerror (errno));