1--
2--  Copyright (C) 2016 Stefan Berghofer <stefan.berghofer@secunet.com>
3--  Copyright (C) 2016 Reto Buerki <reet@codelabs.ch>
4--  Copyright (C) 2016 Adrian-Ken Rueegsegger <ken@codelabs.ch>
5--
6--  This program is free software; you can redistribute it and/or modify it
7--  under the terms of the GNU General Public License as published by the
8--  Free Software Foundation; either version 2 of the License, or (at your
9--  option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
10--
11--  This program is distributed in the hope that it will be useful, but
12--  WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13--  or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14--  for more details.
15--
16--  As a special exception, if other files instantiate generics from this
17--  unit,  or  you  link  this  unit  with  other  files  to  produce  an
18--  executable   this  unit  does  not  by  itself  cause  the  resulting
19--  executable to  be  covered by the  GNU General  Public License.  This
20--  exception does  not  however  invalidate  any  other reasons why  the
21--  executable file might be covered by the GNU Public License.
22--
23
24with GNAT.OS_Lib;
25
26with Ada.Text_IO;
27with Ada.Streams;
28with Ada.Unchecked_Conversion;
29
30with Anet.Sockets.Unix;
31with Anet.Constants;
32
33use type Ada.Streams.Stream_Element_Offset;
34
35--  Non-blocking server example.
36--  Client: socat UNIX:/tmp/anet.server.nonblocking -
37procedure Server_Nonblocking
38is
39   subtype Stream_Type is Ada.Streams.Stream_Element_Array (1 .. 100);
40   subtype String_Type is String (1 .. 100);
41
42   function Stream_To_String is new Ada.Unchecked_Conversion
43     (Source => Stream_Type,
44      Target => String_Type);
45
46   Socket, Client_Socket : Anet.Sockets.Unix.TCP_Socket_Type;
47   Message               : Stream_Type;
48   Last                  : Ada.Streams.Stream_Element_Offset;
49   Accepted              : Boolean := False;
50begin
51   Socket.Init;
52   Socket.Set_Nonblocking_Mode;
53   Socket.Bind ("/tmp/anet.server.nonblocking");
54   Socket.Listen;
55
56   loop
57      begin
58         if Accepted then
59            Client_Socket.Receive
60              (Item => Message,
61               Last => Last);
62
63            if Last /= 0 then
64               Ada.Text_IO.Put ("Received message: ");
65               Ada.Text_IO.Put_Line (Stream_To_String (Message)
66                                     (1 .. Natural (Last)));
67            else
68               Ada.Text_IO.Put_Line ("Closed connection");
69               Client_Socket.Close;
70               Accepted := False;
71            end if;
72         else
73            Socket.Accept_Connection
74              (New_Socket => Client_Socket);
75            Client_Socket.Set_Nonblocking_Mode;
76            Ada.Text_IO.Put_Line ("Connection established");
77            Accepted := True;
78         end if;
79
80      exception
81         when Anet.Socket_Error =>
82            if GNAT.OS_Lib.Errno = Anet.Constants.Sys.EAGAIN then
83               Ada.Text_IO.Put_Line ("Waiting");
84               delay 1.0;
85            else
86               raise;
87            end if;
88      end;
89   end loop;
90end Server_Nonblocking;
91