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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [rtos/] [rtems/] [c/] [src/] [libnetworking/] [rtems_webserver/] [socket.c] - Blame information for rev 373

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

Line No. Rev Author Line
1 30 unneback
/*
2
 * socket.c -- Socket support module for UNIX
3
 *
4
 * Copyright (c) Go Ahead, 1995-1999
5
 */
6
 
7
/******************************** Description *********************************/
8
 
9
/*
10
 *      SCO Unix Socket Module.  This supports non-blocking buffered socket I/O.
11
 */
12
 
13
/********************************** Includes **********************************/
14
 
15
#include        <errno.h>
16
#include        <fcntl.h>
17
#include        <string.h>
18
#include        <stdlib.h>
19
#include        <unistd.h>
20
 
21
#if __rtems__
22
#include        <sys/select.h>
23
#endif
24
 
25
#include        "uemf.h"
26
 
27
/*********************************** Defines **********************************/
28
 
29
typedef struct {
30
        char                    host[64];                               /* Host name */
31
        ringq_t                 inBuf;                                  /* Input ring queue */
32
        ringq_t                 outBuf;                                 /* Output ring queue */
33
        ringq_t                 lineBuf;                                /* Line ring queue */
34
        socketAccept_t  accept;                                 /* Accept handler */
35
        socketHandler_t handler;                                /* User I/O handler */
36
        int                             handler_data;                   /* User handler data */
37
        int                             sid;                                    /* Index into socket[] */
38
        int                             port;                                   /* Port to listen on */
39
        int                             flags;                                  /* Current state flags */
40
        int                             readyMask;                              /* Events now ready */
41
        int                             interestMask;                   /* Events interest */
42
        int                             error;                                  /* Last error */
43
        int                             sock;                                   /* Actual socket handle */
44
} socket_t;
45
 
46
/************************************ Locals **********************************/
47
 
48
static socket_t**       socketList;                             /* List of open sockets */
49
static int                      socketMax;                              /* Maximum size of socket */
50
static int                      socketHighestFd = -1;   /* Highest socket fd opened */
51
 
52
/***************************** Forward Declarations ***************************/
53
 
54
static int      socketAlloc(char* host, int port, socketAccept_t accept, int flags);
55
static void socketFree(int sid);
56
static void socketAccept(socket_t* sp);
57
static int      socketGetInput(int sid, char* buf, int toRead, int* errCode);
58
static int      socketDoOutput(socket_t* sp, char* buf, int toWrite, int* errCode);
59
static int      socketDoEvent(socket_t *sp);
60
static int      socketGetError();
61
static int      socketWaitForEvent(socket_t* sp, int events, int* errCode);
62
static int      socketNonBlock(socket_t *sp);
63
static socket_t* socketPtr(int sid);
64
 
65
/*********************************** Code *************************************/
66
/*
67
 *      Open socket module
68
 */
69
 
70
int socketOpen()
71
{
72
        return 0;
73
}
74
 
75
/******************************************************************************/
76
/*
77
 *      Close the socket module, by closing all open connections
78
 */
79
 
80
void socketClose()
81
{
82
        int             i;
83
 
84
        for (i = socketMax; i >= 0; i--) {
85
                if (socketList && socketList[i]) {
86
                        socketCloseConnection(i);
87
                }
88
        }
89
}
90
 
91
/******************************************************************************/
92
/*
93
 *      Open a client or server socket. Host is NULL if we want server capability.
94
 */
95
 
96
int socketOpenConnection(char* host, int port, socketAccept_t accept, int flags)
97
{
98
        socket_t                        *sp;
99
        struct sockaddr_in      sockaddr;
100
        struct hostent          *hostent;               /* Host database entry */
101
        int                                     sid, rc;
102
 
103
/*
104
 *      Allocate a socket structure
105
 */
106
        if ((sid = socketAlloc(host, port, accept, flags)) < 0) {
107
                return -1;
108
        }
109
        sp = socketList[sid];
110
        a_assert(sp);
111
 
112
/*
113
 *      Create the socket address structure
114
 */
115
        memset((char *) &sockaddr, '\0', sizeof(struct sockaddr_in));
116
        sockaddr.sin_family = AF_INET;
117
        sockaddr.sin_port = htons((short) (port & 0xFFFF));
118
 
119
        if (host == NULL) {
120
                sockaddr.sin_addr.s_addr = INADDR_ANY;
121
        } else {
122
                sockaddr.sin_addr.s_addr = inet_addr(host);
123
                if (sockaddr.sin_addr.s_addr == INADDR_NONE) {
124
                        hostent = gethostbyname(host);
125
                        if (hostent != NULL) {
126
                                memcpy((char *) &sockaddr.sin_addr,
127
                                        (char *) hostent->h_addr_list[0],
128
                                        (size_t) hostent->h_length);
129
                        } else {
130
                                errno = ENXIO;
131
                                socketFree(sid);
132
                                return -1;
133
                        }
134
                }
135
        }
136
 
137
/*
138
 *      Create the socket. Set the close on exec flag so children don't
139
 *      inherit the socket.
140
 */
141
        sp->sock = socket(AF_INET, SOCK_STREAM, 0);
142
        if (sp->sock < 0) {
143
                socketFree(sid);
144
                return -1;
145
        }
146
        fcntl(sp->sock, F_SETFD, FD_CLOEXEC);
147
        socketHighestFd = max(socketHighestFd, sp->sock);
148
 
149
/*
150
 *      Host is set if we are the client
151
 */
152
        if (host) {
153
/*
154
 *              Connect to the remote server
155
 */
156
                if (connect(sp->sock, (struct sockaddr *) &sockaddr,
157
                                sizeof(sockaddr)) < 0) {
158
                        socketFree(sid);
159
                        return -1;
160
                }
161
                socketNonBlock(sp);
162
 
163
        } else {
164
/*
165
 *              Bind to the socket endpoint with resule and the call listen()
166
 **             to start listening
167
 */
168
                rc = 1;
169
                setsockopt(sp->sock, SOL_SOCKET, SO_REUSEADDR, (char *)&rc, sizeof(rc));
170
                if (bind(sp->sock, (struct sockaddr *) &sockaddr, sizeof(sockaddr))
171
                                < 0) {
172
                        socketFree(sid);
173
                        return -1;
174
                }
175
                sp->flags |= SOCKET_LISTENING;
176
 
177
                if (listen(sp->sock, SOMAXCONN) < 0) {
178
                        socketFree(sid);
179
                        return -1;
180
                }
181
                sp->interestMask = SOCKET_READABLE;
182
        }
183
        return sid;
184
}
185
 
186
/******************************************************************************/
187
/*
188
 *      Close a socket
189
 */
190
 
191
void socketCloseConnection(int sid)
192
{
193
        socket_t*       sp;
194
 
195
        if ((sp = socketPtr(sid)) == NULL) {
196
                return;
197
        }
198
 
199
/*
200
 *      We always flush all output before closing. Unlink from the emf event
201
 *      mechanism and then free (and close) the connection
202
 */
203
        socketFlush(sid, 1);
204
        socketFree(sid);
205
}
206
 
207
/******************************************************************************/
208
/*
209
 *      Accept a connection. Called by socketDoEvent
210
 */
211
 
212
static void socketAccept(socket_t* sp)
213
{
214
        struct sockaddr_in      addr;
215
        socket_t                        *nsp;
216
        int                             len;
217
        int                             newSock, nid;
218
 
219
        a_assert(sp);
220
 
221
/*
222
 *      Accept the connection and prevent inheriting by children (F_SETFD)
223
 */
224
        len = sizeof(struct sockaddr_in);
225
        if ((newSock = accept(sp->sock, (struct sockaddr *) &addr, &len)) < 0) {
226
                return;
227
        }
228
        fcntl(newSock, F_SETFD, FD_CLOEXEC);
229
        socketHighestFd = max(socketHighestFd, newSock);
230
 
231
/*
232
 *      Create a socket structure and insert into the socket list
233
 */
234
        nid = socketAlloc(sp->host, sp->port, sp->accept, 0);
235
        nsp = socketList[nid];
236
        a_assert(nsp);
237
        nsp->sock = newSock;
238
 
239
        if (nsp == NULL) {
240
                return;
241
        }
242
/*
243
 *      Call the user accept callback, the user must call socketCreateHandler
244
 *      to register for further events of interest.
245
 */
246
        if (sp->accept != NULL) {
247
                if ((sp->accept)(nid, inet_ntoa(addr.sin_addr),
248
                                ntohs(addr.sin_port)) < 0) {
249
                        socketFree(nid);
250
                        return;
251
                }
252
        }
253
        socketNonBlock(nsp);
254
}
255
 
