source: rtems/cpukit/libnetworking/rtems/rtems_syscall.c @ da10694

4.115
Last change on this file since da10694 was a418b2f, checked in by Sebastian Huber <sebastian.huber@…>, on 03/03/14 at 07:38:10

libnetworking: Typo

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