OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [gcc/] [ada/] [g-socthi.adb] - Blame information for rev 801

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 706 jeremybenn
------------------------------------------------------------------------------
2
--                                                                          --
3
--                         GNAT COMPILER COMPONENTS                         --
4
--                                                                          --
5
--                    G N A T . S O C K E T S . T H I N                     --
6
--                                                                          --
7
--                                 B o d y                                  --
8
--                                                                          --
9
--                     Copyright (C) 2001-2010, AdaCore                     --
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 3,  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.                                     --
17
--                                                                          --
18
-- As a special exception under Section 7 of GPL version 3, you are granted --
19
-- additional permissions described in the GCC Runtime Library Exception,   --
20
-- version 3.1, as published by the Free Software Foundation.               --
21
--                                                                          --
22
-- You should have received a copy of the GNU General Public License and    --
23
-- a copy of the GCC Runtime Library Exception along with this program;     --
24
-- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
25
-- <http://www.gnu.org/licenses/>.                                          --
26
--                                                                          --
27
-- GNAT was originally developed  by the GNAT team at  New York University. --
28
-- Extensive contributions were provided by Ada Core Technologies Inc.      --
29
--                                                                          --
30
------------------------------------------------------------------------------
31
 
32
--  This package provides a target dependent thin interface to the sockets
33
--  layer for use by the GNAT.Sockets package (g-socket.ads). This package
34
--  should not be directly with'ed by an applications program.
35
 
36
--  This is the default version
37
 
38
with GNAT.OS_Lib; use GNAT.OS_Lib;
39
with GNAT.Task_Lock;
40
 
41
with Interfaces.C; use Interfaces.C;
42
 
43
package body GNAT.Sockets.Thin is
44
 
45
   Non_Blocking_Sockets : aliased Fd_Set;
46
   --  When this package is initialized with Process_Blocking_IO set
47
   --  to True, sockets are set in non-blocking mode to avoid blocking
48
   --  the whole process when a thread wants to perform a blocking IO
49
   --  operation. But the user can also set a socket in non-blocking
50
   --  mode by purpose. In order to make a difference between these
51
   --  two situations, we track the origin of non-blocking mode in
52
   --  Non_Blocking_Sockets. If S is in Non_Blocking_Sockets, it has
53
   --  been set in non-blocking mode by the user.
54
 
55
   Quantum : constant Duration := 0.2;
56
   --  When SOSC.Thread_Blocking_IO is False, we set sockets in
57
   --  non-blocking mode and we spend a period of time Quantum between
58
   --  two attempts on a blocking operation.
59
 
60
   Unknown_System_Error : constant C.Strings.chars_ptr :=
61
                            C.Strings.New_String ("Unknown system error");
62
 
63
   --  Comments required for following functions ???
64
 
65
   function Syscall_Accept
66
     (S       : C.int;
67
      Addr    : System.Address;
68
      Addrlen : not null access C.int) return C.int;
69
   pragma Import (C, Syscall_Accept, "accept");
70
 
71
   function Syscall_Connect
72
     (S       : C.int;
73
      Name    : System.Address;
74
      Namelen : C.int) return C.int;
75
   pragma Import (C, Syscall_Connect, "connect");
76
 
77
   function Syscall_Recv
78
     (S     : C.int;
79
      Msg   : System.Address;
80
      Len   : C.int;
81
      Flags : C.int) return C.int;
82
   pragma Import (C, Syscall_Recv, "recv");
83
 
84
   function Syscall_Recvfrom
85
     (S       : C.int;
86
      Msg     : System.Address;
87
      Len     : C.int;
88
      Flags   : C.int;
89
      From    : System.Address;
90
      Fromlen : not null access C.int) return C.int;
91
   pragma Import (C, Syscall_Recvfrom, "recvfrom");
92
 
93
   function Syscall_Recvmsg
94
     (S     : C.int;
95
      Msg   : System.Address;
96
      Flags : C.int) return System.CRTL.ssize_t;
97
   pragma Import (C, Syscall_Recvmsg, "recvmsg");
98
 
99
   function Syscall_Sendmsg
100
     (S     : C.int;
101
      Msg   : System.Address;
102
      Flags : C.int) return System.CRTL.ssize_t;
103
   pragma Import (C, Syscall_Sendmsg, "sendmsg");
