]>
Commit | Line | Data |
---|---|---|
6cbd1b6f RK |
1 | ------------------------------------------------------------------------------ |
2 | -- -- | |
3 | -- GNAT COMPILER COMPONENTS -- | |
4 | -- -- | |
5 | -- G N A T . S O C K E T S . T H I N -- | |
6 | -- -- | |
7 | -- S p e c -- | |
8 | -- -- | |
4491f0ae | 9 | -- Copyright (C) 2001-2007, AdaCore -- |
6cbd1b6f RK |
10 | -- -- |
11 | -- GNAT is free software; you can redistribute it and/or modify it under -- | |
12 | -- terms of the GNU General Public License as published by the Free Soft- -- | |
13 | -- ware Foundation; either version 2, or (at your option) any later ver- -- | |
14 | -- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- | |
15 | -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- | |
16 | -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -- | |
17 | -- for more details. You should have received a copy of the GNU General -- | |
18 | -- Public License distributed with GNAT; see file COPYING. If not, write -- | |
cb5fee25 KC |
19 | -- to the Free Software Foundation, 51 Franklin Street, Fifth Floor, -- |
20 | -- Boston, MA 02110-1301, USA. -- | |
6cbd1b6f RK |
21 | -- -- |
22 | -- As a special exception, if other files instantiate generics from this -- | |
23 | -- unit, or you link this unit with other files to produce an executable, -- | |
24 | -- this unit does not by itself cause the resulting executable to be -- | |
25 | -- covered by the GNU General Public License. This exception does not -- | |
26 | -- however invalidate any other reasons why the executable file might be -- | |
27 | -- covered by the GNU Public License. -- | |
28 | -- -- | |
fbf5a39b AC |
29 | -- GNAT was originally developed by the GNAT team at New York University. -- |
30 | -- Extensive contributions were provided by Ada Core Technologies Inc. -- | |
6cbd1b6f RK |
31 | -- -- |
32 | ------------------------------------------------------------------------------ | |
33 | ||
fbf5a39b AC |
34 | -- This package provides a target dependent thin interface to the sockets |
35 | -- layer for use by the GNAT.Sockets package (g-socket.ads). This package | |
36 | -- should not be directly with'ed by an applications program. | |
37 | ||
38 | -- This version is for NT | |
6cbd1b6f RK |
39 | |
40 | with Interfaces.C.Pointers; | |
41 | with Interfaces.C.Strings; | |
42 | ||
43 | with GNAT.Sockets.Constants; | |
44 | ||
45 | with System; | |
46 | ||
47 | package GNAT.Sockets.Thin is | |
48 | ||
6cbd1b6f RK |
49 | package C renames Interfaces.C; |
50 | ||
51 | use type C.int; | |
a2cb348e | 52 | -- So that we can declare the Failure constant below |
6cbd1b6f RK |
53 | |
54 | Success : constant C.int := 0; | |
55 | Failure : constant C.int := -1; | |
56 | ||
57 | function Socket_Errno return Integer; | |
a2cb348e | 58 | -- Returns last socket error number |
6cbd1b6f | 59 | |
fbf5a39b | 60 | procedure Set_Socket_Errno (Errno : Integer); |
a2cb348e | 61 | -- Set last socket error number |
fbf5a39b | 62 | |
3d3bf932 TQ |
63 | function Socket_Error_Message (Errno : Integer) return C.Strings.chars_ptr; |
64 | -- Returns the error message string for the error number Errno. If Errno is | |
4491f0ae | 65 | -- not known, returns "Unknown system error". |
6cbd1b6f | 66 | |
3e1fd98f TQ |
67 | function Host_Errno return Integer; |
68 | pragma Import (C, Host_Errno, "__gnat_get_h_errno"); | |
69 | -- Returns last host error number | |
70 | ||
4491f0ae AC |
71 | package Host_Error_Messages is |
72 | ||
73 | function Host_Error_Message | |
74 | (H_Errno : Integer) return C.Strings.chars_ptr; | |
75 | -- Returns the error message string for the host error number H_Errno. | |
76 | -- If H_Errno is not known, returns "Unknown system error". | |
77 | ||
78 | end Host_Error_Messages; | |
79 | ||
fbf5a39b AC |
80 | subtype Fd_Set_Access is System.Address; |
81 | No_Fd_Set : constant Fd_Set_Access := System.Null_Address; | |
6cbd1b6f | 82 | |
3e1fd98f | 83 | type time_t is |
3d3bf932 TQ |
84 | range -2 ** (8 * Constants.SIZEOF_tv_sec - 1) |
85 | .. 2 ** (8 * Constants.SIZEOF_tv_sec - 1) - 1; | |
3e1fd98f TQ |
86 | for time_t'Size use 8 * Constants.SIZEOF_tv_sec; |
87 | pragma Convention (C, time_t); | |
88 | ||
89 | type suseconds_t is | |
3d3bf932 TQ |
90 | range -2 ** (8 * Constants.SIZEOF_tv_usec - 1) |
91 | .. 2 ** (8 * Constants.SIZEOF_tv_usec - 1) - 1; | |
3e1fd98f TQ |
92 | for suseconds_t'Size use 8 * Constants.SIZEOF_tv_usec; |
93 | pragma Convention (C, suseconds_t); | |
6cbd1b6f RK |
94 | |
95 | type Timeval is record | |
3e1fd98f TQ |
96 | Tv_Sec : time_t; |
97 | Tv_Usec : suseconds_t; | |
6cbd1b6f RK |
98 | end record; |
99 | pragma Convention (C, Timeval); | |
100 | ||
101 | type Timeval_Access is access all Timeval; | |
102 | pragma Convention (C, Timeval_Access); | |
103 | ||
104 | Immediat : constant Timeval := (0, 0); | |
105 | ||
106 | type Int_Access is access all C.int; | |
107 | pragma Convention (C, Int_Access); | |
108 | -- Access to C integers | |
109 | ||
110 | type Chars_Ptr_Array is array (C.size_t range <>) of | |
111 | aliased C.Strings.chars_ptr; | |
112 | ||
113 | package Chars_Ptr_Pointers is | |
114 | new C.Pointers (C.size_t, C.Strings.chars_ptr, Chars_Ptr_Array, | |
3d3bf932 | 115 | C.Strings.Null_Ptr); |
6cbd1b6f RK |
116 | -- Arrays of C (char *) |
117 | ||
118 | type In_Addr is record | |
119 | S_B1, S_B2, S_B3, S_B4 : C.unsigned_char; | |
120 | end record; | |
4491f0ae | 121 | for In_Addr'Alignment use C.int'Alignment; |
6cbd1b6f | 122 | pragma Convention (C, In_Addr); |
4491f0ae AC |
123 | -- IPv4 address, represented as a network-order C.int. Note that the |
124 | -- underlying operating system may assume that values of this type have | |
125 | -- C.int alignment, so we need to provide a suitable alignment clause here. | |
6cbd1b6f RK |
126 | |
127 | type In_Addr_Access is access all In_Addr; | |
128 | pragma Convention (C, In_Addr_Access); | |
129 | -- Access to internet address | |
130 | ||
131 | Inaddr_Any : aliased constant In_Addr := (others => 0); | |
132 | -- Any internet address (all the interfaces) | |
133 | ||
134 | type In_Addr_Access_Array is array (C.size_t range <>) | |
135 | of aliased In_Addr_Access; | |
136 | pragma Convention (C, In_Addr_Access_Array); | |
3d3bf932 | 137 | |
6cbd1b6f RK |
138 | package In_Addr_Access_Pointers is |
139 | new C.Pointers (C.size_t, In_Addr_Access, In_Addr_Access_Array, null); | |
140 | -- Array of internet addresses | |
141 | ||
142 | type Sockaddr is record | |
143 | Sa_Family : C.unsigned_short; | |
144 | Sa_Data : C.char_array (1 .. 14); | |
145 | end record; | |
146 | pragma Convention (C, Sockaddr); | |
147 | -- Socket address | |
148 | ||
149 | type Sockaddr_Access is access all Sockaddr; | |
150 | pragma Convention (C, Sockaddr_Access); | |
151 | -- Access to socket address | |
152 | ||
153 | type Sockaddr_In is record | |
154 | Sin_Family : C.unsigned_short := Constants.AF_INET; | |
155 | Sin_Port : C.unsigned_short := 0; | |
156 | Sin_Addr : In_Addr := Inaddr_Any; | |
157 | Sin_Zero : C.char_array (1 .. 8) := (others => C.char'Val (0)); | |
158 | end record; | |
159 | pragma Convention (C, Sockaddr_In); | |
160 | -- Internet socket address | |
161 | ||
162 | type Sockaddr_In_Access is access all Sockaddr_In; | |
163 | pragma Convention (C, Sockaddr_In_Access); | |
164 | -- Access to internet socket address | |
165 | ||
fbf5a39b AC |
166 | procedure Set_Length |
167 | (Sin : Sockaddr_In_Access; | |
168 | Len : C.int); | |
169 | pragma Inline (Set_Length); | |
170 | -- Set Sin.Sin_Length to Len. | |
171 | -- On this platform, nothing is done as there is no such field. | |
172 | ||
173 | procedure Set_Family | |
174 | (Sin : Sockaddr_In_Access; | |
175 | Family : C.int); | |
176 | pragma Inline (Set_Family); | |
177 | -- Set Sin.Sin_Family to Family | |
178 | ||
179 | procedure Set_Port | |
180 | (Sin : Sockaddr_In_Access; | |
181 | Port : C.unsigned_short); | |
182 | pragma Inline (Set_Port); | |
183 | -- Set Sin.Sin_Port to Port | |
184 | ||
185 | procedure Set_Address | |
186 | (Sin : Sockaddr_In_Access; | |
187 | Address : In_Addr); | |
188 | pragma Inline (Set_Address); | |
189 | -- Set Sin.Sin_Addr to Address | |
190 | ||
6cbd1b6f RK |
191 | type Hostent is record |
192 | H_Name : C.Strings.chars_ptr; | |
193 | H_Aliases : Chars_Ptr_Pointers.Pointer; | |
194 | H_Addrtype : C.short; | |
195 | H_Length : C.short; | |
196 | H_Addr_List : In_Addr_Access_Pointers.Pointer; | |
197 | end record; | |
198 | pragma Convention (C, Hostent); | |
199 | -- Host entry | |
200 | ||
201 | type Hostent_Access is access all Hostent; | |
202 | pragma Convention (C, Hostent_Access); | |
203 | -- Access to host entry | |
204 | ||
fbf5a39b | 205 | type Servent is record |
a397db96 AC |
206 | S_Name : C.Strings.chars_ptr; |
207 | S_Aliases : Chars_Ptr_Pointers.Pointer; | |
208 | S_Port : C.int; | |
209 | S_Proto : C.Strings.chars_ptr; | |
fbf5a39b AC |
210 | end record; |
211 | pragma Convention (C, Servent); | |
212 | -- Service entry | |
213 | ||
214 | type Servent_Access is access all Servent; | |
215 | pragma Convention (C, Servent_Access); | |
216 | -- Access to service entry | |
217 | ||
3d3bf932 TQ |
218 | type Two_Ints is array (0 .. 1) of C.int; |
219 | pragma Convention (C, Two_Ints); | |
220 | -- Container for two int values | |
221 | ||
222 | subtype Fd_Pair is Two_Ints; | |
223 | -- Two_Ints as used for Create_Signalling_Fds: a pair of connected file | |
224 | -- descriptors, one of which (the "read end" of the connection) being used | |
225 | -- for reading, the other one (the "write end") being used for writing. | |
226 | ||
227 | Read_End : constant := 0; | |
228 | Write_End : constant := 1; | |
229 | -- Indices into an Fd_Pair value providing access to each of the connected | |
230 | -- file descriptors. | |
6cbd1b6f | 231 | |
4491f0ae AC |
232 | -------------------------------- |
233 | -- Standard library functions -- | |
234 | -------------------------------- | |
235 | ||
6cbd1b6f RK |
236 | function C_Accept |
237 | (S : C.int; | |
238 | Addr : System.Address; | |
3d3bf932 | 239 | Addrlen : not null access C.int) return C.int; |
6cbd1b6f RK |
240 | |
241 | function C_Bind | |
242 | (S : C.int; | |
243 | Name : System.Address; | |
a397db96 | 244 | Namelen : C.int) return C.int; |
6cbd1b6f RK |
245 | |
246 | function C_Close | |
a397db96 | 247 | (Fd : C.int) return C.int; |
6cbd1b6f RK |
248 | |
249 | function C_Connect | |
250 | (S : C.int; | |
251 | Name : System.Address; | |
a397db96 | 252 | Namelen : C.int) return C.int; |
6cbd1b6f | 253 | |
6cbd1b6f RK |
254 | function C_Gethostname |
255 | (Name : System.Address; | |
a397db96 | 256 | Namelen : C.int) return C.int; |
6cbd1b6f RK |
257 | |
258 | function C_Getpeername | |
259 | (S : C.int; | |
260 | Name : System.Address; | |
3d3bf932 | 261 | Namelen : not null access C.int) return C.int; |
6cbd1b6f RK |
262 | |
263 | function C_Getsockname | |
264 | (S : C.int; | |
265 | Name : System.Address; | |
3d3bf932 | 266 | Namelen : not null access C.int) return C.int; |
6cbd1b6f RK |
267 | |
268 | function C_Getsockopt | |
269 | (S : C.int; | |
270 | Level : C.int; | |
271 | Optname : C.int; | |
272 | Optval : System.Address; | |
3d3bf932 | 273 | Optlen : not null access C.int) return C.int; |
6cbd1b6f RK |
274 | |
275 | function C_Inet_Addr | |
a397db96 | 276 | (Cp : C.Strings.chars_ptr) return C.int; |
6cbd1b6f RK |
277 | |
278 | function C_Ioctl | |
279 | (S : C.int; | |
280 | Req : C.int; | |
a397db96 | 281 | Arg : Int_Access) return C.int; |
6cbd1b6f RK |
282 | |
283 | function C_Listen | |
a397db96 AC |
284 | (S : C.int; |
285 | Backlog : C.int) return C.int; | |
6cbd1b6f | 286 | |
fbf5a39b | 287 | function C_Readv |
3d3bf932 | 288 | (Fd : C.int; |
fbf5a39b | 289 | Iov : System.Address; |
a397db96 | 290 | Iovcnt : C.int) return C.int; |
fbf5a39b | 291 | |
6cbd1b6f RK |
292 | function C_Recv |
293 | (S : C.int; | |
3d3bf932 | 294 | Msg : System.Address; |
6cbd1b6f | 295 | Len : C.int; |
a397db96 | 296 | Flags : C.int) return C.int; |
6cbd1b6f RK |
297 | |
298 | function C_Recvfrom | |
299 | (S : C.int; | |
3d3bf932 | 300 | Msg : System.Address; |
6cbd1b6f RK |
301 | Len : C.int; |
302 | Flags : C.int; | |
303 | From : Sockaddr_In_Access; | |
3d3bf932 | 304 | Fromlen : not null access C.int) return C.int; |
6cbd1b6f RK |
305 | |
306 | function C_Select | |
307 | (Nfds : C.int; | |
308 | Readfds : Fd_Set_Access; | |
309 | Writefds : Fd_Set_Access; | |
310 | Exceptfds : Fd_Set_Access; | |
a397db96 | 311 | Timeout : Timeval_Access) return C.int; |
6cbd1b6f RK |
312 | |
313 | function C_Send | |
314 | (S : C.int; | |
3d3bf932 | 315 | Msg : System.Address; |
6cbd1b6f | 316 | Len : C.int; |
a397db96 | 317 | Flags : C.int) return C.int; |
6cbd1b6f RK |
318 | |
319 | function C_Sendto | |
320 | (S : C.int; | |
321 | Msg : System.Address; | |
322 | Len : C.int; | |
323 | Flags : C.int; | |
324 | To : Sockaddr_In_Access; | |
a397db96 | 325 | Tolen : C.int) return C.int; |
6cbd1b6f RK |
326 | |
327 | function C_Setsockopt | |
328 | (S : C.int; | |
329 | Level : C.int; | |
330 | Optname : C.int; | |
331 | Optval : System.Address; | |
a397db96 | 332 | Optlen : C.int) return C.int; |
6cbd1b6f RK |
333 | |
334 | function C_Shutdown | |
3d3bf932 TQ |
335 | (S : C.int; |
336 | How : C.int) return C.int; | |
6cbd1b6f RK |
337 | |
338 | function C_Socket | |
339 | (Domain : C.int; | |
340 | Typ : C.int; | |
a397db96 | 341 | Protocol : C.int) return C.int; |
6cbd1b6f RK |
342 | |
343 | function C_Strerror | |
a397db96 | 344 | (Errnum : C.int) return C.Strings.chars_ptr; |
6cbd1b6f RK |
345 | |
346 | function C_System | |
a397db96 | 347 | (Command : System.Address) return C.int; |
6cbd1b6f | 348 | |
fbf5a39b | 349 | function C_Writev |
3d3bf932 | 350 | (Fd : C.int; |
fbf5a39b | 351 | Iov : System.Address; |
a397db96 | 352 | Iovcnt : C.int) return C.int; |
fbf5a39b | 353 | |
6cbd1b6f RK |
354 | function WSAStartup |
355 | (WS_Version : Interfaces.C.int; | |
a397db96 | 356 | WSADataAddress : System.Address) return Interfaces.C.int; |
6cbd1b6f | 357 | |
4491f0ae AC |
358 | ------------------------------------------------------- |
359 | -- Signalling file descriptors for selector abortion -- | |
360 | ------------------------------------------------------- | |
361 | ||
3d3bf932 TQ |
362 | package Signalling_Fds is |
363 | ||
364 | function Create (Fds : not null access Fd_Pair) return C.int; | |
365 | pragma Convention (C, Create); | |
366 | -- Create a pair of connected descriptors suitable for use with C_Select | |
367 | -- (used for signalling in Selector objects). | |
368 | ||
369 | function Read (Rsig : C.int) return C.int; | |
370 | pragma Convention (C, Read); | |
371 | -- Read one byte of data from rsig, the read end of a pair of signalling | |
372 | -- fds created by Create_Signalling_Fds. | |
373 | ||
374 | function Write (Wsig : C.int) return C.int; | |
375 | pragma Convention (C, Write); | |
376 | -- Write one byte of data to wsig, the write end of a pair of signalling | |
377 | -- fds created by Create_Signalling_Fds. | |
378 | ||
4491f0ae AC |
379 | procedure Close (Sig : C.int); |
380 | pragma Convention (C, Close); | |
381 | -- Close one end of a pair of signalling fds (ignoring any error) | |
382 | ||
3d3bf932 TQ |
383 | end Signalling_Fds; |
384 | ||
4491f0ae AC |
385 | ---------------------------- |
386 | -- Socket sets management -- | |
387 | ---------------------------- | |
388 | ||
fbf5a39b | 389 | procedure Free_Socket_Set |
a397db96 | 390 | (Set : Fd_Set_Access); |
a2cb348e | 391 | -- Free system-dependent socket set |
fbf5a39b AC |
392 | |
393 | procedure Get_Socket_From_Set | |
394 | (Set : Fd_Set_Access; | |
395 | Socket : Int_Access; | |
396 | Last : Int_Access); | |
4491f0ae AC |
397 | -- Get last socket in Socket and remove it from the socket set. The |
398 | -- parameter Last is a maximum value of the largest socket. This hint is | |
399 | -- used to avoid scanning very large socket sets. After a call to | |
400 | -- Get_Socket_From_Set, Last is set back to the real largest socket in the | |
401 | -- socket set. | |
fbf5a39b AC |
402 | |
403 | procedure Insert_Socket_In_Set | |
404 | (Set : Fd_Set_Access; | |
405 | Socket : C.int); | |
406 | -- Insert socket in the socket set | |
407 | ||
408 | function Is_Socket_In_Set | |
409 | (Set : Fd_Set_Access; | |
5d09245e AC |
410 | Socket : C.int) return C.int; |
411 | -- Check whether Socket is in the socket set, return a non-zero | |
412 | -- value if it is, zero if it is not. | |
fbf5a39b AC |
413 | |
414 | procedure Last_Socket_In_Set | |
3d3bf932 TQ |
415 | (Set : Fd_Set_Access; |
416 | Last : Int_Access); | |
417 | -- Find the largest socket in the socket set. This is needed for select(). | |
418 | -- When Last_Socket_In_Set is called, parameter Last is a maximum value of | |
419 | -- the largest socket. This hint is used to avoid scanning very large | |
420 | -- socket sets. After the call, Last is set back to the real largest socket | |
421 | -- in the socket set. | |
fbf5a39b AC |
422 | |
423 | function New_Socket_Set | |
a397db96 | 424 | (Set : Fd_Set_Access) return Fd_Set_Access; |
3d3bf932 TQ |
425 | -- Allocate a new socket set which is a system-dependent structure and |
426 | -- initialize by copying Set if it is non-null, by making it empty | |
427 | -- otherwise. | |
fbf5a39b AC |
428 | |
429 | procedure Remove_Socket_From_Set | |
430 | (Set : Fd_Set_Access; | |
431 | Socket : C.int); | |
432 | -- Remove socket from the socket set | |
6cbd1b6f | 433 | |
fbf5a39b | 434 | procedure WSACleanup; |
6cbd1b6f | 435 | |
4491f0ae | 436 | procedure Initialize; |
6cbd1b6f | 437 | procedure Finalize; |
6cbd1b6f RK |
438 | |
439 | private | |
6cbd1b6f RK |
440 | pragma Import (Stdcall, C_Accept, "accept"); |
441 | pragma Import (Stdcall, C_Bind, "bind"); | |
442 | pragma Import (Stdcall, C_Close, "closesocket"); | |
6cbd1b6f RK |
443 | pragma Import (Stdcall, C_Gethostname, "gethostname"); |
444 | pragma Import (Stdcall, C_Getpeername, "getpeername"); | |
445 | pragma Import (Stdcall, C_Getsockname, "getsockname"); | |
446 | pragma Import (Stdcall, C_Getsockopt, "getsockopt"); | |
4491f0ae | 447 | pragma Import (Stdcall, C_Inet_Addr, "inet_addr"); |
6cbd1b6f RK |
448 | pragma Import (Stdcall, C_Ioctl, "ioctlsocket"); |
449 | pragma Import (Stdcall, C_Listen, "listen"); | |
6cbd1b6f RK |
450 | pragma Import (Stdcall, C_Recv, "recv"); |
451 | pragma Import (Stdcall, C_Recvfrom, "recvfrom"); | |
6cbd1b6f RK |
452 | pragma Import (Stdcall, C_Send, "send"); |
453 | pragma Import (Stdcall, C_Sendto, "sendto"); | |
454 | pragma Import (Stdcall, C_Setsockopt, "setsockopt"); | |
455 | pragma Import (Stdcall, C_Shutdown, "shutdown"); | |
456 | pragma Import (Stdcall, C_Socket, "socket"); | |
457 | pragma Import (C, C_Strerror, "strerror"); | |
458 | pragma Import (C, C_System, "_system"); | |
6cbd1b6f | 459 | pragma Import (Stdcall, Socket_Errno, "WSAGetLastError"); |
fbf5a39b | 460 | pragma Import (Stdcall, Set_Socket_Errno, "WSASetLastError"); |
6cbd1b6f RK |
461 | pragma Import (Stdcall, WSAStartup, "WSAStartup"); |
462 | pragma Import (Stdcall, WSACleanup, "WSACleanup"); | |
463 | ||
fbf5a39b AC |
464 | pragma Import (C, Free_Socket_Set, "__gnat_free_socket_set"); |
465 | pragma Import (C, Get_Socket_From_Set, "__gnat_get_socket_from_set"); | |
466 | pragma Import (C, Is_Socket_In_Set, "__gnat_is_socket_in_set"); | |
467 | pragma Import (C, Last_Socket_In_Set, "__gnat_last_socket_in_set"); | |
468 | pragma Import (C, New_Socket_Set, "__gnat_new_socket_set"); | |
469 | pragma Import (C, Insert_Socket_In_Set, "__gnat_insert_socket_in_set"); | |
470 | pragma Import (C, Remove_Socket_From_Set, "__gnat_remove_socket_from_set"); | |
3d3bf932 | 471 | |
6cbd1b6f | 472 | end GNAT.Sockets.Thin; |