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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [packages/] [io/] [fileio/] [current/] [src/] [socket.cxx] - Blame information for rev 786

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 786 skrzyp
//==========================================================================
2
//
3
//      socket.cxx
4
//
5
//      Fileio socket operations
6
//
7
//==========================================================================
8
// ####ECOSGPLCOPYRIGHTBEGIN####                                            
9
// -------------------------------------------                              
10
// This file is part of eCos, the Embedded Configurable Operating System.   
11
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
12
//
13
// eCos is free software; you can redistribute it and/or modify it under    
14
// the terms of the GNU General Public License as published by the Free     
15
// Software Foundation; either version 2 or (at your option) any later      
16
// version.                                                                 
17
//
18
// eCos is distributed in the hope that it will be useful, but WITHOUT      
19
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or    
20
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License    
21
// for more details.                                                        
22
//
23
// You should have received a copy of the GNU General Public License        
24
// along with eCos; if not, write to the Free Software Foundation, Inc.,    
25
// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.            
26
//
27
// As a special exception, if other files instantiate templates or use      
28
// macros or inline functions from this file, or you compile this file      
29
// and link it with other works to produce a work based on this file,       
30
// this file does not by itself cause the resulting work to be covered by   
31
// the GNU General Public License. However the source code for this file    
32
// must still be made available in accordance with section (3) of the GNU   
33
// General Public License v2.                                               
34
//
35
// This exception does not invalidate any other reasons why a work based    
36
// on this file might be covered by the GNU General Public License.         
37
// -------------------------------------------                              
38
// ####ECOSGPLCOPYRIGHTEND####                                              
39
//==========================================================================
40
//#####DESCRIPTIONBEGIN####
41
//
42
// Author(s):           nickg
43
// Contributors:        nickg
44
// Date:                2000-05-25
45
// Purpose:             Fileio socket operations
46
// Description:         These are the functions that operate on sockets,
47
//                      such as socket(), bind(), accept() etc.
48
//              
49
//              
50
//
51
//####DESCRIPTIONEND####
52
//
53
//==========================================================================
54
 
55
#include <pkgconf/system.h>
56
#include <pkgconf/hal.h>
57
#include <pkgconf/kernel.h>
58
#include <pkgconf/io_fileio.h>
59
 
60
#include <cyg/hal/hal_tables.h>
61
 
62
#include <cyg/kernel/ktypes.h>         // base kernel types
63
#include <cyg/infra/cyg_trac.h>        // tracing macros
64
#include <cyg/infra/cyg_ass.h>         // assertion macros
65
 
66
#include <stdarg.h>                     // for fcntl()
67
 
68
#include <cyg/io/file.h>                // struct iovec
69
 
70
#include "fio.h"                       // Private header
71
 
72
#include <cyg/kernel/mutex.hxx>        // mutex definitions
73
 
74
#ifdef CYGPKG_NET
75
 
76
#include <sys/socket.h>                 // struct msghdr
77
 
78
#endif
79
 
80
//==========================================================================
81
// Forward definitions
82
 
83
static void cyg_ns_lock( cyg_nstab_entry *ns );
84
static void cyg_ns_unlock( cyg_nstab_entry *ns );
85
static void cyg_sock_lock( cyg_file *fp );
86
static void cyg_sock_unlock( cyg_file *fp );
87
 
88
//==========================================================================
89
// Local entry/return macros
90
 
91
#define SOCKET_ENTRY() FILEIO_ENTRY()
92
 
93
#define SOCKET_RETURN(err) FILEIO_RETURN(err)
94
 
95
#define SOCKET_RETURN_VALUE(val) FILEIO_RETURN_VALUE(val)
96
 
97
//==========================================================================
98
// Locking protocols
99
 
100
#define LOCK_NS( _n ) cyg_ns_lock( _n )
101
 
102
#define UNLOCK_NS( _n ) cyg_ns_unlock( _n )
103
 
104
#define LOCK_SOCKET( _fp ) cyg_sock_lock( _fp )
105
 
