source: trunk/ORBit2-2.14.0/linc2/src/linc-compat.c

Last change on this file was 92, checked in by cinc, 19 years ago

Orbit2 modified for use with NOM

File size: 5.2 KB
Line 
1/*
2 * linc-compat.c: This file is part of the linc library.
3 *
4 * Authors:
5 * Tor Lillqvist (tml@novell.com)
6 *
7 * Copyright 2005, Novell, Inc.
8 */
9#include "config.h"
10
11#include <linc/linc.h>
12
13#include "linc-compat.h"
14#include "linc-debug.h"
15
16#ifdef G_OS_WIN32
17
18/* Map some WinSock error codes to errno values. Only those that
19 * correspond to real errno values that the linc2 source code checks
20 * for are mapped. They should obviously not include those errno
21 * values that don't exist in the Microsoft C library, and which are
22 * defined as the corresponding WSAE* value in linc-compat.h
23 */
24void
25link_map_winsock_error_to_errno (void)
26{
27 errno = WSAGetLastError ();
28 d_printf ("WSAGetLastError: %d\n", errno);
29 switch (errno) {
30 case WSAEBADF:
31 errno = EBADF; break;
32 case WSAEWOULDBLOCK:
33 errno = EAGAIN; break;
34 }
35}
36
37#endif
38
39int
40link_pipe (int *handles)
41{
42#ifndef G_OS_WIN32
43
44 return pipe (handles);
45
46#else
47
48 SOCKET temp, socket1 = -1, socket2 = -1;
49 struct sockaddr_in saddr;
50 int len;
51 u_long arg;
52 fd_set read_set, write_set;
53 struct timeval tv;
54
55 temp = socket (AF_INET, SOCK_STREAM, 0);
56 if (temp == INVALID_SOCKET)
57 {
58 link_map_winsock_error_to_errno ();
59 goto out0;
60 }
61
62 arg = 1;
63 if (ioctlsocket (temp, FIONBIO, &arg) == SOCKET_ERROR)
64 {
65 link_map_winsock_error_to_errno ();
66 goto out0;
67 }
68
69 memset (&saddr, 0, sizeof (saddr));
70 saddr.sin_family = AF_INET;
71 saddr.sin_port = 0;
72 saddr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
73
74 if (bind (temp, (struct sockaddr *)&saddr, sizeof (saddr)))
75 {
76 link_map_winsock_error_to_errno ();
77 goto out0;
78 }
79
80 if (listen (temp, 1) == SOCKET_ERROR)
81 {
82 link_map_winsock_error_to_errno ();
83 goto out0;
84 }
85
86 len = sizeof (saddr);
87 if (getsockname (temp, (struct sockaddr *)&saddr, &len))
88 {
89 link_map_winsock_error_to_errno ();
90 goto out0;
91 }
92
93 socket1 = socket (AF_INET, SOCK_STREAM, 0);
94 if (socket1 == INVALID_SOCKET)
95 {
96 link_map_winsock_error_to_errno ();
97 goto out0;
98 }
99
100 arg = 1;
101 if (ioctlsocket (socket1, FIONBIO, &arg) == SOCKET_ERROR)
102 {
103 link_map_winsock_error_to_errno ();
104 goto out1;
105 }
106
107 if (connect (socket1, (struct sockaddr *)&saddr, len) != SOCKET_ERROR ||
108 WSAGetLastError () != WSAEWOULDBLOCK)
109 {
110 link_map_winsock_error_to_errno ();
111 goto out1;
112 }
113
114 FD_ZERO (&read_set);
115 FD_SET (temp, &read_set);
116
117 tv.tv_sec = 0;
118 tv.tv_usec = 0;
119
120 if (select (0, &read_set, NULL, NULL, NULL) == SOCKET_ERROR)
121 {
122 link_map_winsock_error_to_errno ();
123 goto out1;
124 }
125
126 if (!FD_ISSET (temp, &read_set))
127 {
128 errno = WSAECONNREFUSED; /* Oh well, whatever */
129 goto out1;
130 }
131
132 socket2 = accept (temp, (struct sockaddr *) &saddr, &len);
133 if (socket2 == INVALID_SOCKET)
134 {
135 link_map_winsock_error_to_errno ();
136 goto out1;
137 }
138
139 FD_ZERO (&write_set);
140 FD_SET (socket1, &write_set);
141
142 tv.tv_sec = 0;
143 tv.tv_usec = 0;
144
145 if (select (0, NULL, &write_set, NULL, NULL) == SOCKET_ERROR)
146 {
147 link_map_winsock_error_to_errno ();
148 goto out2;
149 }
150
151 if (!FD_ISSET (socket1, &write_set))
152 {
153 errno = WSAECONNREFUSED;
154 goto out2;
155 }
156
157 arg = 0;
158 if (ioctlsocket (socket1, FIONBIO, &arg) == SOCKET_ERROR)
159 {
160 link_map_winsock_error_to_errno ();
161 goto out2;
162 }
163
164 arg = 0;
165 if (ioctlsocket (socket2, FIONBIO, &arg) == SOCKET_ERROR)
166 {
167 link_map_winsock_error_to_errno ();
168 goto out2;
169 }
170
171 handles[0] = socket1;
172 handles[1] = socket2;
173
174 d_printf ("socketpair %d <-> %d\n", socket1, socket2);
175
176 closesocket (temp);
177
178 return 0;
179
180 out2:
181 closesocket (socket2);
182 out1:
183 closesocket (socket1);
184 out0:
185 closesocket (temp);
186
187 return -1;
188
189#endif
190}
191
192const char *
193link_strerror (int number)
194{
195 switch (number) {
196#ifdef HAVE_WINSOCK2_H
197 case WSAEOPNOTSUPP:
198 return "Operation not supported on transport endpoint";
199 case WSAEPFNOSUPPORT:
200 return "Protocol family not supported";
201 case WSAECONNRESET:
202 return "Connection reset by peer";
203 case WSAENOBUFS:
204 return "No buffer space available";
205 case WSAEAFNOSUPPORT:
206 return "Address family not supported by protocol family";
207 case WSAENOTSOCK:
208 return "Socket operation on non-socket";
209 case WSAENOPROTOOPT:
210 return "Protocol not available";
211 case WSAESHUTDOWN:
212 return "Can't send after socket shutdown";
213 case WSAECONNREFUSED:
214 return "Connection refused";
215 case WSAEADDRINUSE:
216 return "Address already in use";
217 case WSAECONNABORTED:
218 return "Connection aborted";
219 case WSAENETUNREACH:
220 return "Network is unreachable";
221 case WSAENETDOWN:
222 return "Network interface is not configured";
223 case WSAETIMEDOUT:
224 return "Connection timed out";
225 case WSAEHOSTDOWN:
226 return "Host is down";
227 case WSAEHOSTUNREACH:
228 return "Host is unreachable";
229 case WSAEINPROGRESS:
230 return "Connection already in progress";
231 case WSAEALREADY:
232 return "Socket already connected";
233 case WSAEPROTONOSUPPORT:
234 return "Unknown protocol";
235 case WSAESOCKTNOSUPPORT:
236 return "Socket type not supported";
237 case WSAEADDRNOTAVAIL:
238 return "Address not available";
239 case WSAEISCONN:
240 return "Socket is already connected";
241 case WSAENOTCONN:
242 return "Socket is not connected";
243#endif
244 default:
245 return g_strerror (number);
246 }
247}
Note: See TracBrowser for help on using the repository browser.