1 /* transport_sockets.cc
3 Copyright 2001, 2002, 2003, 2004 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 "transport.h"
30 #include "transport_sockets.h"
32 #ifdef __INSIDE_CYGWIN__
33 #define SET_ERRNO(err) set_errno (err)
34 #define GET_ERRNO() get_errno ()
36 #define SET_ERRNO(err) errno = (err)
37 #define GET_ERRNO() (errno)
40 /* to allow this to link into cygwin and the .dll, a little magic is needed. */
41 #ifndef __OUTSIDE_CYGWIN__
43 extern "C" int cygwin_accept (int fd
, struct sockaddr
*, int *len
);
44 extern "C" int cygwin_bind (int fd
, const struct sockaddr
*, int len
);
45 extern "C" int cygwin_connect (int fd
, const struct sockaddr
*, int len
);
46 extern "C" int cygwin_listen (int fd
, int backlog
);
47 extern "C" int cygwin_shutdown (int fd
, int how
);
48 extern "C" int cygwin_socket (int af
, int type
, int protocol
);
50 #else /* __OUTSIDE_CYGWIN__ */
52 #define cygwin_accept(A,B,C) ::accept (A,B,C)
53 #define cygwin_bind(A,B,C) ::bind (A,B,C)
54 #define cygwin_connect(A,B,C) ::connect (A,B,C)
55 #define cygwin_listen(A,B) ::listen (A,B)
56 #define cygwin_shutdown(A,B) ::shutdown (A,B)
57 #define cygwin_socket(A,B,C) ::socket (A,B,C)
59 #endif /* __OUTSIDE_CYGWIN__ */
63 MAX_CONNECT_RETRY
= 64
66 transport_layer_sockets::transport_layer_sockets (const int fd
)
69 _is_accepted_endpoint (true),
70 _is_listening_endpoint (false)
74 memset (&_addr
, '\0', sizeof (_addr
));
77 transport_layer_sockets::transport_layer_sockets ()
80 _is_accepted_endpoint (false),
81 _is_listening_endpoint (false)
83 memset (&_addr
, '\0', sizeof (_addr
));
85 _addr
.sun_family
= AF_UNIX
;
86 strcpy (_addr
.sun_path
, "/tmp/cygdaemo"); // FIXME: $TMP?
87 _addr_len
= SUN_LEN (&_addr
);
90 transport_layer_sockets::~transport_layer_sockets ()
95 #ifndef __INSIDE_CYGWIN__
98 transport_layer_sockets::listen ()
101 assert (!_is_accepted_endpoint
);
102 assert (!_is_listening_endpoint
);
104 debug_printf ("listen () [this = %p]", this);
108 if (stat (_addr
.sun_path
, &sbuf
) == -1)
110 if (GET_ERRNO () != ENOENT
)
112 system_printf ("cannot access socket file `%s': %s",
113 _addr
.sun_path
, strerror (GET_ERRNO ()));
117 else if (S_ISSOCK (sbuf
.st_mode
))
119 // The socket already exists: is a duplicate cygserver running?
121 const int newfd
= cygwin_socket (AF_UNIX
, SOCK_STREAM
, 0);
125 system_printf ("failed to create UNIX domain socket: %s",
126 strerror (GET_ERRNO ()));
130 if (cygwin_connect (newfd
, (struct sockaddr
*) &_addr
, _addr_len
) == 0)
132 system_printf ("the daemon is already running");
133 (void) cygwin_shutdown (newfd
, SHUT_WR
);
135 while (::read (newfd
, buf
, sizeof (buf
)) > 0)
137 (void) ::close (newfd
);
141 if (unlink (_addr
.sun_path
) == -1)
143 system_printf ("failed to remove `%s': %s",
144 _addr
.sun_path
, strerror (GET_ERRNO ()));
145 (void) ::close (newfd
);
151 system_printf ("cannot create socket `%s': File already exists",
156 _fd
= cygwin_socket (AF_UNIX
, SOCK_STREAM
, 0);
160 system_printf ("failed to create UNIX domain socket: %s",
161 strerror (GET_ERRNO ()));
165 if (cygwin_bind (_fd
, (struct sockaddr
*) &_addr
, _addr_len
) == -1)
167 const int saved_errno
= GET_ERRNO ();
169 SET_ERRNO (saved_errno
);
170 system_printf ("failed to bind UNIX domain socket `%s': %s",
171 _addr
.sun_path
, strerror (GET_ERRNO ()));
175 _is_listening_endpoint
= true; // i.e. this really means "have bound".
177 if (cygwin_listen (_fd
, SOMAXCONN
) == -1)
179 const int saved_errno
= GET_ERRNO ();
181 SET_ERRNO (saved_errno
);
182 system_printf ("failed to listen on UNIX domain socket `%s': %s",
183 _addr
.sun_path
, strerror (GET_ERRNO ()));
187 debug_printf ("0 = listen () [this = %p, fd = %d]", this, _fd
);
192 class transport_layer_sockets
*
193 transport_layer_sockets::accept (bool *const recoverable
)
196 assert (!_is_accepted_endpoint
);
197 assert (_is_listening_endpoint
);
199 debug_printf ("accept () [this = %p, fd = %d]", this, _fd
);
201 struct sockaddr_un client_addr
;
202 socklen_t client_addr_len
= sizeof (client_addr
);
204 const int accept_fd
=
205 cygwin_accept (_fd
, (struct sockaddr
*) &client_addr
, &client_addr_len
);
209 system_printf ("failed to accept connection: %s", strerror (GET_ERRNO ()));
210 switch (GET_ERRNO ())
222 *recoverable
= false;
228 debug_printf ("%d = accept () [this = %p, fd = %d]", accept_fd
, this, _fd
);
230 return new transport_layer_sockets (accept_fd
);
233 #endif /* !__INSIDE_CYGWIN__ */
236 transport_layer_sockets::close ()
238 debug_printf ("close () [this = %p, fd = %d]", this, _fd
);
240 if (_is_listening_endpoint
)
241 (void) unlink (_addr
.sun_path
);
245 (void) cygwin_shutdown (_fd
, SHUT_WR
);
246 if (!_is_listening_endpoint
)
249 while (::read (_fd
, buf
, sizeof (buf
)) > 0)
252 (void) ::close (_fd
);
256 _is_listening_endpoint
= false;
260 transport_layer_sockets::read (void *const buf
, const size_t buf_len
)
263 assert (!_is_listening_endpoint
);
266 assert (buf_len
> 0);
268 // verbose: debug_printf ("read (buf = %p, len = %u) [this = %p, fd = %d]",
269 // buf, buf_len, this, _fd);
271 char *read_buf
= static_cast<char *> (buf
);
272 size_t read_buf_len
= buf_len
;
275 while (read_buf_len
!= 0
276 && (res
= ::read (_fd
, read_buf
, read_buf_len
)) > 0)
281 assert (read_buf_len
>= 0);
287 SET_ERRNO (EIO
); // FIXME?
289 res
= buf_len
- read_buf_len
;
292 if (res
!= static_cast<ssize_t
> (buf_len
))
293 debug_printf ("%d = read (buf = %p, len = %u) [this = %p, fd = %d]: %s",
294 res
, buf
, buf_len
, this, _fd
,
295 (res
== -1 ? strerror (GET_ERRNO ()) : "EOF"));
298 // verbose: debug_printf ("%d = read (buf = %p, len = %u) [this = %p, fd = %d]",
299 // res, buf, buf_len, this, _fd);
306 transport_layer_sockets::write (void *const buf
, const size_t buf_len
)
309 assert (!_is_listening_endpoint
);
312 assert (buf_len
> 0);
314 // verbose: debug_printf ("write (buf = %p, len = %u) [this = %p, fd = %d]",
315 // buf, buf_len, this, _fd);
317 char *write_buf
= static_cast<char *> (buf
);
318 size_t write_buf_len
= buf_len
;
321 while (write_buf_len
!= 0
322 && (res
= ::write (_fd
, write_buf
, write_buf_len
)) > 0)
325 write_buf_len
-= res
;
327 assert (write_buf_len
>= 0);
333 SET_ERRNO (EIO
); // FIXME?
335 res
= buf_len
- write_buf_len
;
338 if (res
!= static_cast<ssize_t
> (buf_len
))
339 debug_printf ("%d = write (buf = %p, len = %u) [this = %p, fd = %d]: %s",
340 res
, buf
, buf_len
, this, _fd
,
341 (res
== -1 ? strerror (GET_ERRNO ()) : "EOF"));
344 // verbose: debug_printf ("%d = write (buf = %p, len = %u) [this = %p, fd = %d]",
345 // res, buf, buf_len, this, _fd);
352 transport_layer_sockets::connect ()
355 assert (!_is_accepted_endpoint
);
356 assert (!_is_listening_endpoint
);
358 static bool assume_cygserver
= false;
360 debug_printf ("connect () [this = %p]", this);
362 for (int retries
= 0; retries
!= MAX_CONNECT_RETRY
; retries
++)
364 _fd
= cygwin_socket (AF_UNIX
, SOCK_STREAM
, 0);
368 system_printf ("failed to create UNIX domain socket: %s",
369 strerror (GET_ERRNO ()));
373 if (cygwin_connect (_fd
, (struct sockaddr
*) &_addr
, _addr_len
) == 0)
375 assume_cygserver
= true;
376 debug_printf ("0 = connect () [this = %p, fd = %d]", this, _fd
);
380 if (!assume_cygserver
|| GET_ERRNO () != ECONNREFUSED
)
382 debug_printf ("failed to connect to server: %s", strerror (GET_ERRNO ()));
383 (void) ::close (_fd
);
388 (void) ::close (_fd
);
390 Sleep (0); // Give the server a chance.
393 debug_printf ("failed to connect to server: %s", strerror (GET_ERRNO ()));