106
#define UNLOCK_SOCKET( _fp ) cyg_sock_unlock( _fp )
107
 
108
//==========================================================================
109
// Tables and local variables
110
 
111
// Array of network stacks installed
112
__externC cyg_nstab_entry cyg_nstab[];
113
CYG_HAL_TABLE_BEGIN( cyg_nstab, nstab );
114
 
115
// End of array marker
116
__externC cyg_nstab_entry cyg_nstab_end;
117
CYG_HAL_TABLE_END( cyg_nstab_end, nstab );
118
 
119
static Cyg_Mutex nstab_lock[CYGNUM_FILEIO_NSTAB_MAX] CYGBLD_ATTRIB_INIT_PRI(CYG_INIT_IO_FS);
120
 
121
//==========================================================================
122
// Initialization
123
 
124
__externC void cyg_nstab_init()
125
{
126
    cyg_nstab_entry *n;
127
 
128
    for( n = &cyg_nstab[0]; n != &cyg_nstab_end; n++ )
129
    {
130
        // stop if there are more than the configured maximum
131
        if( n-&cyg_nstab[0] >= CYGNUM_FILEIO_NSTAB_MAX )
132
            break;
133
 
134
        if( n->init( n ) == 0 )
135
        {
136
            n->valid = true;
137
        }
138
    }
139
}
140
 
141
//==========================================================================
142
// Socket API calls
143
 
144
// -------------------------------------------------------------------------
145
 
146
__externC int   socket (int domain, int type, int protocol)
147
{
148
    SOCKET_ENTRY();
149
 
150
    int err = EAFNOSUPPORT;
151
    int fd;
152
    cyg_file *file;
153
 
154
    fd = cyg_fd_alloc(0);
155
 
156
    if( fd < 0 )
157
        SOCKET_RETURN(EMFILE);
158
 
159
    file = cyg_file_alloc();
160
 
161
    if( file == NULL )
162
    {
163
        cyg_fd_free(fd);
164
        SOCKET_RETURN(ENFILE);
165
    }
166
 
167
    cyg_nstab_entry *n;
168
 
169
    for( n = &cyg_nstab[0]; n != &cyg_nstab_end; n++ )
170
    {
171
        LOCK_NS( n );
172
 
173
        err = n->socket( n, domain, type, protocol, file );
174
 
175
        UNLOCK_NS( n );
176
 
177
        if( err == 0 ) break;
178
    }
179
 
180
    if( err != 0 )
181
    {
182
        cyg_fd_free(fd);
183
        cyg_file_free(file);
184
        SOCKET_RETURN( err );
185
    }
186
 
187
    file->f_syncmode = n->syncmode;
188
    file->f_mte = (cyg_mtab_entry *)n;
189
 
190
    cyg_fd_assign( fd, file );
191
 
192
    SOCKET_RETURN_VALUE(fd);
193
}
194
 
195
 
196
// -------------------------------------------------------------------------
197
 
198
__externC int   accept (int s, struct sockaddr *sa, socklen_t *addrlen)
199
{
200
    SOCKET_ENTRY();
201
 
202
    int err = 0;
203
    int fd;
204
    cyg_file *fp;
205
    cyg_file *new_fp;
206
 
207
    fp = cyg_fp_get( s );
208
 
209
    if( fp == NULL )
210
        FILEIO_RETURN(EBADF);
211
 
212
    fd = cyg_fd_alloc(0);
213
 
214
    if( fd < 0 )
215
    {
216
        cyg_fp_free( fp );
217
        SOCKET_RETURN(EMFILE);
218
    }
219
 
220
    new_fp = cyg_file_alloc();
221
 
222
    if( new_fp == NULL )
223
    {
224
        cyg_fp_free( fp );
225
        cyg_fd_free(fd);
226
        SOCKET_RETURN(ENFILE);
227
    }
228
 
229
    if( fp->f_type == CYG_FILE_TYPE_SOCKET )
230
    {
231
        cyg_sock_ops *ops = (cyg_sock_ops *)fp->f_xops;
232
 
233
        LOCK_SOCKET( fp );
234
 
235
        err = ops->accept( fp, new_fp, sa, addrlen );
236
 
237
        UNLOCK_SOCKET( fp );
238
 
239
    }
240
    else err = EBADF;
241
 
242
    if( err != 0 )
243
    {
244
        cyg_fp_free( fp );
245
        cyg_fd_free(fd);
246
        cyg_file_free(new_fp);
247
        SOCKET_RETURN( err );
248
    }
249
 
250
    new_fp->f_syncmode = fp->f_syncmode;
251
    new_fp->f_mte = fp->f_mte;
252
 
253
    cyg_fd_assign( fd, new_fp );
254
 
255
    cyg_fp_free( fp );
256
 
257
    SOCKET_RETURN_VALUE(fd);
258
}
259
 
260
 
261
// -------------------------------------------------------------------------
262
 
263
__externC int   bind (int s, const struct sockaddr *sa, unsigned int len)
264
{
265
    SOCKET_ENTRY();
266
 
267
    int ret = 0;
268
    cyg_file *fp;
269
    struct sockaddr sa2 = *sa;
270
 
271
    fp = cyg_fp_get( s );
272
 
273
    if( fp == NULL )
274
        FILEIO_RETURN(EBADF);
275
 
276
    if( fp->f_type == CYG_FILE_TYPE_SOCKET )
277
    {
278
        cyg_sock_ops *ops = (cyg_sock_ops *)fp->f_xops;
279
 
280
        LOCK_SOCKET( fp );
281
 
282
        ret = ops->bind( fp, &sa2, len );
283
 
284
        UNLOCK_SOCKET( fp );
285
 
286
    }
287
 
288
    cyg_fp_free( fp );
289
 
290
    SOCKET_RETURN(ret);
291
}
292
 
293
 
294
// -------------------------------------------------------------------------
295
 
296
__externC int   connect (int s, const struct sockaddr *sa, socklen_t len)
297
{
298
    SOCKET_ENTRY();
299
 
300
    int ret = 0;
301
    cyg_file *fp;
302
 
303
    fp = cyg_fp_get( s );
304
 
305
    if( fp == NULL )
306
        FILEIO_RETURN(EBADF);
307
 
308
    if( fp->f_type == CYG_FILE_TYPE_SOCKET )
309
    {
310
        cyg_sock_ops *ops = (cyg_sock_ops *)fp->f_xops;
311
 
312
        LOCK_SOCKET( fp );
313
 
314
        ret = ops->connect( fp, sa, len );
315
 
316
        UNLOCK_SOCKET( fp );
317
 
318
    }
319
 
320
    cyg_fp_free( fp );
321
 
322
    SOCKET_RETURN(ret);
323
}
324
 
325
 
326
// -------------------------------------------------------------------------
327
 
328
__externC int   getpeername (int s, struct sockaddr *sa, socklen_t *len)
329
{
330
    SOCKET_ENTRY();
331
 
332
    int ret = 0;
333
    cyg_file *fp;
334
 
335
    fp = cyg_fp_get( s );
336
 
337
    if( fp == NULL )
338
        FILEIO_RETURN(EBADF);
339
 
340
    if( fp->f_type == CYG_FILE_TYPE_SOCKET )
341
    {
342
        cyg_sock_ops *ops = (cyg_sock_ops *)fp->f_xops;
343
 
344
        LOCK_SOCKET( fp );
345
 
346
        ret = ops->getname( fp, sa, len, 1 );
347
 
348
        UNLOCK_SOCKET( fp );
349
    }
350
 
351
    cyg_fp_free( fp );
352
 
353
    SOCKET_RETURN(ret);
354
}
355
 
356
 
357
// -------------------------------------------------------------------------
358
 
359
__externC int   getsockname (int s, struct sockaddr *sa, socklen_t *len)
360
{
361
    SOCKET_ENTRY();
362
 
363
    int ret = 0;
364
    cyg_file *fp;
365
 
366
    fp = cyg_fp_get( s );
367
 
368
    if( fp == NULL )
369
        FILEIO_RETURN(EBADF);
370
 
371
    if( fp->f_type == CYG_FILE_TYPE_SOCKET )
372
    {
373
        cyg_sock_ops *ops = (cyg_sock_ops *)fp->f_xops;
374
 
375
        LOCK_SOCKET( fp );
376
 
377
        ret = ops->getname( fp, sa, len, 0 );
378
 
379
        UNLOCK_SOCKET( fp );
380
    }
381
 
382
    cyg_fp_free( fp );
383
 
384
    SOCKET_RETURN(ret);
385
}
386
 
387
 
388
// -------------------------------------------------------------------------
389
 
390
__externC int   getsockopt (int s, int level, int optname, void *optval, socklen_t *optlen)
391
{
392
    SOCKET_ENTRY();
393
 
394
    int ret = 0;
395
    cyg_file *fp;
396
 
397
    fp = cyg_fp_get( s );
398
 
399
    if( fp == NULL )
400
        FILEIO_RETURN(EBADF);
401
 
402
    if( fp->f_type == CYG_FILE_TYPE_SOCKET )
403
    {
404
        cyg_sock_ops *ops = (cyg_sock_ops *)fp->f_xops;
405
 
406
        LOCK_SOCKET( fp );
407
 
408
        ret = ops->getsockopt( fp, level, optname, optval, optlen );
409
 
410
        UNLOCK_SOCKET( fp );
411
    }
412
 
413
    cyg_fp_free( fp );
414
 
415
    SOCKET_RETURN(ret);
416
}
417
 
418
 
419
// -------------------------------------------------------------------------
420
 
421
__externC int   listen (int s, int len)
422
{
423
    SOCKET_ENTRY();
424
 
425
    int ret = 0;
426
    cyg_file *fp;
427
 
428
    fp = cyg_fp_get( s );
429
 
430
    if( fp == NULL )
431
        FILEIO_RETURN(EBADF);
432
 
433
    if( fp->f_type == CYG_FILE_TYPE_SOCKET )
434
    {
435
        cyg_sock_ops *ops = (cyg_sock_ops *)fp->f_xops;
436
 
437
        LOCK_SOCKET( fp );
438
 
439
        ret = ops->listen( fp, len );
440
 
441
        UNLOCK_SOCKET( fp );
442
    }
443
 
444
    cyg_fp_free( fp );
445
 
446
    SOCKET_RETURN(ret);
447
}
448
 
449
 
450
// -------------------------------------------------------------------------
451
 
452
__externC ssize_t recvmsg (int s, struct msghdr *msg, int flags)
453
{
454
    SOCKET_ENTRY();
455
 
456
    ssize_t ret = 0;
457
    int error = 0;
458
    cyg_file *fp;
459
 
460
    fp = cyg_fp_get( s );
461
 
462
    if( fp == NULL )
463
        FILEIO_RETURN(EBADF);
464
 
465
    if( fp->f_type == CYG_FILE_TYPE_SOCKET )
466
    {
467
        cyg_sock_ops *ops = (cyg_sock_ops *)fp->f_xops;
468
 
469
        LOCK_SOCKET( fp );
470
 
471
        msg->msg_flags = flags;
472
 
473
        error = ops->recvmsg( fp, msg, NULL, &ret );
474
 
475
        UNLOCK_SOCKET( fp );
476
    }
477
 
478
    cyg_fp_free( fp );
479
 
480
    if( error != ENOERR )
481
        SOCKET_RETURN(error);
482
 
483
    SOCKET_RETURN_VALUE( ret );
484
}
485
 
486
// -------------------------------------------------------------------------
487
 
488
__externC ssize_t recvfrom (int s, void *buf, size_t len, int flags,
489
                          struct sockaddr *from, socklen_t *fromlen)
490
{
491
    SOCKET_ENTRY();
492
 
493
    struct msghdr msg;
494
    struct iovec iov;
495
    ssize_t ret = 0;
496
    int error = 0;
497
    cyg_file *fp;
498
 
499
    fp = cyg_fp_get( s );
500
 
501
    if( fp == NULL )
502
        FILEIO_RETURN(EBADF);
503
 
504
    if( fp->f_type == CYG_FILE_TYPE_SOCKET )
505
    {
506
        cyg_sock_ops *ops = (cyg_sock_ops *)fp->f_xops;
507
 
508
        // Set up a message header...
509
        msg.msg_name = (caddr_t)from;
510
        msg.msg_namelen = fromlen ? *fromlen : 0;
511
        msg.msg_iov = &iov;
512
        msg.msg_iovlen = 1;
513
        iov.iov_base = buf;
514
        iov.iov_len = len;
515
        msg.msg_control = 0;
516
        msg.msg_flags = flags;
517
 
518
        LOCK_SOCKET( fp );
519
 
520
        error = ops->recvmsg( fp, &msg, fromlen, &ret );
521
 
522
        UNLOCK_SOCKET( fp );
523
    }
524
 
525
    cyg_fp_free( fp );
526
 
527
    if( error != ENOERR )
528
        SOCKET_RETURN(error);
529
 
530
    SOCKET_RETURN_VALUE( ret );
531
 
532
}
533
 
534
// -------------------------------------------------------------------------
535
 
536
__externC ssize_t recv (int s, void *buf, size_t len, int flags)
537
{
538
    return recvfrom( s, buf, len, flags, NULL, NULL );
539
}
540
 
541
// -------------------------------------------------------------------------
542
 
543
__externC ssize_t sendmsg (int s, const struct msghdr *msg, int flags)
544
{
545
    SOCKET_ENTRY();
546
 
547
    ssize_t ret = 0;
548
    int error = 0;
549
    cyg_file *fp;
550
 
551
    fp = cyg_fp_get( s );
552
 
553
    if( fp == NULL )
554
        FILEIO_RETURN(EBADF);
555
 
556
    if( fp->f_type == CYG_FILE_TYPE_SOCKET )
557
    {
558
        cyg_sock_ops *ops = (cyg_sock_ops *)fp->f_xops;
559
 
560
        LOCK_SOCKET( fp );
561
 
562
        error = ops->sendmsg( fp, msg, flags, &ret );
563
 
564
        UNLOCK_SOCKET( fp );
565
    }
566
 
567
    cyg_fp_free( fp );
568
 
569
    if( error != ENOERR )
570
        SOCKET_RETURN(error);
571
 
572
    SOCKET_RETURN_VALUE( ret );
573
}
574
 
575
 
576
// -------------------------------------------------------------------------
577
 
578
__externC ssize_t sendto (int s, const void *buf,
579
            size_t len, int flags, const struct sockaddr *to, socklen_t tolen)
580
{
581
    SOCKET_ENTRY();
582
 
583
    ssize_t ret = 0;
584
    int error = 0;
585
    cyg_file *fp;
586
 
587
    fp = cyg_fp_get( s );
588
 
589
    if( fp == NULL )
590
        FILEIO_RETURN(EBADF);
591
 
592
    if( fp->f_type == CYG_FILE_TYPE_SOCKET )
593
    {
594
        cyg_sock_ops *ops = (cyg_sock_ops *)fp->f_xops;
595
 
596
 
597
        struct msghdr msg;
598
        struct iovec iov;
599
 
600
        msg.msg_name = (caddr_t)to;
601
        msg.msg_namelen = tolen;
602
        msg.msg_iov = &iov;
603
        msg.msg_iovlen = 1;
604
        msg.msg_control = 0;
605
        msg.msg_flags = 0;
606
        iov.iov_base = (char *)buf;
607
        iov.iov_len = len;
608
 
609
        LOCK_SOCKET( fp );
610
 
611
        error = ops->sendmsg( fp, &msg, flags, &ret );
612
 
613
        UNLOCK_SOCKET( fp );
614
    }
615
 
616
    cyg_fp_free( fp );
617
 
618
    if( error != ENOERR )
619
        SOCKET_RETURN(error);
620
 
621
    SOCKET_RETURN_VALUE( ret );
622
}
623
 