104
 
105
   function Syscall_Sendto
106
     (S     : C.int;
107
      Msg   : System.Address;
108
      Len   : C.int;
109
      Flags : C.int;
110
      To    : System.Address;
111
      Tolen : C.int) return C.int;
112
   pragma Import (C, Syscall_Sendto, "sendto");
113
 
114
   function Syscall_Socket
115
     (Domain   : C.int;
116
      Typ      : C.int;
117
      Protocol : C.int) return C.int;
118
   pragma Import (C, Syscall_Socket, "socket");
119
 
120
   procedure Disable_SIGPIPE (S : C.int);
121
   pragma Import (C, Disable_SIGPIPE, "__gnat_disable_sigpipe");
122
 
123
   procedure Disable_All_SIGPIPEs;
124
   pragma Import (C, Disable_All_SIGPIPEs, "__gnat_disable_all_sigpipes");
125
   --  Sets the process to ignore all SIGPIPE signals on platforms that
126
   --  don't support Disable_SIGPIPE for particular streams.
127
 
128
   function Non_Blocking_Socket (S : C.int) return Boolean;
129
   procedure Set_Non_Blocking_Socket (S : C.int; V : Boolean);
130
 
131
   --------------
132
   -- C_Accept --
133
   --------------
134
 
135
   function C_Accept
136
     (S       : C.int;
137
      Addr    : System.Address;
138
      Addrlen : not null access C.int) return C.int
139
   is
140
      R   : C.int;
141
      Val : aliased C.int := 1;
142
 
143
      Discard : C.int;
144
      pragma Warnings (Off, Discard);
145
 
146
   begin
147
      loop
148
         R := Syscall_Accept (S, Addr, Addrlen);
149
         exit when SOSC.Thread_Blocking_IO
150
           or else R /= Failure
151
           or else Non_Blocking_Socket (S)
152
           or else Errno /= SOSC.EWOULDBLOCK;
153
         delay Quantum;
154
      end loop;
155
 
156
      if not SOSC.Thread_Blocking_IO
157
        and then R /= Failure
158
      then
159
         --  A socket inherits the properties ot its server especially
160
         --  the FIONBIO flag. Do not use Socket_Ioctl as this subprogram
161
         --  tracks sockets set in non-blocking mode by user.
162
 
163
         Set_Non_Blocking_Socket (R, Non_Blocking_Socket (S));
