source: rtems/cpukit/libnetworking/rtems/rtems_syscall.c @ 58f6655

4.115
Last change on this file since 58f6655 was 58f6655, checked in by Sebastian Huber <sebastian.huber@…>, on 04/03/12 at 14:15:34

networking: socket to/from file descriptor

o Move rtems_bsdnet_fdToSocket() and rtems_bsdnet_makeFdForSocket() to

"cpukit/libnetworking/rtems/rtems_syscall.c".

o The rtems_bsdnet_makeFdForSocket() function is now static.
o Check in rtems_bsdnet_fdToSocket() function that the file descriptor

uses the socket handlers, otherwise an error status will be returned
and errno set to ENOTSOCK.

o New test libtests/syscall01.

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