diff --git a/gcc/ada/libgnat/g-socket.adb b/gcc/ada/libgnat/g-socket.adb index dca696f7c5f8ae9aef492627b32181fdd570140a..c4e29075a0b40a84288c1ac73bdce7b30160c9d8 100644 --- a/gcc/ada/libgnat/g-socket.adb +++ b/gcc/ada/libgnat/g-socket.adb @@ -120,7 +120,8 @@ package body GNAT.Sockets is IPv6_Only => SOSC.IPV6_V6ONLY, Send_Timeout => SOSC.SO_SNDTIMEO, Receive_Timeout => SOSC.SO_RCVTIMEO, - Busy_Polling => SOSC.SO_BUSY_POLL]; + Busy_Polling => SOSC.SO_BUSY_POLL, + Bind_To_Device => SOSC.SO_BINDTODEVICE]; -- ??? Note: for OpenSolaris, Receive_Packet_Info should be IP_RECVPKTINFO, -- but for Linux compatibility this constant is the same as IP_PKTINFO. @@ -1413,17 +1414,21 @@ package body GNAT.Sockets is use type C.unsigned; use type C.unsigned_char; + -- SOSC.IF_NAMESIZE may be not defined, ensure that we have at least + -- a valid range for VS declared below. + NS : constant Interfaces.C.size_t := + (if SOSC.IF_NAMESIZE = -1 then 256 else SOSC.IF_NAMESIZE); V8 : aliased Two_Ints; V4 : aliased C.int; U4 : aliased C.unsigned; V1 : aliased C.unsigned_char; + VS : aliased C.char_array (1 .. NS); -- for devices name VT : aliased Timeval; Len : aliased C.int; Add : System.Address; Res : C.int; Opt : Option_Type (Name); Onm : Interfaces.C.int; - begin if Name in Specific_Option_Name then Onm := Options (Name); @@ -1491,6 +1496,11 @@ package body GNAT.Sockets is => Len := V8'Size / 8; Add := V8'Address; + + when Bind_To_Device + => + Len := VS'Length; + Add := VS'Address; end case; Res := @@ -1589,6 +1599,9 @@ package body GNAT.Sockets is else Opt.Timeout := To_Duration (VT); end if; + + when Bind_To_Device => + Opt.Device := ASU.To_Unbounded_String (C.To_Ada (VS)); end case; return Opt; @@ -2616,6 +2629,10 @@ package body GNAT.Sockets is V4 : aliased C.int; U4 : aliased C.unsigned; V1 : aliased C.unsigned_char; + VS : aliased C.char_array + (1 .. (if Option.Name = Bind_To_Device + then C.size_t (ASU.Length (Option.Device) + 1) + else 0)); VT : aliased Timeval; Len : C.int; Add : System.Address := Null_Address; @@ -2754,6 +2771,11 @@ package body GNAT.Sockets is Len := VT'Size / 8; Add := VT'Address; end if; + + when Bind_To_Device => + VS := C.To_C (ASU.To_String (Option.Device)); + Len := C.int (VS'Length); + Add := VS'Address; end case; if Option.Name in Specific_Option_Name then diff --git a/gcc/ada/libgnat/g-socket.ads b/gcc/ada/libgnat/g-socket.ads index d49245290ce1bbaf9c84a8ea0e2eb6e703d926e0..90740ec65a4bd87f777036615f5d138882ca1fe4 100644 --- a/gcc/ada/libgnat/g-socket.ads +++ b/gcc/ada/libgnat/g-socket.ads @@ -841,6 +841,9 @@ package GNAT.Sockets is -- Sets the approximate time in microseconds to busy poll on a blocking -- receive when there is no data. + Bind_To_Device, -- SO_BINDTODEVICE + -- Bind to a specific NIC (Network Interface Controller) + ------------------------------- -- IP_Protocol_For_TCP_Level -- ------------------------------- @@ -986,6 +989,8 @@ package GNAT.Sockets is Receive_Timeout => Timeout : Timeval_Duration; + when Bind_To_Device => + Device : Ada.Strings.Unbounded.Unbounded_String; end case; end record; diff --git a/gcc/ada/s-oscons-tmplt.c b/gcc/ada/s-oscons-tmplt.c index 28d42c5a4595e7ea9cfbfebfe46d34ecf92da2ad..fb6bb0f043bdfe5a3c41b5a1cd0af0f7f96d41ef 100644 --- a/gcc/ada/s-oscons-tmplt.c +++ b/gcc/ada/s-oscons-tmplt.c @@ -1545,6 +1545,11 @@ CND(SO_KEEPALIVE, "Enable keep-alive msgs") #endif CND(SO_LINGER, "Defer close to flush data") +#ifndef SO_BINDTODEVICE +# define SO_BINDTODEVICE -1 +#endif +CND(SO_BINDTODEVICE, "Bind to a NIC - Network Interface Controller") + #ifndef SO_BROADCAST # define SO_BROADCAST -1 #endif