624
// -------------------------------------------------------------------------
625
 
626
__externC ssize_t send (int s, const void *buf, size_t len, int flags)
627
{
628
    return sendto( s, buf, len, flags, NULL, 0 );
629
}
630
 
631
 
632
// -------------------------------------------------------------------------
633
 
634
__externC int   setsockopt (int s, int level, int optname,
635
                            const void *optval, socklen_t optlen)
636
{
637
    SOCKET_ENTRY();
638
 
639
    int ret = 0;
640
    cyg_file *fp;
641
 
642
    fp = cyg_fp_get( s );
643
 
644
    if( fp == NULL )
645
        FILEIO_RETURN(EBADF);
646
 
647
    if( fp->f_type == CYG_FILE_TYPE_SOCKET )
648
    {
649
        cyg_sock_ops *ops = (cyg_sock_ops *)fp->f_xops;
650
 
651
        LOCK_SOCKET( fp );
652
 
653
        ret = ops->setsockopt( fp, level, optname, optval, optlen );
654
 
655
        UNLOCK_SOCKET( fp );
656
    }
657
 
658
    cyg_fp_free( fp );
659
 
660
    SOCKET_RETURN(ret);
661
}
662
 
663
// -------------------------------------------------------------------------
664
 
665
__externC int   shutdown (int s, int how)
666
{
667
    SOCKET_ENTRY();
668
 
669
    int ret = 0;
670
    cyg_file *fp;
671
 
672
    fp = cyg_fp_get( s );
673
 
674
    if( fp == NULL )
675
        FILEIO_RETURN(EBADF);
676
 
677
    if( fp->f_type == CYG_FILE_TYPE_SOCKET )
678
    {
679
        cyg_sock_ops *ops = (cyg_sock_ops *)fp->f_xops;
680
 
681
        LOCK_SOCKET( fp );
682
 
683
        ret = ops->shutdown( fp, how );
684
 
685
        UNLOCK_SOCKET( fp );
686
    }
687
 
688
    cyg_fp_free( fp );
689
 
690
    SOCKET_RETURN(ret);
691
}
692
 
693
//==========================================================================
694
// Locking protocol
695
 
696
static void cyg_ns_lock( cyg_nstab_entry *ns )
697
{
698
    if( ns->syncmode & CYG_SYNCMODE_SOCK_NETSTACK )
699
    {
700
        nstab_lock[ns-&cyg_nstab[0]].lock();
701
    }
702
}
703
 
704
static void cyg_ns_unlock( cyg_nstab_entry *ns )
705
{
706
    if( ns->syncmode & CYG_SYNCMODE_SOCK_NETSTACK )
707
    {
708
        nstab_lock[ns-&cyg_nstab[0]].unlock();
709
    }
710
}
711
 
712
static void cyg_sock_lock( cyg_file *fp )
713
{
714
    cyg_nstab_entry *ns = (cyg_nstab_entry *)fp->f_mte;
715
 
716
    if( fp->f_syncmode & CYG_SYNCMODE_SOCK_NETSTACK )
717
        nstab_lock[ns-&cyg_nstab[0]].lock();
718
 
719
    cyg_file_lock( fp, fp->f_syncmode>>CYG_SYNCMODE_SOCK_SHIFT);
720
}
721
 
722
static void cyg_sock_unlock( cyg_file *fp )
723
{
724
    cyg_nstab_entry *ns = (cyg_nstab_entry *)fp->f_mte;
725
 
726
    if( fp->f_syncmode & CYG_SYNCMODE_SOCK_NETSTACK )
727
        nstab_lock[ns-&cyg_nstab[0]].unlock();
728
 
729
    cyg_file_unlock( fp, fp->f_syncmode>>CYG_SYNCMODE_SOCK_SHIFT);
730
}
731
 
732
 
733
// -------------------------------------------------------------------------
734
// EOF socket.cxx

powered by: WebSVN 2.1.0

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