summaryrefslogtreecommitdiff
path: root/gcc/ada/g-socket.adb
diff options
context:
space:
mode:
authorcharlet <charlet@138bc75d-0d04-0410-961f-82ee72b054a4>2007-04-06 09:15:09 +0000
committercharlet <charlet@138bc75d-0d04-0410-961f-82ee72b054a4>2007-04-06 09:15:09 +0000
commit232e4d04f0263022b1379a7886e28e7f082f7eb8 (patch)
treed2a9f2de1b4f8ce5a655a929362077213fa220da /gcc/ada/g-socket.adb
parent32c07c22100b9a6f342e6a5825ac36b1b72d036b (diff)
downloadgcc-232e4d04f0263022b1379a7886e28e7f082f7eb8.tar.gz
2007-04-06 Thomas Quinot <quinot@adacore.com>
Pat Rogers <rogers@adacore.com> Pascal Obry <obry@adacore.com> * g-stsifd-sockets.adb: New file. * g-socthi.ads, g-socket.adb, g-socthi-vxworks.adb, g-socthi-vxworks.ads, g-socthi-mingw.ads, g-socthi-vms.ads, g-socthi-vms.adb: Move signalling fd management to a nested package, so that they can conveniently be moved to a subunit that is shared across Windows, VMS, and VxWorks (Ada implementation) or completed with imported bodies from socket.c (UNIX case). (Read_Signalling_Fd, Write_Signalling_Fd, Create_Signalling_Fds): New subprograms. (Check_Selector): Use Read_Signalling_Fd to read and discard data from the signalling file descriptor. (Abort_Selector): Use Write_Signalling_Fd to write dummy data to the signalling file descriptor. (Create_Selector): Use new C-imported subprogram Create_Signalling_Fds instead of creating a pair of sockets for signalling here. * g-socthi.adb: Ditto. Set the runtime process to ignore SIGPIPEs on platforms that support neither SO_NOSIGPIPE nor MSG_NOSIGNAL functionality. * g-socthi-mingw.adb: Ditto. (WS_Version): Use Windows 2.2. Use Winsock 2.2 (instead of 1.1) for the GNAT.Socket API. * g-soliop-mingw.ads: Link with ws2_32 for Windows 2.x support. Use Winsock 2.2 (instead of 1.1) for the GNAT.Socket API. * Makefile.in: New libgnat pair g-stsifd.adb<g-stsifd-sockets.adb. added GNAT byte swapping facility Update FreeBSD THREADSLIB from -lc_r to -lpthread, for FreeBSD 6. * g-bytswa.adb, g-bytswa-x86.adb, g-bytswa.ads: New files. * socket.c (__gnat_read_signalling_fd, __gnat_write_controlling_fd): New subprograms. (__gnat_create_signalling_fds): New subprogram. Set the runtime process to ignore SIGPIPEs on platforms that support neither SO_NOSIGPIPE nor MSG_NOSIGNAL functionality. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@123542 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/ada/g-socket.adb')
-rw-r--r--gcc/ada/g-socket.adb122
1 files changed, 17 insertions, 105 deletions
diff --git a/gcc/ada/g-socket.adb b/gcc/ada/g-socket.adb
index 01765a70715..2773b7ab036 100644
--- a/gcc/ada/g-socket.adb
+++ b/gcc/ada/g-socket.adb
@@ -236,14 +236,13 @@ package body GNAT.Sockets is
--------------------
procedure Abort_Selector (Selector : Selector_Type) is
- Buf : aliased Character := ASCII.NUL;
Res : C.int;
begin
- -- Send an empty array to unblock C select system call
+ -- Send one byte to unblock select system call
+
+ Res := Signalling_Fds.Write (C.int (Selector.W_Sig_Socket));
- Res := C_Send (C.int (Selector.W_Sig_Socket), Buf'Address, 1,
- Constants.MSG_Forced_Flags);
if Res = Failure then
Raise_Socket_Error (Socket_Errno);
end if;
@@ -454,16 +453,11 @@ package body GNAT.Sockets is
if Is_Set (RSet, RSig) then
Clear (RSet, RSig);
- declare
- Buf : Character;
-
- begin
- Res := C_Recv (C.int (RSig), Buf'Address, 1, 0);
+ Res := Signalling_Fds.Read (C.int (RSig));
- if Res = Failure then
- Raise_Socket_Error (Socket_Errno);
- end if;
- end;
+ if Res = Failure then
+ Raise_Socket_Error (Socket_Errno);
+ end if;
Status := Aborted;
@@ -674,105 +668,23 @@ package body GNAT.Sockets is
---------------------
procedure Create_Selector (Selector : out Selector_Type) is
- S0 : C.int;
- S1 : C.int;
- S2 : C.int;
- Res : C.int;
- Sin : aliased Sockaddr_In;
- Len : aliased C.int := Sin'Size / 8;
- Err : Integer;
+ Two_Fds : aliased Fd_Pair;
+ Res : C.int;
begin
- -- We open two signalling sockets. One of them is used to send data to
- -- the other, which is included in a C_Select socket set. The
- -- communication is used to force the call to C_Select to complete, and
+ -- We open two signalling file descriptors. One of them is used to send
+ -- data to the other, which is included in a C_Select socket set. The
+ -- communication is used to force a call to C_Select to complete, and
-- the waiting task to resume its execution.
- -- Create a listening socket
-
- S0 := C_Socket (Constants.AF_INET, Constants.SOCK_STREAM, 0);
-
- if S0 = Failure then
- Raise_Socket_Error (Socket_Errno);
- end if;
-
- -- Bind the socket to any unused port on localhost
-
- Sin.Sin_Addr.S_B1 := 127;
- Sin.Sin_Addr.S_B2 := 0;
- Sin.Sin_Addr.S_B3 := 0;
- Sin.Sin_Addr.S_B4 := 1;
- Sin.Sin_Port := 0;
-
- Res := C_Bind (S0, Sin'Address, Len);
-
- if Res = Failure then
- Err := Socket_Errno;
- Res := C_Close (S0);
- Raise_Socket_Error (Err);
- end if;
-
- -- Get the port used by the socket
-
- Res := C_Getsockname (S0, Sin'Address, Len'Access);
-
- if Res = Failure then
- Err := Socket_Errno;
- Res := C_Close (S0);
- Raise_Socket_Error (Err);
- end if;
-
- -- Set backlog to 1 to guarantee that exactly one call to connect(2)
- -- can succeed.
-
- Res := C_Listen (S0, 1);
-
- if Res = Failure then
- Err := Socket_Errno;
- Res := C_Close (S0);
- Raise_Socket_Error (Err);
- end if;
-
- S1 := C_Socket (Constants.AF_INET, Constants.SOCK_STREAM, 0);
-
- if S1 = Failure then
- Err := Socket_Errno;
- Res := C_Close (S0);
- Raise_Socket_Error (Err);
- end if;
-
- -- Do a connect and accept the connection
-
- Res := C_Connect (S1, Sin'Address, Len);
-
- if Res = Failure then
- Err := Socket_Errno;
- Res := C_Close (S0);
- Res := C_Close (S1);
- Raise_Socket_Error (Err);
- end if;
-
- -- Since the call to connect(2) has suceeded and the backlog limit on
- -- the listening socket is 1, we know that there is now exactly one
- -- pending connection on S0, which is the one from S1.
-
- S2 := C_Accept (S0, Sin'Address, Len'Access);
-
- if S2 = Failure then
- Err := Socket_Errno;
- Res := C_Close (S0);
- Res := C_Close (S1);
- Raise_Socket_Error (Err);
- end if;
-
- Res := C_Close (S0);
+ Res := Signalling_Fds.Create (Two_Fds'Access);
if Res = Failure then
Raise_Socket_Error (Socket_Errno);
end if;
- Selector.R_Sig_Socket := Socket_Type (S1);
- Selector.W_Sig_Socket := Socket_Type (S2);
+ Selector.R_Sig_Socket := Socket_Type (Two_Fds (Read_End));
+ Selector.W_Sig_Socket := Socket_Type (Two_Fds (Write_End));
end Create_Selector;
-------------------
@@ -1073,7 +985,7 @@ package body GNAT.Sockets is
is
use type C.unsigned_char;
- V8 : aliased Two_Int;
+ V8 : aliased Two_Ints;
V4 : aliased C.int;
V1 : aliased C.unsigned_char;
VT : aliased Timeval;
@@ -1899,7 +1811,7 @@ package body GNAT.Sockets is
Level : Level_Type := Socket_Level;
Option : Option_Type)
is
- V8 : aliased Two_Int;
+ V8 : aliased Two_Ints;
V4 : aliased C.int;
V1 : aliased C.unsigned_char;
VT : aliased Timeval;