164
         Discard := C_Ioctl (R, SOSC.FIONBIO, Val'Access);
165
      end if;
166
 
167
      Disable_SIGPIPE (R);
168
      return R;
169
   end C_Accept;
170
 
171
   ---------------
172
   -- C_Connect --
173
   ---------------
174
 
175
   function C_Connect
176
     (S       : C.int;
177
      Name    : System.Address;
178
      Namelen : C.int) return C.int
179
   is
180
      Res : C.int;
181
 
182
   begin
183
      Res := Syscall_Connect (S, Name, Namelen);
184
 
185
      if SOSC.Thread_Blocking_IO
186
        or else Res /= Failure
187
        or else Non_Blocking_Socket (S)
188
        or else Errno /= SOSC.EINPROGRESS
189
      then
190
         return Res;
191
      end if;
192
 
193
      declare
194
         WSet : aliased Fd_Set;
195
         Now  : aliased Timeval;
196
 
197
      begin
198
         Reset_Socket_Set (WSet'Access);
199
         loop
200
            Insert_Socket_In_Set (WSet'Access, S);
201
            Now := Immediat;
202
            Res := C_Select
203
              (S + 1,
204
               No_Fd_Set_Access,
205
               WSet'Access,
206
               No_Fd_Set_Access,
207
               Now'Unchecked_Access);
208
 
209
            exit when Res > 0;
210
 
211
            if Res = Failure then
212
               return Res;
213
            end if;
214
 
215
            delay Quantum;
216
         end loop;
217
      end;
218
 
219
      Res := Syscall_Connect (S, Name, Namelen);
220
 
221
      if Res = Failure
222
        and then Errno = SOSC.EISCONN
223
      then
224
         return Thin_Common.Success;
225
      else
226
         return Res;
227
      end if;
228
   end C_Connect;
229
 
230
   ------------------
231
   -- Socket_Ioctl --
232
   ------------------
233
 
234
   function Socket_Ioctl
235
     (S   : C.int;
236
      Req : C.int;
237
      Arg : access C.int) return C.int
238
   is
239
   begin
240
      if not SOSC.Thread_Blocking_IO and then Req = SOSC.FIONBIO then
241
         if Arg.all /= 0 then
242
            Set_Non_Blocking_Socket (S, True);
243
         end if;
244
      end if;
245
 
246
      return C_Ioctl (S, Req, Arg);
247
   end Socket_Ioctl;
248
 
249
   ------------
250
   -- C_Recv --
251
   ------------
252
 
253
   function C_Recv
254
     (S     : C.int;
255
      Msg   : System.Address;
256
      Len   : C.int;
257
      Flags : C.int) return C.int
258
   is
259
      Res : C.int;
260
 
261
   begin
262
      loop
263
         Res := Syscall_Recv (S, Msg, Len, Flags);
264
         exit when SOSC.Thread_Blocking_IO
265
           or else Res /= Failure
266
           or else Non_Blocking_Socket (S)
267
           or else Errno /= SOSC.EWOULDBLOCK;
268
         delay Quantum;
269
      end loop;
270
 
271
      return Res;
272
   end C_Recv;
273
 
274
   ----------------
275
   -- C_Recvfrom --
276
   ----------------
277
 
278
   function C_Recvfrom
279
     (S       : C.int;
280
      Msg     : System.Address;
281
      Len     : C.int;
282
      Flags   : C.int;
283
      From    : System.Address;
284
      Fromlen : not null access C.int) return C.int
285
   is
286
      Res : C.int;
287
 
288
   begin
289
      loop
290
         Res := Syscall_Recvfrom (S, Msg, Len, Flags, From, Fromlen);
291
         exit when SOSC.Thread_Blocking_IO
292
           or else Res /= Failure
293
           or else Non_Blocking_Socket (S)
294
           or else Errno /= SOSC.EWOULDBLOCK;
295
         delay Quantum;
296
      end loop;
297
 
298
      return Res;
299
   end C_Recvfrom;
300
 
301
   ---------------
302
   -- C_Recvmsg --
303
   ---------------
304
 
305
   function C_Recvmsg
306
     (S     : C.int;
307
      Msg   : System.Address;
308
      Flags : C.int) return System.CRTL.ssize_t
309
   is
310
      Res : System.CRTL.ssize_t;
311
 
312
   begin
313
      loop
314
         Res := Syscall_Recvmsg (S, Msg, Flags);
315
         exit when SOSC.Thread_Blocking_IO
316
           or else Res /= System.CRTL.ssize_t (Failure)
317
           or else Non_Blocking_Socket (S)
318
           or else Errno /= SOSC.EWOULDBLOCK;
319
         delay Quantum;
320
      end loop;
321
 
322
      return Res;
323
   end C_Recvmsg;
324
 
325
   ---------------
326
   -- C_Sendmsg --
327
   ---------------
328
 
329
   function C_Sendmsg
330
     (S     : C.int;
331
      Msg   : System.Address;
332
      Flags : C.int) return System.CRTL.ssize_t
333
   is
334
      Res : System.CRTL.ssize_t;
335
 
336
   begin
337
      loop
338
         Res := Syscall_Sendmsg (S, Msg, Flags);
339
         exit when SOSC.Thread_Blocking_IO
340
           or else Res /= System.CRTL.ssize_t (Failure)
341
           or else Non_Blocking_Socket (S)
342
           or else Errno /= SOSC.EWOULDBLOCK;
343
         delay Quantum;
344
      end loop;
345
 
346
      return Res;
347
   end C_Sendmsg;
348
 
349
   --------------
350
   -- C_Sendto --
351
   --------------
352
 
353
   function C_Sendto
354
     (S     : C.int;
355
      Msg   : System.Address;
356
      Len   : C.int;
357
      Flags : C.int;
358
      To    : System.Address;
359
      Tolen : C.int) return C.int
360
   is
361
      Res : C.int;
362
 
363
   begin
364
      loop
365
         Res := Syscall_Sendto (S, Msg, Len, Flags, To, Tolen);
366
         exit when SOSC.Thread_Blocking_IO
367
           or else Res /= Failure
368
           or else Non_Blocking_Socket (S)
369
           or else Errno /= SOSC.EWOULDBLOCK;
370
         delay Quantum;
371
      end loop;
372
 
373
      return Res;
374
   end C_Sendto;
375
 
376
   --------------
377
   -- C_Socket --
378
   --------------
379
 
380
   function C_Socket
381
     (Domain   : C.int;
382
      Typ      : C.int;
383
      Protocol : C.int) return C.int
384
   is
385
      R   : C.int;
386
      Val : aliased C.int := 1;
387
 
388
      Discard : C.int;
389
      pragma Unreferenced (Discard);
390
 
391
   begin
392
      R := Syscall_Socket (Domain, Typ, Protocol);
393
 
394
      if not SOSC.Thread_Blocking_IO
395
        and then R /= Failure
396
      then
397
         --  Do not use Socket_Ioctl as this subprogram tracks sockets set
398
         --  in non-blocking mode by user.
399
 
400
         Discard := C_Ioctl (R, SOSC.FIONBIO, Val'Access);
401
         Set_Non_Blocking_Socket (R, False);
402
      end if;
403
      Disable_SIGPIPE (R);
404
      return R;
405
   end C_Socket;
406
 
407
   --------------
408
   -- Finalize --
409
   --------------
410
 
411
   procedure Finalize is
412
   begin
413
      null;
414
   end Finalize;
415
 
416
   -------------------------
417
   -- Host_Error_Messages --
418
   -------------------------
419
 
420
   package body Host_Error_Messages is separate;
421
 
422
   ----------------
423
   -- Initialize --
424
   ----------------
425
 
426
   procedure Initialize is
427
   begin
428
      Disable_All_SIGPIPEs;
429
      Reset_Socket_Set (Non_Blocking_Sockets'Access);
430
   end Initialize;
431
 
432
   -------------------------
433
   -- Non_Blocking_Socket --
434
   -------------------------
435
 
436
   function Non_Blocking_Socket (S : C.int) return Boolean is
437
      R : Boolean;
438
   begin
439
      Task_Lock.Lock;
440
      R := (Is_Socket_In_Set (Non_Blocking_Sockets'Access, S) /= 0);
441
      Task_Lock.Unlock;
442
      return R;
443
   end Non_Blocking_Socket;
444
 
445
   -----------------------------
446
   -- Set_Non_Blocking_Socket --
447
   -----------------------------
448
 
449
   procedure Set_Non_Blocking_Socket (S : C.int; V : Boolean) is
450
   begin
451
      Task_Lock.Lock;
452
 
453
      if V then
454
         Insert_Socket_In_Set (Non_Blocking_Sockets'Access, S);
455
      else
456
         Remove_Socket_From_Set (Non_Blocking_Sockets'Access, S);
457
      end if;
458
 
459
      Task_Lock.Unlock;
460
   end Set_Non_Blocking_Socket;
461
 
462
   --------------------
463
   -- Signalling_Fds --
464
   --------------------
465
 
466
   package body Signalling_Fds is
467
 
468
      --  In this default implementation, we use a C version of these
469
      --  subprograms provided by socket.c.
470
 
471
      function C_Create (Fds : not null access Fd_Pair) return C.int;
472
      function C_Read (Rsig : C.int) return C.int;
473
      function C_Write (Wsig : C.int) return C.int;
474
      procedure C_Close (Sig : C.int);
475
 
476
      pragma Import (C, C_Create, "__gnat_create_signalling_fds");
477
      pragma Import (C, C_Read,   "__gnat_read_signalling_fd");
478
      pragma Import (C, C_Write,  "__gnat_write_signalling_fd");
479
      pragma Import (C, C_Close,  "__gnat_close_signalling_fd");
480
 
481
      function Create
482
        (Fds : not null access Fd_Pair) return C.int renames C_Create;
483
      function Read (Rsig : C.int) return C.int renames C_Read;
484
      function Write (Wsig : C.int) return C.int renames C_Write;
485
      procedure Close (Sig : C.int) renames C_Close;
486
 
487
   end Signalling_Fds;
488
 
489
   --------------------------
490
   -- Socket_Error_Message --
491
   --------------------------
492
 
493
   function Socket_Error_Message
494
     (Errno : Integer) return C.Strings.chars_ptr
495
   is separate;
496
 
497
end GNAT.Sockets.Thin;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.