source: rtems/cpukit/httpd/sock.c @ 4e97166

4.104.114.84.95
Last change on this file since 4e97166 was bfb4c547, checked in by Joel Sherrill <joel.sherrill@…>, on 03/05/04 at 18:14:27

2004-03-05 Joel Sherrill <joel@…>

  • libnetworking/rtems_webserver/ejparse.c, libnetworking/rtems_webserver/emfdb.c, libnetworking/rtems_webserver/sock.c, libnetworking/rtems_webserver/socket.c, libnetworking/rtems_webserver/sym.c, libnetworking/rtems_webserver/webs.c, libnetworking/rtems_webserver/websuemf.c: Remove warnings.
  • Property mode set to 100644
File size: 17.4 KB
Line 
1/*
2 * sock.c -- Posix Socket upper layer support module for general posix use
3 *
4 * Copyright (c) GoAhead Software Inc., 1995-2000. All Rights Reserved.
5 *
6 * $Id$
7 */
8
9/******************************** Description *********************************/
10
11/*
12 *      Posix Socket Module.  This supports blocking and non-blocking buffered
13 *      socket I/O.
14 */
15
16/********************************** Includes **********************************/
17
18#include        <string.h>
19#include        <stdlib.h>
20
21#ifdef UEMF
22        #include        "uemf.h"
23#else
24        #include        <socket.h>
25        #include        <types.h>
26        #include        <unistd.h>
27        #include        "emfInternal.h"
28#endif
29
30/************************************ Locals **********************************/
31
32socket_t        **socketList;                   /* List of open sockets */
33int                     socketMax;                              /* Maximum size of socket */
34int                     socketHighestFd = -1;   /* Highest socket fd opened */
35
36/***************************** Forward Declarations ***************************/
37
38static int      socketDoOutput(socket_t *sp, char *buf, int toWrite, int *errCode);
39static int      tryAlternateSendTo(int sock, char *buf, int toWrite, int i,
40                        struct sockaddr *server);
41
42/*********************************** Code *************************************/
43/*
44 *      Write to a socket. Absorb as much data as the socket can buffer. Block if
45 *      the socket is in blocking mode. Returns -1 on error, otherwise the number
46 *      of bytes written.
47 */
48
49int     socketWrite(int sid, char *buf, int bufsize)
50{
51        socket_t        *sp;
52        ringq_t         *rq;
53        int                     len, bytesWritten, room;
54
55        a_assert(buf);
56        a_assert(bufsize >= 0);
57
58        if ((sp = socketPtr(sid)) == NULL) {
59                return -1;
60        }
61
62/*
63 *      Loop adding as much data to the output ringq as we can absorb. Initiate a
64 *      flush when the ringq is too full and continue. Block in socketFlush if the
65 *      socket is in blocking mode.
66 */
67        rq = &sp->outBuf;
68        for (bytesWritten = 0; bufsize > 0; ) {
69                if ((room = ringqPutBlkMax(rq)) == 0) {
70                        if (socketFlush(sid) < 0) {
71                                return -1;
72                        }
73                        if ((room = ringqPutBlkMax(rq)) == 0) {
74                                if (sp->flags & SOCKET_BLOCK) {
75#if (defined (WIN) || defined (CE))
76                                        int             errCode;
77                                        if (! socketWaitForEvent(sp,  FD_WRITE | SOCKET_WRITABLE,
78                                                &errCode)) {
79                                                return -1;
80                                        }
81#endif
82                                        continue;
83                                }
84                                break;
85                        }
86                        continue;
87                }
88                len = min(room, bufsize);
89                ringqPutBlk(rq, (unsigned char *) buf, len);
90                bytesWritten += len;
91                bufsize -= len;
92                buf += len;
93        }
94        return bytesWritten;
95}
96
97/******************************************************************************/
98/*
99 *      Write a string to a socket
100 */
101
102int     socketWriteString(int sid, char_t *buf)
103{
104 #ifdef UNICODE
105        char    *byteBuf;
106        int             r, len;
107 
108        len = gstrlen(buf);
109        byteBuf = ballocUniToAsc(buf, len);
110        r = socketWrite(sid, byteBuf, len);
111        bfreeSafe(B_L, byteBuf);
112        return r;
113 #else
114        return socketWrite(sid, buf, strlen(buf));
115 #endif /* UNICODE */
116}
117
118/******************************************************************************/
119/*
120 *      Read from a socket. Return the number of bytes read if successful. This
121 *      may be less than the requested "bufsize" and may be zero. Return -1 for
122 *      errors. Return 0 for EOF. Otherwise return the number of bytes read.
123 *      If this routine returns zero it indicates an EOF condition.
124 *  which can be verified with socketEof()
125 
126 *      Note: this ignores the line buffer, so a previous socketGets
127 *      which read a partial line may cause a subsequent socketRead to miss some
128 *      data. This routine may block if the socket is in blocking mode.
129 *
130 */
131
132int     socketRead(int sid, char *buf, int bufsize)
133{
134        socket_t        *sp;
135        ringq_t         *rq;
136        int                     len, room, errCode, bytesRead;
137
138        a_assert(buf);
139        a_assert(bufsize > 0);
140
141        if ((sp = socketPtr(sid)) == NULL) {
142                return -1;
143        }
144
145        if (sp->flags & SOCKET_EOF) {
146                return 0;
147        }
148
149        rq = &sp->inBuf;
150        for (bytesRead = 0; bufsize > 0; ) {
151                len = min(ringqLen(rq), bufsize);
152                if (len <= 0) {
153/*
154 *                      if blocking mode and already have data, exit now or it may block
155 *                      forever.
156 */
157                        if ((sp->flags & SOCKET_BLOCK) &&
158                                (bytesRead > 0)) {
159                                break;
160                        }
161/*
162 *                      This flush is critical for readers of datagram packets. If the
163 *                      buffer is not big enough to read the whole datagram in one hit,
164 *                      the recvfrom call will fail.
165 */
166                        ringqFlush(rq);
167                        room = ringqPutBlkMax(rq);
168                        len = socketGetInput(sid, (char *) rq->endp, room, &errCode);
169                        if (len < 0) {
170                                if (errCode == EWOULDBLOCK) {
171                                        if ((sp->flags & SOCKET_BLOCK) &&
172                                                (bytesRead ==  0)) {
173                                                continue;
174                                        }
175                                        if (bytesRead >= 0) {
176                                                return bytesRead;
177                                        }
178                                }
179                                return -1;
180
181                        } else if (len == 0) {
182/*
183 *                              If bytesRead is 0, this is EOF since socketRead should never
184 *                              be called unless there is data yet to be read.  Set the flag. 
185 *                              Then pass back the number of bytes read.
186 */
187                                if (bytesRead == 0) {
188                                        sp->flags |= SOCKET_EOF;
189                                }
190                                return bytesRead;
191                        }
192                        ringqPutBlkAdj(rq, len);
193                        len = min(len, bufsize);
194                }
195                memcpy(&buf[bytesRead], rq->servp, len);
196                ringqGetBlkAdj(rq, len);
197                bufsize -= len;
198                bytesRead += len;
199        }
200        return bytesRead;
201}
202
203/******************************************************************************/
204/*
205 *      Get a string from a socket. This returns data in *buf in a malloced string
206 *      after trimming the '\n'. If there is zero bytes returned, *buf will be set
207 *      to NULL. If doing non-blocking I/O, it returns -1 for error, EOF or when
208 *      no complete line yet read. If doing blocking I/O, it will block until an
209 *      entire line is read. If a partial line is read socketInputBuffered or
210 *      socketEof can be used to distinguish between EOF and partial line still
211 *      buffered. This routine eats and ignores carriage returns.
212 */
213
214int     socketGets(int sid, char_t **buf)
215{
216        socket_t        *sp;
217        ringq_t         *lq;
218        char            c;
219        int                     rc, len;
220
221        a_assert(buf);
222        *buf = NULL;
223
224        if ((sp = socketPtr(sid)) == NULL) {
225                return -1;
226        }
227        lq = &sp->lineBuf;
228
229        while (1) {
230
231                if ((rc = socketRead(sid, &c, 1)) < 0) {
232                        return rc;
233                }
234               
235                if (rc == 0) {
236/*
237 *                      If there is a partial line and we are at EOF, pretend we saw a '\n'
238 */
239                        if (ringqLen(lq) > 0 && (sp->flags & SOCKET_EOF)) {
240                                c = '\n';
241                        } else {
242                                return -1;
243                        }
244                }
245/*
246 *              If a newline is seen, return the data excluding the new line to the
247 *              caller. If carriage return is seen, just eat it.
248 */
249                if (c == '\n') {
250                        len = ringqLen(lq);
251                        if (len > 0) {
252                                *buf = ballocAscToUni((char *)lq->servp, len);
253                        } else {
254                                *buf = NULL;
255                        }
256                        ringqFlush(lq);
257                        return len;
258
259                } else if (c == '\r') {
260                        continue;
261                }
262                ringqPutcA(lq, c);
263        }
264        return 0;
265}
266
267/******************************************************************************/
268/*
269 *      Flush the socket. Block if the socket is in blocking mode.
270 *      This will return -1 on errors and 0 if successful.
271 */
272
273int socketFlush(int sid)
274{
275        socket_t        *sp;
276        ringq_t         *rq;
277        int                     len, bytesWritten, errCode;
278
279        if ((sp = socketPtr(sid)) == NULL) {
280                return -1;
281        }
282        rq = &sp->outBuf;
283
284/*
285 *      Set the background flushing flag which socketEventProc will check to
286 *      continue the flush.
287 */
288        if (! (sp->flags & SOCKET_BLOCK)) {
289                sp->flags |= SOCKET_FLUSHING;
290        }
291
292/*
293 *      Break from loop if not blocking after initiating output. If we are blocking
294 *      we wait for a write event.
295 */
296        while (ringqLen(rq) > 0) {
297                len = ringqGetBlkMax(&sp->outBuf);
298                bytesWritten = socketDoOutput(sp, (char*) rq->servp, len, &errCode);
299                if (bytesWritten < 0) {
300                        if (errCode == EINTR) {
301                                continue;
302                        } else if (errCode == EWOULDBLOCK || errCode == EAGAIN) {
303#if (defined (WIN) || defined (CE))
304                                if (sp->flags & SOCKET_BLOCK) {
305                                        int             errCode;
306                                        if (! socketWaitForEvent(sp,  FD_WRITE | SOCKET_WRITABLE,
307                                                &errCode)) {
308                                                return -1;
309                                        }
310                                        continue;
311                                }
312#endif
313/*
314 *                              Ensure we get a FD_WRITE message when the socket can absorb
315 *                              more data (non-blocking only.) Store the user's mask if we
316 *                              haven't done it already.
317 */
318                                if (sp->saveMask < 0 ) {
319                                        sp->saveMask = sp->handlerMask;
320                                        socketRegisterInterest(sp,
321                                        sp->handlerMask | SOCKET_WRITABLE);
322                                }
323                                return 0;
324                        }
325                        return -1;
326                }
327                ringqGetBlkAdj(rq, bytesWritten);
328        }
329/*
330 *      If the buffer is empty, reset the ringq pointers to point to the start
331 *      of the buffer. This is essential to ensure that datagrams get written
332 *      in one single I/O operation.
333 */
334        if (ringqLen(rq) == 0) {
335                ringqFlush(rq);
336        }
337/*
338 *      Restore the users mask if it was saved by the non-blocking code above.
339 *      Note: saveMask = -1 if empty. socketRegisterInterest will set handlerMask
340 */
341        if (sp->saveMask >= 0) {
342                socketRegisterInterest(sp, sp->saveMask);
343                sp->saveMask = -1;
344        }
345        sp->flags &= ~SOCKET_FLUSHING;
346        return 0;
347}
348
349/******************************************************************************/
350/*
351 *      Return the count of input characters buffered. We look at both the line
352 *      buffer and the input (raw) buffer. Return -1 on error or EOF.
353 */
354
355int socketInputBuffered(int sid)
356{
357        socket_t        *sp;
358
359        if ((sp = socketPtr(sid)) == NULL) {
360                return -1;
361        }
362        if (socketEof(sid)) {
363                return -1;
364        }
365        return ringqLen(&sp->lineBuf) + ringqLen(&sp->inBuf);
366}
367
368/******************************************************************************/
369/*
370 *      Return true if EOF
371 */
372
373int socketEof(int sid)
374{
375        socket_t        *sp;
376
377        if ((sp = socketPtr(sid)) == NULL) {
378                return -1;
379        }
380        return sp->flags & SOCKET_EOF;
381}
382
383/******************************************************************************/
384/*
385 *      Return the number of bytes the socket can absorb without blocking
386 */
387
388int socketCanWrite(int sid)
389{
390        socket_t        *sp;
391
392        if ((sp = socketPtr(sid)) == NULL) {
393                return -1;
394        }
395        return sp->outBuf.buflen - ringqLen(&sp->outBuf) - 1;
396}
397
398/******************************************************************************/
399/*
400 *      Add one to allow the user to write exactly SOCKET_BUFSIZ
401 */
402
403void socketSetBufferSize(int sid, int in, int line, int out)
404{
405        socket_t        *sp;
406
407        if ((sp = socketPtr(sid)) == NULL) {
408                return;
409        }
410
411        if (in >= 0) {
412                ringqClose(&sp->inBuf);
413                in++;
414                ringqOpen(&sp->inBuf, in, in);
415        }
416
417        if (line >= 0) {
418                ringqClose(&sp->lineBuf);
419                line++;
420                ringqOpen(&sp->lineBuf, line, line);
421        }
422
423        if (out >= 0) {
424                ringqClose(&sp->outBuf);
425                out++;
426                ringqOpen(&sp->outBuf, out, out);
427        }
428}
429
430/******************************************************************************/
431/*
432 *      Create a user handler for this socket. The handler called whenever there
433 *      is an event of interest as defined by handlerMask (SOCKET_READABLE, ...)
434 */
435
436void socketCreateHandler(int sid, int handlerMask, socketHandler_t handler,
437                int data)
438{
439        socket_t        *sp;
440
441        if ((sp = socketPtr(sid)) == NULL) {
442                return;
443        }
444        sp->handler = handler;
445        sp->handler_data = data;
446        socketRegisterInterest(sp, handlerMask);
447}
448
449/******************************************************************************/
450/*
451 *      Delete a handler
452 */
453
454void socketDeleteHandler(int sid)
455{
456        socket_t        *sp;
457
458        if ((sp = socketPtr(sid)) == NULL) {
459                return;
460        }
461        sp->handler = NULL;
462        socketRegisterInterest(sp, 0);
463}
464
465/******************************************************************************/
466/*
467 *      Socket output procedure. Return -1 on errors otherwise return the number
468 *      of bytes written.
469 */
470
471static int socketDoOutput(socket_t *sp, char *buf, int toWrite, int *errCode)
472{
473        struct sockaddr_in      server;
474        int                                     bytes;
475
476        a_assert(sp);
477        a_assert(buf);
478        a_assert(toWrite > 0);
479        a_assert(errCode);
480
481        *errCode = 0;
482
483#if (defined (WIN) || defined (CE))
484        if ((sp->flags & SOCKET_ASYNC)
485                        && ! socketWaitForEvent(sp,  FD_CONNECT, errCode)) {
486                return -1;
487        }
488#endif
489
490/*
491 *      Write the data
492 */
493        if (sp->flags & SOCKET_BROADCAST) {
494                server.sin_family = AF_INET;
495#if (defined (UEMF) || defined (LITTLEFOOT))
496                server.sin_addr.s_addr = INADDR_BROADCAST;
497#else
498                server.sin_addr.s_addr = inet_addr(basicGetBroadcastAddress());
499#endif
500                server.sin_port = htons((short)(sp->port & 0xFFFF));
501                if ((bytes = sendto(sp->sock, buf, toWrite, 0,
502                        (struct sockaddr *) &server, sizeof(server))) < 0) {
503                        bytes = tryAlternateSendTo(sp->sock, buf, toWrite, 0,
504                        (struct sockaddr *) &server);
505                }
506        } else if (sp->flags & SOCKET_DATAGRAM) {
507                server.sin_family = AF_INET;
508                server.sin_addr.s_addr = inet_addr(sp->host);
509                server.sin_port = htons((short)(sp->port & 0xFFFF));
510                bytes = sendto(sp->sock, buf, toWrite, 0,
511                        (struct sockaddr *) &server, sizeof(server));
512
513        } else {
514                bytes = send(sp->sock, buf, toWrite, 0);
515        }
516
517        if (bytes < 0) {
518                *errCode = socketGetError();
519#if (defined (WIN) || defined (CE))
520                sp->currentEvents &= ~FD_WRITE;
521#endif
522
523                return -1;
524
525        } else if (bytes == 0 && bytes != toWrite) {
526                *errCode = EWOULDBLOCK;
527#if (defined (WIN) || defined (CE))
528                sp->currentEvents &= ~FD_WRITE;
529#endif
530                return -1;
531        }
532
533/*
534 *      Ensure we get to write some more data real soon if the socket can absorb
535 *      more data
536 */
537#ifndef UEMF
538#ifdef WIN
539        if (sp->interestEvents & FD_WRITE) {
540                emfTime_t blockTime = { 0, 0 };
541                emfSetMaxBlockTime(&blockTime);
542        }
543#endif /* WIN */
544#endif
545        return bytes;
546}
547
548/******************************************************************************/
549/*
550 *              If the sendto failed, swap the first two bytes in the
551 *              sockaddr structure.  This is a kludge due to a change in
552 *              VxWorks between versions 5.3 and 5.4, but we want the
553 *              product to run on either.
554 */
555static int tryAlternateSendTo(int sock, char *buf, int toWrite, int i,
556                        struct sockaddr *server)
557{
558#ifdef VXWORKS
559        char *ptr;
560
561        ptr = (char *)server;
562        *ptr = *(ptr+1);
563        *(ptr+1) = 0;
564        return sendto(sock, buf, toWrite, i, server, sizeof(struct sockaddr));
565#else
566        return -1;
567#endif /* VXWORKS */
568}
569
570/******************************************************************************/
571/*
572 *      Allocate a new socket structure
573 */
574
575int socketAlloc(char *host, int port, socketAccept_t accept, int flags)
576{
577        socket_t        *sp;
578        int                     sid;
579
580        if ((sid = hAllocEntry((void*) &socketList, &socketMax,
581                        sizeof(socket_t))) < 0) {
582                return -1;
583        }
584        sp = socketList[sid];
585
586        sp->sid = sid;
587        sp->accept = accept;
588        sp->port = port;
589        sp->fileHandle = -1;
590        sp->saveMask = -1;
591
592        if (host) {
593                strncpy(sp->host, host, sizeof(sp->host));
594        }
595
596/*
597 *      Preserve only specified flags from the callers open
598 */
599        a_assert((flags & ~(SOCKET_BROADCAST|SOCKET_DATAGRAM|SOCKET_BLOCK|
600                                                SOCKET_LISTENING)) == 0);
601        sp->flags = flags & (SOCKET_BROADCAST | SOCKET_DATAGRAM | SOCKET_BLOCK|
602                                                SOCKET_LISTENING);
603
604/*
605 *      Add one to allow the user to write exactly SOCKET_BUFSIZ
606 */
607        ringqOpen(&sp->inBuf, SOCKET_BUFSIZ, SOCKET_BUFSIZ);
608        ringqOpen(&sp->outBuf, SOCKET_BUFSIZ + 1, SOCKET_BUFSIZ + 1);
609        ringqOpen(&sp->lineBuf, SOCKET_BUFSIZ, -1);
610
611        return sid;
612}
613
614/******************************************************************************/
615/*
616 *      Free a socket structure
617 */
618
619void socketFree(int sid)
620{
621        socket_t        *sp;
622        char_t          buf[256];
623        int                     i;
624
625        if ((sp = socketPtr(sid)) == NULL) {
626                return;
627        }
628
629/*
630 *      To close a socket, remove any registered interests, set it to
631 *      non-blocking so that the recv which follows won't block, do a
632 *      shutdown on it so peers on the other end will receive a FIN,
633 *      then read any data not yet retrieved from the receive buffer,
634 *      and finally close it.  If these steps are not all performed
635 *      RESETs may be sent to the other end causing problems.
636 */
637        socketRegisterInterest(sp, 0);
638        if (sp->sock >= 0) {
639                socketSetBlock(sid, 0);
640                if (shutdown(sp->sock, 1) >= 0) {
641                        recv(sp->sock, buf, sizeof(buf), 0);
642                }
643#if (defined (WIN) || defined (CE))
644                closesocket(sp->sock);
645#else
646                close(sp->sock);
647#endif
648        }
649
650        ringqClose(&sp->inBuf);
651        ringqClose(&sp->outBuf);
652        ringqClose(&sp->lineBuf);
653
654        bfree(B_L, sp);
655        socketMax = hFree((void*) &socketList, sid);
656
657/*
658 *      Calculate the new highest socket number
659 */
660        socketHighestFd = -1;
661        for (i = 0; i < socketMax; i++) {
662                if ((sp = socketList[i]) == NULL) {
663                        continue;
664                }
665                socketHighestFd = max(socketHighestFd, sp->sock);
666        }
667}
668
669/******************************************************************************/
670/*
671 *      Validate a socket handle
672 */
673
674socket_t *socketPtr(int sid)
675{
676        if (sid < 0 || sid >= socketMax || socketList[sid] == NULL) {
677                a_assert(NULL);
678                errno = EBADF;
679                return NULL;
680        }
681
682        a_assert(socketList[sid]);
683        return socketList[sid];
684}
685
686/******************************************************************************/
687/*
688 *      Get the operating system error code
689 */
690
691int socketGetError()
692{
693#if (defined (WIN) || defined (CE))
694        switch (WSAGetLastError()) {
695        case WSAEWOULDBLOCK:
696                return EWOULDBLOCK;
697        case WSAECONNRESET:
698                return ECONNRESET;
699        case WSAENETDOWN:
700                return ENETDOWN;
701        case WSAEPROCLIM:
702                return EAGAIN;
703        case WSAEINTR:
704                return EINTR;
705        default:
706                return EINVAL;
707        }
708#else
709        return errno;
710#endif
711}
712
713/******************************************************************************/
714/*
715 *      Return the underlying socket handle
716 */
717
718int socketGetHandle(int sid)
719{
720        socket_t        *sp;
721
722        if ((sp = socketPtr(sid)) == NULL) {
723                return -1;
724        }
725        return sp->sock;
726}
727
728/******************************************************************************/
729/*
730 *      Get blocking mode
731 */
732
733int socketGetBlock(int sid)
734{
735        socket_t        *sp;
736
737        if ((sp = socketPtr(sid)) == NULL) {
738                a_assert(0);
739                return 0;
740        }
741        return (sp->flags & SOCKET_BLOCK);
742}
743
744/******************************************************************************/
745/*
746 *      Get mode
747 */
748
749int socketGetMode(int sid)
750{
751        socket_t        *sp;
752
753        if ((sp = socketPtr(sid)) == NULL) {
754                a_assert(0);
755                return 0;
756        }
757        return sp->flags;
758}
759
760/******************************************************************************/
761/*
762 *      Set mode
763 */
764
765void socketSetMode(int sid, int mode)
766{
767        socket_t        *sp;
768
769        if ((sp = socketPtr(sid)) == NULL) {
770                a_assert(0);
771                return;
772        }
773        sp->flags = mode;
774}
775
776/******************************************************************************/
777/*
778 *      Get port.
779 */
780
781int socketGetPort(int sid)
782{
783        socket_t        *sp;
784
785        if ((sp = socketPtr(sid)) == NULL) {
786                return -1;
787        }
788        return sp->port;
789}
790
791/******************************************************************************/
Note: See TracBrowser for help on using the repository browser.