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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [packages/] [io/] [fileio/] [v2_0/] [src/] [socket.cxx] - Blame information for rev 307

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

Line No. Rev Author Line
1 27 unneback
//==========================================================================
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 Red Hat, 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 version.
16
//
17
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
18
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
19
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
20
// for more details.
21
//
22
// You should have received a copy of the GNU General Public License along
23
// with eCos; if not, write to the Free Software Foundation, Inc.,
24
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
25
//
26
// As a special exception, if other files instantiate templates or use macros
27
// or inline functions from this file, or you compile this file and link it
28
// with other works to produce a work based on this file, this file does not
29
// by itself cause the resulting work to be covered by the GNU General Public
30
// License. However the source code for this file must still be made available
31
// in accordance with section (3) of the GNU General Public License.
32
//
33
// This exception does not invalidate any other reasons why a work based on
34
// this file might be covered by the GNU General Public License.
35
//
36
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
37
// at http://sources.redhat.com/ecos/ecos-license/
38
// -------------------------------------------
39
//####ECOSGPLCOPYRIGHTEND####
40
//==========================================================================
41
//#####DESCRIPTIONBEGIN####
42
//
43
// Author(s):           nickg
44
// Contributors:        nickg
45
// Date:                2000-05-25
46
// Purpose:             Fileio socket operations
47
// Description:         These are the functions that operate on sockets,
48
//                      such as socket(), bind(), accept() etc.
49
//              
50
//              
51
//
52
//####DESCRIPTIONEND####
53
//
54
//==========================================================================
55
 
56
#include <pkgconf/system.h>
57
#include <pkgconf/hal.h>
58
#include <pkgconf/kernel.h>
59
#include <pkgconf/io_fileio.h>
60
 
61
#include <cyg/hal/hal_tables.h>
62
 
63
#include <cyg/kernel/ktypes.h>         // base kernel types
64
#include <cyg/infra/cyg_trac.h>        // tracing macros
65
#include <cyg/infra/cyg_ass.h>         // assertion macros
66
 
67
#include <stdarg.h>                     // for fcntl()
68
 
69
#include <cyg/io/file.h>                // struct iovec
70
 
71
#include "fio.h"                       // Private header
72
 
73
#include <cyg/kernel/mutex.hxx>        // mutex definitions
74
 
75
#ifdef CYGPKG_NET
76
 
77
#include <sys/socket.h>                 // struct msghdr
78
 
79
#endif
80
 
81
//==========================================================================
82
// Forward definitions
83
 
84
static void cyg_ns_lock( cyg_nstab_entry *ns );
85
static void cyg_ns_unlock( cyg_nstab_entry *ns );
86
static void cyg_sock_lock( cyg_file *fp );
87
static void cyg_sock_unlock( cyg_file *fp );
88
 
89
//==========================================================================
90
// Local entry/return macros
91
 
92
#define SOCKET_ENTRY() FILEIO_ENTRY()
93
 
94
#define SOCKET_RETURN(err) FILEIO_RETURN(err)
95
 
96
#define SOCKET_RETURN_VALUE(val) FILEIO_RETURN_VALUE(val)
97
 
98
//==========================================================================
99
// Locking protocols
100
 
101
#define LOCK_NS( _n ) cyg_ns_lock( _n )
102
 
103
#define UNLOCK_NS( _n ) cyg_ns_unlock( _n )
104
 
105
#define LOCK_SOCKET( _fp ) cyg_sock_lock( _fp )
106
 
107
#define UNLOCK_SOCKET( _fp ) cyg_sock_unlock( _fp )
108
 
109
//==========================================================================
110
// Tables and local variables
111
 
112
// Array of network stacks installed
113
__externC cyg_nstab_entry nstab[];
114
CYG_HAL_TABLE_BEGIN( nstab, nstab );
115
 
116
// End of array marker
117
__externC cyg_nstab_entry nstab_end;
118
CYG_HAL_TABLE_END( nstab_end, nstab );
119
 
120
Cyg_Mutex nstab_lock[CYGNUM_FILEIO_NSTAB_MAX];
121
 
122
//==========================================================================
123
// Initialization
124
 
125
__externC void cyg_nstab_init()
126
{
127
    cyg_nstab_entry *n;
128
 
129
    for( n = &nstab[0]; n != &nstab_end; n++ )
130
    {
131
        // stop if there are more than the configured maximum
132
        if( n-&nstab[0] >= CYGNUM_FILEIO_NSTAB_MAX )
133
            break;
134
 
135
        if( n->init( n ) == 0 )
136
        {
137
            n->valid = true;
138
        }
139
    }
140
}
141
 
142
//==========================================================================
143
// Socket API calls
144
 
145
// -------------------------------------------------------------------------
146
 
147
__externC int   socket (int domain, int type, int protocol)
148
{
149
    SOCKET_ENTRY();
150
 
151
    int err = 0;
152
    int fd;
153
    cyg_file *file;
154
 
155
    fd = cyg_fd_alloc(0);
156
 
157
    if( fd < 0 )
158
        SOCKET_RETURN(EMFILE);
159
 
160
    file = cyg_file_alloc();
161
 
162
    if( file == NULL )
163
    {
164
        cyg_fd_free(fd);
165
        SOCKET_RETURN(ENFILE);
166
    }
167
 
168
    cyg_nstab_entry *n;
169
 
170
    for( n = &nstab[0]; n != &nstab_end; n++ )
171
    {
172
        LOCK_NS( n );
173
 
174
        err = n->socket( n, domain, type, protocol, file );
175
 
176
        UNLOCK_NS( n );
177
 
178
        if( err == 0 ) break;
179
    }
180
 
181
    if( err != 0 )
182
    {
183
        cyg_fd_free(fd);
184
        cyg_file_free(file);
185
        SOCKET_RETURN( err );
186
    }
187
 
188
    file->f_syncmode = n->syncmode;
189
    file->f_mte = (cyg_mtab_entry *)n;
190
 
191
    cyg_fd_assign( fd, file );
192
 
193
    SOCKET_RETURN_VALUE(fd);
194
}
195
 
196
 
197
// -------------------------------------------------------------------------
198
 
199
__externC int   accept (int s, struct sockaddr *sa, socklen_t *addrlen)
200
{
201
    SOCKET_ENTRY();
202
 
203
    int err = 0;
204
    int fd;
205
    cyg_file *fp;
206
    cyg_file *new_fp;
207
 
208
    fp = cyg_fp_get( s );
209
 
210
    if( fp == NULL )
211
        FILEIO_RETURN(EBADF);
212
 
213
    fd = cyg_fd_alloc(0);
214
 
215
    if( fd < 0 )
216
    {
217
        cyg_fp_free( fp );
218
        SOCKET_RETURN(EMFILE);
219
    }
220
 
221
    new_fp = cyg_file_alloc();
222
 
223
    if( new_fp == NULL )
224
    {
225
        cyg_fp_free( fp );
226
        cyg_fd_free(fd);
227
        SOCKET_RETURN(ENFILE);
228
    }
229
 
230
    if( fp->f_type == CYG_FILE_TYPE_SOCKET )
231
    {
232
        cyg_sock_ops *ops = (cyg_sock_ops *)fp->f_xops;
233
 
234
        LOCK_SOCKET( fp );
235
 
236
        err = ops->accept( fp, new_fp, sa, addrlen );
237
 
238
        UNLOCK_SOCKET( fp );
239
 
240
    }
241
    else err = EBADF;
242
 
243
    if( err != 0 )
244
    {
245
        cyg_fp_free( fp );
246
        cyg_fd_free(fd);
247
        cyg_file_free(new_fp);
248
        SOCKET_RETURN( err );
249
    }
250
 
251
    new_fp->f_syncmode = fp->f_syncmode;
252
    new_fp->f_mte = fp->f_mte;
253
 
254
    cyg_fd_assign( fd, new_fp );
255
 
256
    cyg_fp_free( fp );
257
 
258
    SOCKET_RETURN_VALUE(fd);
259
}
260
 
261
 
262
// -------------------------------------------------------------------------
263
 
264
__externC int   bind (int s, const struct sockaddr *sa, unsigned int len)
265
{
266
    SOCKET_ENTRY();
267
 
268
    int ret = 0;
269
    cyg_file *fp;
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, sa, 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-&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-&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-&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-&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.