source: rtems/cpukit/libnetworking/rtems/rtems_syscall.c @ 9b4422a2

4.115
Last change on this file since 9b4422a2 was 9b4422a2, checked in by Joel Sherrill <joel.sherrill@…>, on 05/03/12 at 15:09:24

Remove All CVS Id Strings Possible Using a Script

Script does what is expected and tries to do it as
smartly as possible.

+ remove occurrences of two blank comment lines

next to each other after Id string line removed.

+ remove entire comment blocks which only exited to

contain CVS Ids

+ If the processing left a blank line at the top of

a file, it was removed.

  • Property mode set to 100644
File size: 17.1 KB
RevLine 
[4aa8a23]1#if HAVE_CONFIG_H
2#include "config.h"
3#endif
4
[39e6e65a]5#include <string.h>
6#include <stdarg.h>
[1b821242]7/* #include <stdlib.h> */
[39e6e65a]8#include <stdio.h>
[36799d4]9#include <errno.h>
[39e6e65a]10
11#include <rtems.h>
[58f6655]12#include <rtems/libio_.h>
[39e6e65a]13#include <rtems/error.h>
14#include <rtems/rtems_bsdnet.h>
15
[b3f8c9e1]16#include <errno.h>
[39e6e65a]17#include <sys/types.h>
18#include <sys/param.h>
19#include <sys/mbuf.h>
20#include <sys/socket.h>
21#include <sys/socketvar.h>
22#include <sys/protosw.h>
23#include <sys/proc.h>
[af020036]24#include <sys/fcntl.h>
[39e6e65a]25#include <sys/filio.h>
[011e3b3f]26#include <sys/sysctl.h>
[39e6e65a]27
28#include <net/if.h>
29#include <net/route.h>
30
[ff089035]31/*
32 *  Since we are "in the kernel", these do not get prototyped in sys/socket.h
33 */
34ssize_t send(int, const void *, size_t, int);
35ssize_t recv(int, void *, size_t, int);
36
[73f6236]37/*
38 * Hooks to RTEMS I/O system
39 */
40static const rtems_filesystem_file_handlers_r socket_handlers;
41
[58f6655]42/*
43 * Convert an RTEMS file descriptor to a BSD socket pointer.
44 */
45struct socket *
46rtems_bsdnet_fdToSocket (int fd)
47{
48  rtems_libio_t *iop;
49
50  /* same as rtems_libio_check_fd(_fd) but different return */
51  if ((uint32_t)fd >= rtems_libio_number_iops) {
52    errno = EBADF;
53    return NULL;
54  }
55  iop = &rtems_libio_iops[fd];
56
57  /* same as rtems_libio_check_is_open(iop) but different return */
58  if ((iop->flags & LIBIO_FLAGS_OPEN) == 0) {
59    errno = EBADF;
60    return NULL;
61  }
62
63  if (iop->pathinfo.handlers != &socket_handlers) {
64    errno = ENOTSOCK;
65    return NULL;
66  }
67
68  if (iop->data1 == NULL)
69    errno = EBADF;
70  return iop->data1;
71}
72
73/*
74 * Create an RTEMS file descriptor for a socket
75 */
76static int
77rtems_bsdnet_makeFdForSocket (void *so)
78{
79  rtems_libio_t *iop;
80  int fd;
81
82  iop = rtems_libio_allocate();
83  if (iop == 0)
84      rtems_set_errno_and_return_minus_one( ENFILE );
85
86  fd = iop - rtems_libio_iops;
87  iop->flags |= LIBIO_FLAGS_WRITE | LIBIO_FLAGS_READ;
88  iop->data0 = fd;
89  iop->data1 = so;
90  iop->pathinfo.handlers = &socket_handlers;
91  iop->pathinfo.ops = &rtems_filesystem_operations_default;
92  iop->pathinfo.mt_entry = &rtems_filesystem_null_mt_entry;
93  rtems_filesystem_location_add_to_mt_entry(&iop->pathinfo);
94  return fd;
95}
96
[39e6e65a]97/*
98 * Package system call argument into mbuf.
99 */
100static int
101sockargstombuf (struct mbuf **mp, const void *buf, int buflen, int type)
102{
103        struct mbuf *m;
104
105        if ((u_int)buflen > MLEN)
106                return (EINVAL);
107        m = m_get(M_WAIT, type);
108        if (m == NULL)
109                return (ENOBUFS);
110        m->m_len = buflen;
111        memcpy (mtod(m, caddr_t), buf, buflen);
112        *mp = m;
113        if (type == MT_SONAME) {
114                struct sockaddr *sa;
115                sa = mtod(m, struct sockaddr *);
116                sa->sa_len = buflen;
117        }
118        return 0;
119}
120
121/*
122 *********************************************************************
123 *                       BSD-style entry points                      *
124 *********************************************************************
125 */
126int
127socket (int domain, int type, int protocol)
128{
[cca4400]129        int fd;
[39e6e65a]130        int error;
131        struct socket *so;
132
133        rtems_bsdnet_semaphore_obtain ();
134        error = socreate(domain, &so, type, protocol, NULL);
135        if (error == 0) {
[58f6655]136                fd = rtems_bsdnet_makeFdForSocket (so);
[39e6e65a]137                if (fd < 0)
138                        soclose (so);
139        }
140        else {
141                errno = error;
142                fd = -1;
143        }
144        rtems_bsdnet_semaphore_release ();
145        return fd;
146}
147
148int
149bind (int s, struct sockaddr *name, int namelen)
150{
151        int error;
152        int ret = -1;
153        struct socket *so;
154        struct mbuf *nam;
155
156        rtems_bsdnet_semaphore_obtain ();
[cca4400]157        if ((so = rtems_bsdnet_fdToSocket (s)) != NULL) {
[39e6e65a]158                error = sockargstombuf (&nam, name, namelen, MT_SONAME);
159                if (error == 0) {
160                        error = sobind (so, nam);
161                        if (error == 0)
162                                ret = 0;
163                        else
164                                errno = error;
165                        m_freem (nam);
166                }
167                else {
168                        errno = error;
169                }
170        }
171        rtems_bsdnet_semaphore_release ();
172        return ret;
173}
174
175int
176connect (int s, struct sockaddr *name, int namelen)
177{
178        int error;
179        int ret = -1;
180        struct socket *so;
181        struct mbuf *nam;
182
183        rtems_bsdnet_semaphore_obtain ();
[cca4400]184        if ((so = rtems_bsdnet_fdToSocket (s)) == NULL) {
[39e6e65a]185                rtems_bsdnet_semaphore_release ();
186                return -1;
187        }
188        if ((so->so_state & SS_NBIO) && (so->so_state & SS_ISCONNECTING)) {
189                errno = EALREADY;
190                rtems_bsdnet_semaphore_release ();
191                return -1;
192        }
193        error = sockargstombuf (&nam, name, namelen, MT_SONAME);
194        if (error) {
195                errno = error;
196                rtems_bsdnet_semaphore_release ();
197                return -1;
198        }
199        error = soconnect (so, nam);
[df49c60]200        if (error)
201                goto bad;
[39e6e65a]202        if ((so->so_state & SS_NBIO) && (so->so_state & SS_ISCONNECTING)) {
203                m_freem(nam);
204                errno = EINPROGRESS;
205                rtems_bsdnet_semaphore_release ();
206                return -1;
207        }
208        while ((so->so_state & SS_ISCONNECTING) && so->so_error == 0) {
[df49c60]209                error = soconnsleep (so);
210                if (error)
211                        break;
[39e6e65a]212        }
213        if (error == 0) {
214                error = so->so_error;
215                so->so_error = 0;
216        }
[df49c60]217    bad:
[39e6e65a]218        so->so_state &= ~SS_ISCONNECTING;
219        m_freem (nam);
[df49c60]220        if (error)
221                errno = error;
222        else
[39e6e65a]223                ret = 0;
224        rtems_bsdnet_semaphore_release ();
225        return ret;
226}
227
228int
229listen (int s, int backlog)
230{
231        int error;
232        int ret = -1;
233        struct socket *so;
234
235        rtems_bsdnet_semaphore_obtain ();
[cca4400]236        if ((so = rtems_bsdnet_fdToSocket (s)) != NULL) {
[39e6e65a]237                error = solisten (so, backlog);
238                if (error == 0)
239                        ret = 0;
240                else
241                        errno = error;
242        }
243        rtems_bsdnet_semaphore_release ();
244        return ret;
245}
246
247int
248accept (int s, struct sockaddr *name, int *namelen)
249{
250        int fd;
251        struct socket *head, *so;
252        struct mbuf *nam;
253
254        rtems_bsdnet_semaphore_obtain ();
[cca4400]255        if ((head = rtems_bsdnet_fdToSocket (s)) == NULL) {
[39e6e65a]256                rtems_bsdnet_semaphore_release ();
257                return -1;
258        }
259        if ((head->so_options & SO_ACCEPTCONN) == 0) {
260                errno = EINVAL;
261                rtems_bsdnet_semaphore_release ();
262                return -1;
263        }
264        if ((head->so_state & SS_NBIO) && head->so_comp.tqh_first == NULL) {
265                errno = EWOULDBLOCK;
266                rtems_bsdnet_semaphore_release ();
267                return -1;
268        }
269        while (head->so_comp.tqh_first == NULL && head->so_error == 0) {
270                if (head->so_state & SS_CANTRCVMORE) {
271                        head->so_error = ECONNABORTED;
272                        break;
273                }
[91b1c8e6]274                head->so_error = soconnsleep (head);
[39e6e65a]275        }
276        if (head->so_error) {
277                errno = head->so_error;
278                head->so_error = 0;
279                rtems_bsdnet_semaphore_release ();
280                return -1;
281        }
282
283        so = head->so_comp.tqh_first;
284        TAILQ_REMOVE(&head->so_comp, so, so_list);
285        head->so_qlen--;
286
[58f6655]287        fd = rtems_bsdnet_makeFdForSocket (so);
[39e6e65a]288        if (fd < 0) {
289                TAILQ_INSERT_HEAD(&head->so_comp, so, so_list);
290                head->so_qlen++;
291                soconnwakeup (head);
292                rtems_bsdnet_semaphore_release ();
293                return -1;
294        }
295        so->so_state &= ~SS_COMP;
296        so->so_head = NULL;
297
298        nam = m_get(M_WAIT, MT_SONAME);
299        (void) soaccept(so, nam);
300        if (name) {
301                 /* check length before it is destroyed */
302                if (*namelen > nam->m_len)
303                        *namelen = nam->m_len;
304                memcpy (name, mtod(nam, caddr_t), *namelen);
305        }
306        m_freem(nam);
307        rtems_bsdnet_semaphore_release ();
308        return (fd);
309
310}
311
[6a4096b]312/*
313 *  Shutdown routine
314 */
315
316int
317shutdown (int s, int how)
318{
319      struct socket *so;
320      int error;
321
322      rtems_bsdnet_semaphore_obtain ();
323      if ((so = rtems_bsdnet_fdToSocket (s)) == NULL) {
324              rtems_bsdnet_semaphore_release ();
325              return -1;
326      }
327      error = soshutdown(so, how);
[efa0baa5]328      rtems_bsdnet_semaphore_release ();
[6a4096b]329      if (error) {
330              errno = error;
331              return -1;
332      }
333      return 0;
334}
335
[39e6e65a]336/*
337 * All `transmit' operations end up calling this routine.
338 */
339ssize_t
340sendmsg (int s, const struct msghdr *mp, int flags)
341{
342        int ret = -1;
343        int error;
344        struct uio auio;
345        struct iovec *iov;
346        struct socket *so;
[3274c876]347        struct mbuf *to;
348        struct mbuf *control = NULL;
[39e6e65a]349        int i;
350        int len;
351
352        rtems_bsdnet_semaphore_obtain ();
[cca4400]353        if ((so = rtems_bsdnet_fdToSocket (s)) == NULL) {
[39e6e65a]354                rtems_bsdnet_semaphore_release ();
355                return -1;
356        }
357        auio.uio_iov = mp->msg_iov;
358        auio.uio_iovcnt = mp->msg_iovlen;
359        auio.uio_segflg = UIO_USERSPACE;
360        auio.uio_rw = UIO_WRITE;
361        auio.uio_offset = 0;
362        auio.uio_resid = 0;
363        iov = mp->msg_iov;
364        for (i = 0; i < mp->msg_iovlen; i++, iov++) {
365                if ((auio.uio_resid += iov->iov_len) < 0) {
366                        errno = EINVAL;
367                        rtems_bsdnet_semaphore_release ();
368                        return -1;
369                }
370        }
371        if (mp->msg_name) {
372                error = sockargstombuf (&to, mp->msg_name, mp->msg_namelen, MT_SONAME);
373                if (error) {
374                        errno = error;
375                        rtems_bsdnet_semaphore_release ();
376                        return -1;
377                }
378        }
379        else {
380                to = NULL;
381        }
382        if (mp->msg_control) {
383                if (mp->msg_controllen < sizeof (struct cmsghdr)) {
384                        errno = EINVAL;
385                        if (to)
386                                m_freem(to);
387                        rtems_bsdnet_semaphore_release ();
388                        return -1;
389                }
390                sockargstombuf (&control, mp->msg_control, mp->msg_controllen, MT_CONTROL);
391        }
392        else {
393                control = NULL;
394        }
395        len = auio.uio_resid;
396        error = sosend (so, to, &auio, (struct mbuf *)0, control, flags);
397        if (error) {
398                if (auio.uio_resid != len && (error == EINTR || error == EWOULDBLOCK))
399                        error = 0;
400        }
[429ba3b]401        if (error)
[39e6e65a]402                errno = error;
403        else
404                ret = len - auio.uio_resid;
405        if (to)
406                m_freem(to);
407        rtems_bsdnet_semaphore_release ();
408        return (ret);
409}
410
411/*
412 * Send a message to a host
413 */
414ssize_t
415sendto (int s, const void *buf, size_t buflen, int flags, const struct sockaddr *to, int tolen)
416{
417        struct msghdr msg;
418        struct iovec iov;
419
420        iov.iov_base = (void *)buf;
421        iov.iov_len = buflen;
422        msg.msg_name = (caddr_t)to;
423        msg.msg_namelen = tolen;
424        msg.msg_iov = &iov;
425        msg.msg_iovlen = 1;
426        msg.msg_control = NULL;
427        msg.msg_controllen = 0;
428        return sendmsg (s, &msg, flags);
429}
430
431/*
432 * All `receive' operations end up calling this routine.
433 */
434ssize_t
435recvmsg (int s, struct msghdr *mp, int flags)
436{
437        int ret = -1;
438        int error;
439        struct uio auio;
440        struct iovec *iov;
441        struct socket *so;
442        struct mbuf *from = NULL, *control = NULL;
443        int i;
444        int len;
445
446        rtems_bsdnet_semaphore_obtain ();
[cca4400]447        if ((so = rtems_bsdnet_fdToSocket (s)) == NULL) {
[39e6e65a]448                rtems_bsdnet_semaphore_release ();
449                return -1;
450        }
451        auio.uio_iov = mp->msg_iov;
452        auio.uio_iovcnt = mp->msg_iovlen;
453        auio.uio_segflg = UIO_USERSPACE;
454        auio.uio_rw = UIO_READ;
455        auio.uio_offset = 0;
456        auio.uio_resid = 0;
457        iov = mp->msg_iov;
458        for (i = 0; i < mp->msg_iovlen; i++, iov++) {
459                if ((auio.uio_resid += iov->iov_len) < 0) {
460                        errno = EINVAL;
461                        rtems_bsdnet_semaphore_release ();
462                        return -1;
463                }
464        }
465        len = auio.uio_resid;
466        mp->msg_flags = flags;
[429ba3b]467        error = soreceive (so, &from, &auio, (struct mbuf **)NULL,
[39e6e65a]468                        mp->msg_control ? &control : (struct mbuf **)NULL,
469                        &mp->msg_flags);
470        if (error) {
471                if (auio.uio_resid != len && (error == EINTR || error == EWOULDBLOCK))
472                        error = 0;
473        }
474        if (error) {
475                errno = error;
476        }
477        else {
478                ret = len - auio.uio_resid;
479                if (mp->msg_name) {
480                        len = mp->msg_namelen;
481                        if ((len <= 0) || (from == NULL)) {
482                                len = 0;
483                        }
484                        else {
485                                if (len > from->m_len)
486                                        len = from->m_len;
487                                memcpy (mp->msg_name, mtod(from, caddr_t), len);
488                        }
489                        mp->msg_namelen = len;
490                }
491                if (mp->msg_control) {
492                        struct mbuf *m;
[caeacbcc]493                        void *ctlbuf;
[39e6e65a]494
495                        len = mp->msg_controllen;
496                        m = control;
497                        mp->msg_controllen = 0;
[caeacbcc]498                        ctlbuf = mp->msg_control;
[39e6e65a]499
500                        while (m && (len > 0)) {
501                                unsigned int tocopy;
502
[429ba3b]503                                if (len >= m->m_len)
[39e6e65a]504                                        tocopy = m->m_len;
505                                else {
506                                        mp->msg_flags |= MSG_CTRUNC;
507                                        tocopy = len;
508                                }
509                                memcpy(ctlbuf, mtod(m, caddr_t), tocopy);
510                                ctlbuf += tocopy;
511                                len -= tocopy;
512                                m = m->m_next;
513                        }
514                        mp->msg_controllen = ctlbuf - mp->msg_control;
515                }
516        }
517        if (from)
518                m_freem (from);
519        if (control)
520                m_freem (control);
521        rtems_bsdnet_semaphore_release ();
522        return (ret);
523}
524
525/*
526 * Receive a message from a host
527 */
528ssize_t
529recvfrom (int s, void *buf, size_t buflen, int flags, const struct sockaddr *from, int *fromlen)
530{
531        struct msghdr msg;
532        struct iovec iov;
533        int ret;
534
535        iov.iov_base = buf;
536        iov.iov_len = buflen;
537        msg.msg_name = (caddr_t)from;
[cdf8a300]538        if (fromlen)
539                msg.msg_namelen = *fromlen;
540        else
541        msg.msg_namelen = 0;
[39e6e65a]542        msg.msg_iov = &iov;
543        msg.msg_iovlen = 1;
544        msg.msg_control = NULL;
545        msg.msg_controllen = 0;
546        ret = recvmsg (s, &msg, flags);
547        if ((from != NULL) && (fromlen != NULL) && (ret >= 0))
548                *fromlen = msg.msg_namelen;
549        return ret;
550}
551
552int
553setsockopt (int s, int level, int name, const void *val, int len)
554{
555        struct socket *so;
556        struct mbuf *m = NULL;
557        int error;
558
559        rtems_bsdnet_semaphore_obtain ();
[cca4400]560        if ((so = rtems_bsdnet_fdToSocket (s)) == NULL) {
[39e6e65a]561                rtems_bsdnet_semaphore_release ();
562                return -1;
563        }
564        if (len > MLEN) {
565                errno = EINVAL;
566                rtems_bsdnet_semaphore_release ();
567                return -1;
568        }
569        if (val) {
570                error = sockargstombuf (&m, val, len, MT_SOOPTS);
571                if (error) {
572                        errno = error;
573                        rtems_bsdnet_semaphore_release ();
574                        return -1;
575                }
576        }
577        error = sosetopt(so, level, name, m);
578        if (error) {
579                errno = error;
580                rtems_bsdnet_semaphore_release ();
581                return -1;
582        }
583        rtems_bsdnet_semaphore_release ();
584        return 0;
585}
586
587int
588getsockopt (int s, int level, int name, void *aval, int *avalsize)
589{
590        struct socket *so;
591        struct mbuf *m = NULL, *m0;
592        char *val = aval;
593        int i, op, valsize;
594        int error;
595
596        rtems_bsdnet_semaphore_obtain ();
[cca4400]597        if ((so = rtems_bsdnet_fdToSocket (s)) == NULL) {
[39e6e65a]598                rtems_bsdnet_semaphore_release ();
599                return -1;
600        }
601        if (val)
602                valsize = *avalsize;
603        else
604                valsize = 0;
605        if (((error = sogetopt(so, level, name, &m)) == 0) && val && valsize && m) {
606                op = 0;
607                while (m && op < valsize) {
608                        i = valsize - op;
609                        if (i > m->m_len)
610                                i = m->m_len;
611                        memcpy (val, mtod(m, caddr_t), i);
612                        op += i;
613                        val += i;
614                        m0 = m;
615                        MFREE (m0, m);
616                }
617                *avalsize = op;
618        }
619        if (m != NULL)
620                (void) m_free(m);
621        if (error) {
622                errno = error;
623                rtems_bsdnet_semaphore_release ();
624                return -1;
625        }
626        rtems_bsdnet_semaphore_release ();
627        return 0;
628}
629
[28e7d7fa]630static int
631getpeersockname (int s, struct sockaddr *name, int *namelen, int pflag)
[39e6e65a]632{
633        struct socket *so;
634        struct mbuf *m;
635        int len = *namelen;
636        int error;
637
638        rtems_bsdnet_semaphore_obtain ();
[cca4400]639        if ((so = rtems_bsdnet_fdToSocket (s)) == NULL) {
[39e6e65a]640                rtems_bsdnet_semaphore_release ();
641                return -1;
642        }
643        m = m_getclr(M_WAIT, MT_SONAME);
644        if (m == NULL) {
645                errno = ENOBUFS;
646                rtems_bsdnet_semaphore_release ();
647                return -1;
648        }
[28e7d7fa]649        if (pflag)
650                error = (*so->so_proto->pr_usrreqs->pru_peeraddr)(so, m);
651        else
652                error = (*so->so_proto->pr_usrreqs->pru_sockaddr)(so, m);
[39e6e65a]653        if (error) {
[df49c60]654                m_freem(m);
[39e6e65a]655                errno = error;
656                rtems_bsdnet_semaphore_release ();
657                return -1;
658        }
659        if (len > m->m_len) {
660                len = m->m_len;
661                *namelen = len;
662        }
663        memcpy (name, mtod(m, caddr_t), len);
664        m_freem (m);
665        rtems_bsdnet_semaphore_release ();
666        return 0;
667}
668
[28e7d7fa]669int
670getpeername (int s, struct sockaddr *name, int *namelen)
671{
672        return getpeersockname (s, name, namelen, 1);
673}
674int
675getsockname (int s, struct sockaddr *name, int *namelen)
676{
677        return getpeersockname (s, name, namelen, 0);
678}
679
[36799d4]680int
681sysctl(int *name, u_int namelen, void *oldp,
682       size_t *oldlenp, void *newp, size_t newlen)
683{
684  int    error;
685        size_t j;
686
[429ba3b]687  rtems_bsdnet_semaphore_obtain ();
[36799d4]688  error = userland_sysctl (0, name, namelen, oldp, oldlenp, 1, newp, newlen, &j);
689  rtems_bsdnet_semaphore_release ();
690
691  if (oldlenp)
692    *oldlenp = j;
[429ba3b]693
[36799d4]694  if (error)
695  {
696    errno = error;
697    return -1;
698  }
699  return 0;
700}
701
[39e6e65a]702/*
703 ************************************************************************
[73f6236]704 *                      RTEMS I/O HANDLER ROUTINES                      *
[39e6e65a]705 ************************************************************************
706 */
707static int
[73f6236]708rtems_bsdnet_close (rtems_libio_t *iop)
[39e6e65a]709{
710        struct socket *so;
711        int error;
712
713        rtems_bsdnet_semaphore_obtain ();
[73f6236]714        if ((so = iop->data1) == NULL) {
715                errno = EBADF;
[39e6e65a]716                rtems_bsdnet_semaphore_release ();
717                return -1;
718        }
[766ed7c]719        error = soclose (so);
720        rtems_bsdnet_semaphore_release ();
[39e6e65a]721        if (error) {
722                errno = error;
723                return -1;
724        }
725        return 0;
726}
727
[abef0f6]728static ssize_t
[7192476f]729rtems_bsdnet_read (rtems_libio_t *iop, void *buffer, size_t count)
[39e6e65a]730{
[73f6236]731        return recv (iop->data0, buffer, count, 0);
[39e6e65a]732}
733
[abef0f6]734static ssize_t
[7192476f]735rtems_bsdnet_write (rtems_libio_t *iop, const void *buffer, size_t count)
[39e6e65a]736{
[73f6236]737        return send (iop->data0, buffer, count, 0);
[39e6e65a]738}
739
740static int
[d8dbdc0]741so_ioctl (rtems_libio_t *iop, struct socket *so, uint32_t   command, void *buffer)
[39e6e65a]742{
743        switch (command) {
744        case FIONBIO:
[af020036]745                if (*(int *)buffer) {
746                        iop->flags |= O_NONBLOCK;
[39e6e65a]747                        so->so_state |= SS_NBIO;
[af020036]748                }
749                else {
750                        iop->flags &= ~O_NONBLOCK;
[39e6e65a]751                        so->so_state &= ~SS_NBIO;
[af020036]752                }
[39e6e65a]753                return 0;
754
755        case FIONREAD:
756                *(int *)buffer = so->so_rcv.sb_cc;
757                return 0;
758        }
759
760        if (IOCGROUP(command) == 'i')
761                return ifioctl (so, command, buffer, NULL);
762        if (IOCGROUP(command) == 'r')
763                return rtioctl (command, buffer, NULL);
764        return (*so->so_proto->pr_usrreqs->pru_control)(so, command, buffer, 0);
765}
766
767static int
[d8dbdc0]768rtems_bsdnet_ioctl (rtems_libio_t *iop, uint32_t   command, void *buffer)
[39e6e65a]769{
770        struct socket *so;
771        int error;
772
773        rtems_bsdnet_semaphore_obtain ();
[73f6236]774        if ((so = iop->data1) == NULL) {
775                errno = EBADF;
[39e6e65a]776                rtems_bsdnet_semaphore_release ();
777                return -1;
778        }
[af020036]779        error = so_ioctl (iop, so, command, buffer);
[39e6e65a]780        rtems_bsdnet_semaphore_release ();
781        if (error) {
782                errno = error;
783                return -1;
784        }
785        return 0;
786}
787
[af020036]788static int
[3b7c123]789rtems_bsdnet_fcntl (rtems_libio_t *iop, int cmd)
[af020036]790{
791        struct socket *so;
792
793        if (cmd == F_SETFL) {
794                rtems_bsdnet_semaphore_obtain ();
795                if ((so = iop->data1) == NULL) {
796                        rtems_bsdnet_semaphore_release ();
797                        return EBADF;
798                }
[bdcf02d4]799                if (iop->flags & LIBIO_FLAGS_NO_DELAY)
[af020036]800                        so->so_state |= SS_NBIO;
801                else
802                        so->so_state &= ~SS_NBIO;
803                rtems_bsdnet_semaphore_release ();
804        }
805        return 0;
806}
807
[73f6236]808static int
[3b7c123]809rtems_bsdnet_fstat (const rtems_filesystem_location_info_t *loc, struct stat *sp)
[73f6236]810{
811        sp->st_mode = S_IFSOCK;
812        return 0;
813}
814
815static const rtems_filesystem_file_handlers_r socket_handlers = {
[5ec75ca]816        rtems_filesystem_default_open,          /* open */
817        rtems_bsdnet_close,                     /* close */
818        rtems_bsdnet_read,                      /* read */
819        rtems_bsdnet_write,                     /* write */
820        rtems_bsdnet_ioctl,                     /* ioctl */
821        rtems_filesystem_default_lseek,         /* lseek */
822        rtems_bsdnet_fstat,                     /* fstat */
823        rtems_filesystem_default_ftruncate,     /* ftruncate */
[4116fce6]824        rtems_filesystem_default_fsync_or_fdatasync,    /* fsync */
825        rtems_filesystem_default_fsync_or_fdatasync,    /* fdatasync */
[3b7c123]826        rtems_bsdnet_fcntl                      /* fcntl */
[39e6e65a]827};
Note: See TracBrowser for help on using the repository browser.