256
/******************************************************************************/
257
/*
258
 *      Write to a socket. This may block if the underlying socket cannot
259
 *      absorb the data. Returns -1 on error, otherwise the number of bytes
260
 *      written.
261
 */
262
 
263
int     socketWrite(int sid, char* buf, int bufsize)
264
{
265
        socket_t*       sp;
266
        ringq_t*        rq;
267
        int                     len, bytesWritten, room;
268
 
269
        a_assert(buf);
270
        a_assert(bufsize >= 0);
271
 
272
        if ((sp = socketPtr(sid)) == NULL) {
273
                return -1;
274
        }
275
 
276
/*
277
 *      Loop adding as much data to the output ringq as we can absorb
278
 *      Flush when the ringq is too full and continue.
279
 */
280
        rq = &sp->outBuf;
281
        for (bytesWritten = 0; bufsize > 0; ) {
282
                if ((room = ringqPutBlkMax(rq)) == 0) {
283
                        if (socketFlush(sid, 0) < 0) {
284
                                return -1;
285
                        }
286
                        if ((room = ringqPutBlkMax(rq)) == 0) {
287
                                break;
288
                        }
289
                        continue;
290
                }
291
                len = min(room, bufsize);
292
                ringqPutBlk(rq, (unsigned char*) buf, len);
293
                bytesWritten += len;
294
                bufsize -= len;
295
                buf += len;
296
        }
297
        return bytesWritten;
298
}
299
 
300
/******************************************************************************/
301
/*
302
 *      Read from a socket. Return the number of bytes read if successful. This
303
 *      may be less than the requested "bufsize" and may be zero. Return -1 for
304
 *      errors. Return 0 for EOF. Otherwise return the number of bytes read. Since
305
 *      this may be zero, callers should use socketEof() to distinguish between
306
 *      this and EOF. Note: this ignores the line buffer, so a previous socketGets
307
 *      which read a partial line may cause a subsequent socketRead to miss
308
 *      some data.
309
 */
310
 
311
int     socketRead(int sid, char* buf, int bufsize)
312
{
313
        socket_t*       sp;
314
        ringq_t*        rq;
315
        int                     len, room, errCode, bytesRead;
316
 
317
        a_assert(buf);
318
        a_assert(bufsize > 0);
319
 
320
        if ((sp = socketPtr(sid)) == NULL) {
321
                return -1;
322
        }
323
 
324
        if (sp->flags & SOCKET_EOF) {
325
                return 0;
326
        }
327
 
328
        rq = &sp->inBuf;
329
        for (bytesRead = 0; bufsize > 0; ) {
330
                len = min(ringqLen(rq), bufsize);
331
                if (len <= 0) {
332
                        room = ringqPutBlkMax(rq);
333
                        len = socketGetInput(sid, (char*) rq->endp, room, &errCode);
334
                        if (len < 0) {
335
                                if (errCode == EWOULDBLOCK) {
336
                                        if (bytesRead >= 0) {
337
                                                return bytesRead;
338
                                        }
339
                                }
340
                                return -1;
341
 
342
                        } else if (len == 0) {
343
/*
344
 *                              This is EOF, but we may have already read some data so pass that
345
 *                              back first before notifying EOF. The next read will return 0
346
 *                              to indicate EOF.
347
 */
348
                                return bytesRead;
349
                        }
350
                        ringqPutBlkAdj(rq, len);
351
                        len = min(len, bufsize);
352
                }
353
                memcpy(&buf[bytesRead], rq->servp, len);
354
                ringqGetBlkAdj(rq, len);
355
                bufsize -= len;
356
                bytesRead += len;
357
        }
358
        return bytesRead;
359
}
360
 
361
/******************************************************************************/
362
/*
363
 *      Get a string from a socket. This returns data in *buf in a malloced string
364
 *      after trimming the '\n'. If there is zero bytes returned, *buf will be set
365
 *      to NULL. It returns -1 for error, EOF or when no complete line yet read.
366
 *      Otherwise the length of the line is returned. If a partial line is read
367
 *      socketInputBuffered or socketEof can be used to distinguish between EOF
368
 *      and partial line still buffered. This routine eats and ignores carriage
369
 *  returns.
370
 */
371
 
372
int     socketGets(int sid, char** buf)
373
{
374
        socket_t*       sp;
375
        ringq_t*        lq;
376
        char            c;
377
        int                     rc, len;
378
 
379
        a_assert(buf);
380
 
381
        if ((sp = socketPtr(sid)) == NULL) {
382
                return -1;
383
        }
384
        lq = &sp->lineBuf;
385
 
386
        while (1) {
387
 
388
                if ((rc = socketRead(sid, &c, 1)) < 0) {
389
                        return rc;
390
 
391
                } else if (rc == 0) {
392
/*
393
 *                      If there is a partial line and we are at EOF, pretend we saw a '\n'
394
 */
395
                        if (ringqLen(lq) > 0 && (sp->flags & SOCKET_EOF)) {
396
                                c = '\n';
397
                        } else {
398
                                return -1;
399
                        }
400
                }
401
/*
402
 *              If a newline is seen, return the data excluding the new line to the
403
 *              caller. If carriage return is seen, just eat it.
404
 */
405
                if (c == '\n') {
406
                        len = ringqLen(lq);
407
                        if (len > 0) {
408
                                if ((*buf = balloc(B_L, len + 1)) == NULL) {
409
                                        return -1;
410
                                }
411
                                memset(*buf, 0, len + 1);
412
                                ringqGetBlk(lq, (unsigned char*) *buf, len);
413
                        } else {
414
                                *buf = NULL;
415
                        }
416
                        return len;
417
 
418
                } else if (c == '\r') {
419
                        continue;
420
                }
421
                ringqPutc(lq, c);
422
        }
423
}
424
 
425
/******************************************************************************/
426
/*
427
 *      Flush a socket. Do not wait, just initiate output and return.
428
 *      This will return -1 on errors and 0 if successful.
429
 */
430
 
431
int socketFlush(int sid, int block)
432
{
433
        socket_t*       sp;
434
        ringq_t*        rq;
435
        int                     len, bytesWritten, errCode;
436
 
437
        a_assert(block == 0 || block == 1);
438
 
439
        if ((sp = socketPtr(sid)) == NULL) {
440
                return -1;
441
        }
442
        rq = &sp->outBuf;
443
 
444
/*
445
 *      Set the background flushing flag which socketDoEvent will check to
446
 *      continue the flush.
447
 */
448
        if (!block) {
449
                sp->flags |= SOCKET_FLUSHING;
450
        }
451
 
452
/*
453
 *      Break from loop if not blocking after initiating output. If we are blocking
454
 *      we wait for a write event.
455
 */
456
        while (ringqLen(rq) > 0) {
457
                len = ringqGetBlkMax(&sp->outBuf);
458
                bytesWritten = socketDoOutput(sp, (char*) rq->servp, len, &errCode);
459
                if (bytesWritten < 0) {
460
                        if (errCode == EINTR) {
461
                                continue;
462
                        } else if (errCode == EWOULDBLOCK || errCode == EAGAIN) {
463
                                if (! block) {
464
                                        return 0;
465
                                }
466
                                if (socketWaitForEvent(sp, SOCKET_WRITABLE | SOCKET_EXCEPTION,
467
                                                &errCode)) {
468
                                        continue;
469
                                }
470
                        }
471
                        return -1;
472
                }
473
                ringqGetBlkAdj(rq, bytesWritten);
474
                if (! block) {
475
                        break;
476
                }
477
        }
478
        return 0;
479
}
480
 
481
/******************************************************************************/
482
/*
483
 *      Return the count of input characters buffered. We look at both the line
484
 *      buffer and the input (raw) buffer. Return -1 on error or EOF.
485
 */
486
 
487
int socketInputBuffered(int sid)
488
{
489
        socket_t*       sp;
490
 
491
        if ((sp = socketPtr(sid)) == NULL) {
492
                return -1;
493
        }
494
        if (socketEof(sid)) {
495
                return -1;
496
        }
497
        return ringqLen(&sp->lineBuf) + ringqLen(&sp->inBuf);
498
}
499
 
500
/******************************************************************************/
501
/*
502
 *      Return true if EOF
503
 */
504
 
505
int socketEof(int sid)
506
{
507
        socket_t*       sp;
508
 
509
        if ((sp = socketPtr(sid)) == NULL) {
510
                return -1;
511
        }
512
        return sp->flags & SOCKET_EOF;
513
}
514
 
515
/******************************************************************************/
516
/*
517
 *      Create a user handler for this socket. The handler called whenever there
518
 *      is an event of interest as defined by interestMask (SOCKET_READABLE, ...)
519
 */
520
 
521
void socketCreateHandler(int sid, int interestMask, socketHandler_t handler,
522
        int data)
523
{
524
        socket_t*       sp;
525
 
526
        if ((sp = socketPtr(sid)) == NULL) {
527
                return;
528
        }
529
        sp->handler = handler;
530
        sp->handler_data = data;
531
        sp->interestMask = interestMask;
532
}
533
 
534
/******************************************************************************/
535
/*
536
 *      Delete a handler
537
 */
538
 
539
void socketDeleteHandler(int sid)
540
{
541
        socket_t*       sp;
542
 
543
        if ((sp = socketPtr(sid)) == NULL) {
544
                return;
545
        }
546
        sp->handler = NULL;
547
        sp->interestMask = 0;
548
}
549
 
550
/******************************************************************************/
551
/*
552
 *      Get more input from the socket and return in buf.
553
 *      Returns 0 for EOF, -1 for errors and otherwise the number of bytes read.
554
 */
555
 
556
static int socketGetInput(int sid, char* buf, int toRead, int* errCode)
557
{
558
        struct sockaddr_in      server;
559
        socket_t*                       sp;
560
        int                             len, bytesRead;
561
 
562
        a_assert(buf);
563
        a_assert(errCode);
564
 
565
        *errCode = 0;
566
 
567
        if ((sp = socketPtr(sid)) == NULL) {
568
                return -1;
569
        }
570
 
571
/*
572
 *      If we have previously seen an EOF condition, then just return
573
 */
574
        if (sp->flags & SOCKET_EOF) {
575
                return 0;
576
        }
577
 
578
/*
579
 *      Read the data
580
 */
581
        if (sp->flags & SOCKET_BROADCAST) {
582
                server.sin_family = AF_INET;
583
                server.sin_addr.s_addr = INADDR_BROADCAST;
584
                server.sin_port = htons((short)(sp->port & 0xFFFF));
585
                len = sizeof(server);
586
                bytesRead = recvfrom(sp->sock, buf, toRead, 0,
587
                        (struct sockaddr*) &server, &len);
588
        } else {
589
                bytesRead = recv(sp->sock, buf, toRead, 0);
590
        }
591
 
592
        if (bytesRead < 0) {
593
                if (errno == ECONNRESET) {
594
                        return 0;
595
                }
596
                *errCode = socketGetError();
597
                return -1;
598
 
599
        } else if (bytesRead == 0) {
600
                sp->flags |= SOCKET_EOF;
601
        }
602
        return bytesRead;
603
}
604
 
605
/******************************************************************************/
606
/*
607
 *      Socket output procedure. Return -1 on errors otherwise return the number
608
 *      of bytes written.
609
 */
610
 
611
static int socketDoOutput(socket_t* sp, char* buf, int toWrite, int* errCode)
612
{
613
        struct sockaddr_in      server;
614
        int                             bytes;
615
 
616
        a_assert(sp);
617
        a_assert(buf);
618
        a_assert(toWrite > 0);
619
        a_assert(errCode);
620
 
621
        *errCode = 0;
622
 
623
/*
624
 *      Write the data
625
 */
626
        if (sp->flags & SOCKET_BROADCAST) {
627
                server.sin_family = AF_INET;
628
                server.sin_addr.s_addr = INADDR_BROADCAST;
629
                server.sin_port = htons((short)(sp->port & 0xFFFF));
630
                bytes = sendto(sp->sock, buf, toWrite, 0,
631
                        (struct sockaddr*) &server, sizeof(server));
632
        } else {
633
                bytes = send(sp->sock, buf, toWrite, 0);
634
        }
635
 
636
        if (bytes == 0 && bytes != toWrite) {
637
                *errCode = EWOULDBLOCK;
638
                return -1;
639
        }
640
 
641
        if (bytes < 0) {
642
                *errCode = socketGetError();
643
        }
644
        return bytes;
645
}
646
 
647
/******************************************************************************/
648
/*
649
 *      Return TRUE if there is a socket with an event ready to process,
650
 */
651
 
652
int socketReady()
653
{
654
        socket_t        *sp;
655
        int                     i;
656
 
657
        for (i = 0; i < socketMax; i++) {
658
                if ((sp = socketList[i]) == NULL) {
659
                        continue;
660
                }
661
                if (sp->readyMask & sp->interestMask) {
662
                        return 1;
663
                }
664
        }
665
        return 0;
666
}
667
 
668
/******************************************************************************/
669
/*
670
 *      Wait for a handle to become readable or writable and return a number of
671
 *      noticed events.
672
 */
673
 
674
int socketSelect()
675
{
676
        socket_t        *sp;
677
        fd_mask         *readFds, *writeFds, *exceptFds;
678
        int             sid, len, nwords, index, bit, nEvents;
679
 
680
/*
681
 *      Allocate and zero the select masks
682
 */
683
        nwords = (socketHighestFd + NFDBITS - 1) / NFDBITS;
684
        len = nwords * sizeof(int);
685
 
686
        readFds = balloc(B_L, len);
687
        memset(readFds, 0, len);
688
        writeFds = balloc(B_L, len);
689
        memset(writeFds, 0, len);
690
        exceptFds = balloc(B_L, len);
691
        memset(exceptFds, 0, len);
692
 
693
/*
694
 *      Set the select event masks for events to watch
695
 */
696
        for (sid = 0; sid < socketMax; sid++) {
697
                if ((sp = socketList[sid]) == NULL) {
698
                        continue;
699
                }
700
                a_assert(sp);
701
 
702
/*
703
 *              Initialize the ready masks and compute the mask offsets.
704
 */
705
                index = sp->sock / (NBBY * sizeof(fd_mask));
706
                bit = 1 << (sp->sock % (NBBY * sizeof(fd_mask)));
707
 
708
/*
709
 *              Set the appropriate bit in the ready masks for the sp->sock.
710
 */
711
                if (sp->interestMask & SOCKET_READABLE) {
712
                        readFds[index] |= bit;
713
                }
714
                if (sp->interestMask & SOCKET_WRITABLE) {
715
                        writeFds[index] |= bit;
716
                }
717
                if (sp->interestMask & SOCKET_EXCEPTION) {
718
                        exceptFds[index] |= bit;
719
                }
720
        }
721
 
722
/*
723
 *      Wait for the event or a timeout.
724
 */
725
        nEvents = select(socketHighestFd + 1, (fd_set *) readFds,
726
                (fd_set *) writeFds, (fd_set *) exceptFds, NULL);
727
        if (nEvents > 0) {
728
                for (sid = 0; sid < socketMax; sid++) {
729
                        if ((sp = socketList[sid]) == NULL) {
730
                                continue;
731
                        }
732
 
733
                        index = sp->sock / (NBBY * sizeof(fd_mask));
734
                        bit = 1 << (sp->sock % (NBBY * sizeof(fd_mask)));
735
 
736
                        if (readFds[index] & bit) {
737
                                sp->readyMask |= SOCKET_READABLE;
738
                        }
739
                        if (writeFds[index] & bit) {
740
                                sp->readyMask |= SOCKET_WRITABLE;
741
                        }
742
                        if (exceptFds[index] & bit) {
743
                                sp->readyMask |= SOCKET_EXCEPTION;
744
                        }
745
                }
746
        }
747
 
748
        bfree(B_L, readFds);
749
        bfree(B_L, writeFds);
750
        bfree(B_L, exceptFds);
751
 
752
        return nEvents;
753
}
754
 
755
/******************************************************************************/
756
/*
757
 *      Process socket events
758
 */
759
 
760
void socketProcess()
761
{
762
        socket_t        *sp;
763
        int                     sid;
764
 
765
/*
766
 *      Process each socket
767
 */
768
        for (sid = 0; sid < socketMax; sid++) {
769
                if ((sp = socketList[sid]) == NULL) {
770
                        continue;
771
                }
772
                if ((sp->readyMask & sp->interestMask) ||
773
                                ((sp->interestMask & SOCKET_READABLE) &&
774
                                socketInputBuffered(sid))) {
775
                        socketDoEvent(sp);
776
                }
777
        }
778
}
779
 
780
/******************************************************************************/
781
/*
782
 *      Process and event on the event queue
783
 */
784
 
785
static int socketDoEvent(socket_t *sp)
786
{
787
        ringq_t*                rq;
788
        int                     sid;
789
 
790
        a_assert(sp);
791
 
792
    sid = sp->sid;
793
        if (sp->readyMask & SOCKET_READABLE) {
794
                if (sp->flags & SOCKET_LISTENING) {
795
                        socketAccept(sp);
796
                        sp->readyMask = 0;
797
                        return 1;
798
                }
799
        } else {
800
/*
801
 *              If there is still read data in the buffers, trigger the read handler
802
 *              NOTE: this may busy spin if the read handler doesn't read the data
803
 */
804
                if (sp->interestMask & SOCKET_READABLE && socketInputBuffered(sid)) {
805
                        sp->readyMask |= SOCKET_READABLE;
806
                }
807
        }
808
 
809
 
810
/*
811
 *      If now writable and flushing in the background, continue flushing
812
 */
813
        if (sp->readyMask & SOCKET_WRITABLE) {
814
                if (sp->flags & SOCKET_FLUSHING) {
815
                        rq = &sp->outBuf;
816
                        if (ringqLen(rq) > 0) {
817
                                socketFlush(sp->sid, 0);
818
                        } else {
819
                                sp->flags &= ~SOCKET_FLUSHING;
820
                        }
821
                }
822
        }
823
 
824
/*
825
 *      Now invoke the users socket handler. NOTE: the handler may delete the
826
 *      socket, so we must be very careful after calling the handler.
827
 */
828
        if (sp->handler && (sp->interestMask & sp->readyMask)) {
829
                (sp->handler)(sid, sp->interestMask & sp->readyMask,
830
                        sp->handler_data);
831
/*
832
 *              Make sure socket pointer is still valid, then set the readyMask
833
 *              to 0.
834
 */
835
                if (socketPtr(sid)) {
836
                        sp->readyMask = 0;
837
                }
838
        }
839
        return 1;
840
}
841
 
842
/******************************************************************************/
843
/*
844
 *      Allocate a new socket structure
845
 */
846
 
847
static int socketAlloc(char* host, int port, socketAccept_t accept, int flags)
848
{
849
        socket_t        *sp;
850
        int                     sid;
851
 
852
        if ((sid = hAlloc((void***) &socketList)) < 0) {
853
                return -1;
854
        }
855
        if ((sp = (socket_t*) balloc(B_L, sizeof(socket_t))) == NULL) {
856
                hFree((void***) &socket, sid);
857
                return -1;
858
        }
859
        memset(sp, 0, sizeof(socket_t));
860
        socketList[sid] = sp;
861
        if (sid >= socketMax)
862
                socketMax = sid + 1;
863
 
864
        sp->sid = sid;
865
        sp->accept = accept;
866
        sp->port = port;
867
        sp->flags = flags;
868
 
869
        if (host) {
870
                strncpy(sp->host, host, sizeof(sp->host));
871
        }
872
 
873
        ringqOpen(&sp->inBuf, SOCKET_BUFSIZ, SOCKET_BUFSIZ);
874
        ringqOpen(&sp->outBuf, SOCKET_BUFSIZ, SOCKET_BUFSIZ);
875
        ringqOpen(&sp->lineBuf, SOCKET_BUFSIZ, -1);
876
 
877
        return sid;
878
}
879
 
880
/******************************************************************************/
881
/*
882
 *      Free a socket structure
883
 */
884
 
885
static void socketFree(int sid)
886
{
887
        socket_t*       sp;
888
        int                     i;
889
 
890
        if ((sp = socketPtr(sid)) == NULL) {
891
                return;
892
        }
893
        if (sp->sock >= 0) {
894
                close(sp->sock);
895
        }
896
 
897
        ringqClose(&sp->inBuf);
898
        ringqClose(&sp->outBuf);
899
        ringqClose(&sp->lineBuf);
900
 
901
        bfree(B_L, sp);
902
        socketMax = hFree((void***) &socketList, sid);
903
 
904
/*
905
 *      Calculate the new highest socket number
906
 */
907
        socketHighestFd = -1;
908
        for (i = 0; i < socketMax; i++) {
909
                if ((sp = socketList[i]) == NULL) {
910
                        continue;
911
                }
912
                socketHighestFd = max(socketHighestFd, sp->sock);
913
        }
914
}
915
 
916
/******************************************************************************/
917
/*
918
 *      Validate a socket handle
919
 */
920
 
921
static socket_t* socketPtr(int sid)
922
{
923
        if (sid < 0 || sid >= socketMax || socketList[sid] == NULL) {
924
                a_assert(NULL);
925
                return NULL;
926
        }
927
 
928
        a_assert(socketList[sid]);
929
        return socketList[sid];
930
}
931
 
932
/******************************************************************************/
933
/*
934
 *      Get the operating system error code
935
 */
936
 
937
static int socketGetError()
938
{
939
        return errno;
940
}
941
 
942
/******************************************************************************/
943
/*
944
 *      Wait until an event occurs on a socket. Return 1 on success, 0 on failure.
945
 */
946
 
947
static int socketWaitForEvent(socket_t* sp, int interestMask, int* errCode)
948
{
949
        a_assert(sp);
950
 
951
        while (socketSelect()) {
952
                if (sp->readyMask & interestMask) {
953
                        break;
954
                }
955
        }
956
        if (sp->readyMask & SOCKET_EXCEPTION) {
957
                return -1;
958
        } else if (sp->readyMask & SOCKET_WRITABLE) {
959
                return 0;
960
        } else {
961
                *errCode = errno = EWOULDBLOCK;
962
                return -1;
963
        }
964
}
965
 
966
/******************************************************************************/
967
/*
968
 *      Put the socket into non-blocking mode
969
 */
970
 
971
static int socketNonBlock(socket_t *sp)
972
{
973
        int             flags;
974
 
975
        flags = fcntl(sp->sock, F_GETFL) | O_NONBLOCK;
976
        if (fcntl(sp->sock, F_SETFL, flags) < 0) {
977
                return -1;
978
    }
979
        return 0;
980
}
981
 
982
/******************************************************************************/
983
/*
984
 *      Duplicate stdin and stdout
985
 */
986
 
987
int DuplicateStdFile (int sid)
988
{
989
  if (0 != dup2(socketList[sid]->sock, 0)  || 1 != dup2(socketList[sid]->sock, 1))
990
    return -1;
991
 
992
  return 0;
993
 
994
}

powered by: WebSVN 2.1.0

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