📄 rtems_syscall.c
字号:
rtems_bsdnet_semaphore_obtain (); if ((so = rtems_bsdnet_fdToSocket (s)) == NULL) { rtems_bsdnet_semaphore_release (); return -1; } auio.uio_iov = mp->msg_iov; auio.uio_iovcnt = mp->msg_iovlen; auio.uio_segflg = UIO_USERSPACE; auio.uio_rw = UIO_READ; auio.uio_offset = 0; auio.uio_resid = 0; iov = mp->msg_iov; for (i = 0; i < mp->msg_iovlen; i++, iov++) { if ((auio.uio_resid += iov->iov_len) < 0) { errno = EINVAL; rtems_bsdnet_semaphore_release (); return -1; } } len = auio.uio_resid; mp->msg_flags = flags; error = soreceive (so, &from, &auio, (struct mbuf **)NULL, mp->msg_control ? &control : (struct mbuf **)NULL, &mp->msg_flags); if (error) { if (auio.uio_resid != len && (error == EINTR || error == EWOULDBLOCK)) error = 0; } if (error) { errno = error; } else { ret = len - auio.uio_resid; if (mp->msg_name) { len = mp->msg_namelen; if ((len <= 0) || (from == NULL)) { len = 0; } else { if (len > from->m_len) len = from->m_len; memcpy (mp->msg_name, mtod(from, caddr_t), len); } mp->msg_namelen = len; } if (mp->msg_control) { struct mbuf *m; caddr_t ctlbuf; len = mp->msg_controllen; m = control; mp->msg_controllen = 0; ctlbuf = (caddr_t) mp->msg_control; while (m && (len > 0)) { unsigned int tocopy; if (len >= m->m_len) tocopy = m->m_len; else { mp->msg_flags |= MSG_CTRUNC; tocopy = len; } memcpy(ctlbuf, mtod(m, caddr_t), tocopy); ctlbuf += tocopy; len -= tocopy; m = m->m_next; } mp->msg_controllen = ctlbuf - mp->msg_control; } } if (from) m_freem (from); if (control) m_freem (control); rtems_bsdnet_semaphore_release (); return (ret);}/* * Receive a message from a host */ssize_trecvfrom (int s, void *buf, size_t buflen, int flags, const struct sockaddr *from, int *fromlen){ struct msghdr msg; struct iovec iov; int ret; iov.iov_base = buf; iov.iov_len = buflen; msg.msg_name = (caddr_t)from; if (fromlen) msg.msg_namelen = *fromlen; else msg.msg_namelen = 0; msg.msg_iov = &iov; msg.msg_iovlen = 1; msg.msg_control = NULL; msg.msg_controllen = 0; ret = recvmsg (s, &msg, flags); if ((from != NULL) && (fromlen != NULL) && (ret >= 0)) *fromlen = msg.msg_namelen; return ret;}/* * Receive a message from a connected host */ssize_trecv (int s, void *buf, size_t buflen, int flags){ return recvfrom (s, buf, buflen, flags, NULL, NULL);}intsetsockopt (int s, int level, int name, const void *val, int len){ struct socket *so; struct mbuf *m = NULL; int error; rtems_bsdnet_semaphore_obtain (); if ((so = rtems_bsdnet_fdToSocket (s)) == NULL) { rtems_bsdnet_semaphore_release (); return -1; } if (len > MLEN) { errno = EINVAL; rtems_bsdnet_semaphore_release (); return -1; } if (val) { error = sockargstombuf (&m, val, len, MT_SOOPTS); if (error) { errno = error; rtems_bsdnet_semaphore_release (); return -1; } } error = sosetopt(so, level, name, m); if (error) { errno = error; rtems_bsdnet_semaphore_release (); return -1; } rtems_bsdnet_semaphore_release (); return 0;}intgetsockopt (int s, int level, int name, void *aval, int *avalsize){ struct socket *so; struct mbuf *m = NULL, *m0; char *val = aval; int i, op, valsize; int error; rtems_bsdnet_semaphore_obtain (); if ((so = rtems_bsdnet_fdToSocket (s)) == NULL) { rtems_bsdnet_semaphore_release (); return -1; } if (val) valsize = *avalsize; else valsize = 0; if (((error = sogetopt(so, level, name, &m)) == 0) && val && valsize && m) { op = 0; while (m && op < valsize) { i = valsize - op; if (i > m->m_len) i = m->m_len; memcpy (val, mtod(m, caddr_t), i); op += i; val += i; m0 = m; MFREE (m0, m); } *avalsize = op; } if (m != NULL) (void) m_free(m); if (error) { errno = error; rtems_bsdnet_semaphore_release (); return -1; } rtems_bsdnet_semaphore_release (); return 0;}static intgetpeersockname (int s, struct sockaddr *name, int *namelen, int pflag){ struct socket *so; struct mbuf *m; int len = *namelen; int error; rtems_bsdnet_semaphore_obtain (); if ((so = rtems_bsdnet_fdToSocket (s)) == NULL) { rtems_bsdnet_semaphore_release (); return -1; } m = m_getclr(M_WAIT, MT_SONAME); if (m == NULL) { errno = ENOBUFS; rtems_bsdnet_semaphore_release (); return -1; } if (pflag) error = (*so->so_proto->pr_usrreqs->pru_peeraddr)(so, m); else error = (*so->so_proto->pr_usrreqs->pru_sockaddr)(so, m); if (error) { m_freem(m); errno = error; rtems_bsdnet_semaphore_release (); return -1; } if (len > m->m_len) { len = m->m_len; *namelen = len; } memcpy (name, mtod(m, caddr_t), len); m_freem (m); rtems_bsdnet_semaphore_release (); return 0;}intgetpeername (int s, struct sockaddr *name, int *namelen){ return getpeersockname (s, name, namelen, 1);}intgetsockname (int s, struct sockaddr *name, int *namelen){ return getpeersockname (s, name, namelen, 0);}intsysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, size_t newlen){ int error; size_t j; rtems_bsdnet_semaphore_obtain (); error = userland_sysctl (0, name, namelen, oldp, oldlenp, 1, newp, newlen, &j); rtems_bsdnet_semaphore_release (); if (oldlenp) *oldlenp = j; if (error) { errno = error; return -1; } return 0;}/* ************************************************************************ * RTEMS I/O HANDLER ROUTINES * ************************************************************************ */static intrtems_bsdnet_close (rtems_libio_t *iop){ struct socket *so; int error; rtems_bsdnet_semaphore_obtain (); if ((so = iop->data1) == NULL) { errno = EBADF; rtems_bsdnet_semaphore_release (); return -1; } error = soclose (so); rtems_bsdnet_semaphore_release (); if (error) { errno = error; return -1; } return 0;}static ssize_trtems_bsdnet_read (rtems_libio_t *iop, void *buffer, unsigned32 count){ return recv (iop->data0, buffer, count, 0);}static ssize_trtems_bsdnet_write (rtems_libio_t *iop, const void *buffer, unsigned32 count){ return send (iop->data0, buffer, count, 0);}static intso_ioctl (rtems_libio_t *iop, struct socket *so, unsigned32 command, void *buffer){ switch (command) { case FIONBIO: if (*(int *)buffer) { iop->flags |= O_NONBLOCK; so->so_state |= SS_NBIO; } else { iop->flags &= ~O_NONBLOCK; so->so_state &= ~SS_NBIO; } return 0; case FIONREAD: *(int *)buffer = so->so_rcv.sb_cc; return 0; } if (IOCGROUP(command) == 'i') return ifioctl (so, command, buffer, NULL); if (IOCGROUP(command) == 'r') return rtioctl (command, buffer, NULL); return (*so->so_proto->pr_usrreqs->pru_control)(so, command, buffer, 0);}static intrtems_bsdnet_ioctl (rtems_libio_t *iop, unsigned32 command, void *buffer){ struct socket *so; int error; rtems_bsdnet_semaphore_obtain (); if ((so = iop->data1) == NULL) { errno = EBADF; rtems_bsdnet_semaphore_release (); return -1; } error = so_ioctl (iop, so, command, buffer); rtems_bsdnet_semaphore_release (); if (error) { errno = error; return -1; } return 0;}static intrtems_bsdnet_fcntl (int cmd, rtems_libio_t *iop){ struct socket *so; if (cmd == F_SETFL) { rtems_bsdnet_semaphore_obtain (); if ((so = iop->data1) == NULL) { rtems_bsdnet_semaphore_release (); return EBADF; } if (iop->flags & LIBIO_FLAGS_NO_DELAY) so->so_state |= SS_NBIO; else so->so_state &= ~SS_NBIO; rtems_bsdnet_semaphore_release (); } return 0;}static intrtems_bsdnet_fstat (rtems_filesystem_location_info_t *loc, struct stat *sp){ sp->st_mode = S_IFSOCK; return 0;}static const rtems_filesystem_file_handlers_r socket_handlers = { NULL, /* open */ rtems_bsdnet_close, /* close */ rtems_bsdnet_read, /* read */ rtems_bsdnet_write, /* write */ rtems_bsdnet_ioctl, /* ioctl */ NULL, /* lseek */ rtems_bsdnet_fstat, /* fstat */ NULL, /* fchmod */ NULL, /* ftruncate */ NULL, /* fpathconf */ NULL, /* fsync */ NULL, /* fdatasync */ rtems_bsdnet_fcntl, /* fcntl */};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -