Add new psock layer; telnet session is now wrapped in a character device

git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@4347 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
patacongo
2012-01-30 21:29:59 +00:00
parent e94dcdf625
commit 9b617b6133
10 changed files with 572 additions and 44 deletions
+2
View File
@@ -2408,3 +2408,5 @@
sub-directory: By making libboard.a a "phony" target, libboard.a should sub-directory: By making libboard.a a "phony" target, libboard.a should
always rebuilt (the end result is worth the small increase in build time) always rebuilt (the end result is worth the small increase in build time)
(submitted by Mike Smith). (submitted by Mike Smith).
* include/net/psock.h: A new low level socket interface that allows the OS
to use the socket interface without having a socket descriptor.
+312
View File
@@ -0,0 +1,312 @@
/****************************************************************************
* include/net/psock.h
*
* Copyright (C) 2012 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
#ifndef __NET_PSOCK_H
#define __NET_PSOCK_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <sys/types.h>
#ifdef CONFIG_NET
/****************************************************************************
* Pre-Processor Definitions
****************************************************************************/
/****************************************************************************
* Public Type Definitions
****************************************************************************/
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
#undef EXTERN
#if defined(__cplusplus)
#define EXTERN extern "C"
extern "C" {
#else
#define EXTERN extern
#endif
/****************************************************************************
* Function: sockfd_socket
*
* Description:
* Given a socket descriptor, return the underly NuttX-specific socket
* structure.
*
* Parameters:
* psock Socket instance
*
* Returned Value:
* 0 on success; -1 on error with errno set appropriately.
*
* Assumptions:
*
****************************************************************************/
struct socket;
EXTERN FAR struct socket *sockfd_socket(int sockfd);
/****************************************************************************
* Function: psock_close
*
* Description:
* Performs the close operation on a socket instance
*
* Parameters:
* psock Socket instance
*
* Returned Value:
* 0 on success; -1 on error with errno set appropriately.
*
* Assumptions:
*
****************************************************************************/
struct socket;
EXTERN int psock_close(FAR struct socket *psock);
/****************************************************************************
* Function: psock_send
*
* Description:
* The send() call may be used only when the socket is in a connected state
* (so that the intended recipient is known). The only difference between
* send() and write() is the presence of flags. With zero flags parameter,
* send() is equivalent to write(). Also, send(sockfd,buf,len,flags) is
* equivalent to sendto(sockfd,buf,len,flags,NULL,0).
*
* Parameters:
* psock And instance of the internal socket structure.
* buf Data to send
* len Length of data to send
* flags Send flags
*
* Returned Value:
* On success, returns the number of characters sent. On error,
* -1 is returned, and errno is set appropriately:
*
* EAGAIN or EWOULDBLOCK
* The socket is marked non-blocking and the requested operation
* would block.
* EBADF
* An invalid descriptor was specified.
* ECONNRESET
* Connection reset by peer.
* EDESTADDRREQ
* The socket is not connection-mode, and no peer address is set.
* EFAULT
* An invalid user space address was specified for a parameter.
* EINTR
* A signal occurred before any data was transmitted.
* EINVAL
* Invalid argument passed.
* EISCONN
* The connection-mode socket was connected already but a recipient
* was specified. (Now either this error is returned, or the recipient
* specification is ignored.)
* EMSGSIZE
* The socket type requires that message be sent atomically, and the
* size of the message to be sent made this impossible.
* ENOBUFS
* The output queue for a network interface was full. This generally
* indicates that the interface has stopped sending, but may be
* caused by transient congestion.
* ENOMEM
* No memory available.
* ENOTCONN
* The socket is not connected, and no target has been given.
* ENOTSOCK
* The argument s is not a socket.
* EOPNOTSUPP
* Some bit in the flags argument is inappropriate for the socket
* type.
* EPIPE
* The local end has been shut down on a connection oriented socket.
* In this case the process will also receive a SIGPIPE unless
* MSG_NOSIGNAL is set.
*
* Assumptions:
*
****************************************************************************/
struct socket;
EXTERN ssize_t psock_send(FAR struct socket *psock, const void *buf,
size_t len, int flags);
/****************************************************************************
* Function: psock_sendto
*
* Description:
* If sendto() is used on a connection-mode (SOCK_STREAM, SOCK_SEQPACKET)
* socket, the parameters to and 'tolen' are ignored (and the error EISCONN
* may be returned when they are not NULL and 0), and the error ENOTCONN is
* returned when the socket was not actually connected.
*
* Parameters:
* psock A pointer to a NuttX-specific, internal socket structure
* buf Data to send
* len Length of data to send
* flags Send flags
* to Address of recipient
* tolen The length of the address structure
*
* Returned Value:
* On success, returns the number of characters sent. On error,
* -1 is returned, and errno is set appropriately:
*
* EAGAIN or EWOULDBLOCK
* The socket is marked non-blocking and the requested operation
* would block.
* EBADF
* An invalid descriptor was specified.
* ECONNRESET
* Connection reset by peer.
* EDESTADDRREQ
* The socket is not connection-mode, and no peer address is set.
* EFAULT
* An invalid user space address was specified for a parameter.
* EINTR
* A signal occurred before any data was transmitted.
* EINVAL
* Invalid argument passed.
* EISCONN
* The connection-mode socket was connected already but a recipient
* was specified. (Now either this error is returned, or the recipient
* specification is ignored.)
* EMSGSIZE
* The socket type requires that message be sent atomically, and the
* size of the message to be sent made this impossible.
* ENOBUFS
* The output queue for a network interface was full. This generally
* indicates that the interface has stopped sending, but may be
* caused by transient congestion.
* ENOMEM
* No memory available.
* ENOTCONN
* The socket is not connected, and no target has been given.
* ENOTSOCK
* The argument s is not a socket.
* EOPNOTSUPP
* Some bit in the flags argument is inappropriate for the socket
* type.
* EPIPE
* The local end has been shut down on a connection oriented socket.
* In this case the process will also receive a SIGPIPE unless
* MSG_NOSIGNAL is set.
*
* Assumptions:
*
****************************************************************************/
struct socket;
struct sockaddr;
EXTERN ssize_t psock_sendto(FAR struct socket *psock, FAR const void *buf,
size_t len, int flags, FAR const struct sockaddr *to,
socklen_t tolen);
/****************************************************************************
* Function: psock_recvfrom
*
* Description:
* recvfrom() receives messages from a socket, and may be used to receive
* data on a socket whether or not it is connection-oriented.
*
* If from is not NULL, and the underlying protocol provides the source
* address, this source address is filled in. The argument fromlen
* initialized to the size of the buffer associated with from, and modified
* on return to indicate the actual size of the address stored there.
*
* Parameters:
* psock A pointer to a NuttX-specific, internal socket structure
* buf Buffer to receive data
* len Length of buffer
* flags Receive flags
* from Address of source (may be NULL)
* fromlen The length of the address structure
*
* Returned Value:
* On success, returns the number of characters sent. On error,
* -1 is returned, and errno is set appropriately:
*
* EAGAIN
* The socket is marked non-blocking and the receive operation would block,
* or a receive timeout had been set and the timeout expired before data
* was received.
* EBADF
* The argument sockfd is an invalid descriptor.
* ECONNREFUSED
* A remote host refused to allow the network connection (typically because
* it is not running the requested service).
* EFAULT
* The receive buffer pointer(s) point outside the process's address space.
* EINTR
* The receive was interrupted by delivery of a signal before any data were
* available.
* EINVAL
* Invalid argument passed.
* ENOMEM
* Could not allocate memory.
* ENOTCONN
* The socket is associated with a connection-oriented protocol and has
* not been connected.
* ENOTSOCK
* The argument sockfd does not refer to a socket.
*
* Assumptions:
*
****************************************************************************/
struct socket;
struct sockaddr;
EXTERN ssize_t psock_recvfrom(FAR struct socket *psock, FAR void *buf,
size_t len, int flags,FAR struct sockaddr *from,
FAR socklen_t *fromlen);
#define psock_recv(psock,buf,len,flags) psock_recvfrom(psock,buf,len,flags,NULL,0)
#undef EXTERN
#if defined(__cplusplus)
}
#endif
#endif /* CONFIG_NET */
#endif /* __NET_PSOCK_H */
+6 -6
View File
@@ -1,8 +1,8 @@
/**************************************************************************** /****************************************************************************
* net/net_close.c * net/net_close.c
* *
* Copyright (C) 2007-2011 Gregory Nutt. All rights reserved. * Copyright (C) 2007-2012 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <spudmonkey@racsa.co.cr> * Author: Gregory Nutt <gnutt@nuttx.org>
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@@ -199,10 +199,10 @@ static inline void netclose_disconnect(FAR struct socket *psock)
****************************************************************************/ ****************************************************************************/
/**************************************************************************** /****************************************************************************
* Function: net_closesocket * Function: psock_close
* *
* Description: * Description:
* Performs the close operation on asocket instance * Performs the close operation on a socket instance
* *
* Parameters: * Parameters:
* psock Socket instance * psock Socket instance
@@ -214,7 +214,7 @@ static inline void netclose_disconnect(FAR struct socket *psock)
* *
****************************************************************************/ ****************************************************************************/
int net_closesocket(FAR struct socket *psock) int psock_close(FAR struct socket *psock)
{ {
int err; int err;
@@ -324,7 +324,7 @@ errout:
int net_close(int sockfd) int net_close(int sockfd)
{ {
return net_closesocket(sockfd_socket(sockfd)); return psock_close(sockfd_socket(sockfd));
} }
#endif /* CONFIG_NET */ #endif /* CONFIG_NET */
+9 -3
View File
@@ -1,8 +1,8 @@
/**************************************************************************** /****************************************************************************
* net/net_internal.h * net/net_internal.h
* *
* Copyright (C) 2007-2009, 2011 Gregory Nutt. All rights reserved. * Copyright (C) 2007-2009, 2011-2012 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <spudmonkey@racsa.co.cr> * Author: Gregory Nutt <gnutt@nuttx.org>
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@@ -48,6 +48,7 @@
#include <time.h> #include <time.h>
#include <nuttx/net.h> #include <nuttx/net.h>
#include <net/psock.h>
#include <net/uip/uip.h> #include <net/uip/uip.h>
/**************************************************************************** /****************************************************************************
@@ -157,7 +158,7 @@ EXTERN FAR struct socket *sockfd_socket(int sockfd);
/* net_close.c ***************************************************************/ /* net_close.c ***************************************************************/
EXTERN int net_closesocket(FAR struct socket *psock); EXTERN int psock_close(FAR struct socket *psock);
/* sockopt support ***********************************************************/ /* sockopt support ***********************************************************/
@@ -206,6 +207,11 @@ EXTERN void arptimer_init(void);
# define arptimer_init() # define arptimer_init()
#endif #endif
/* send.c ********************************************************************/
EXTERN ssize_t psock_send(FAR struct socket *psock, const void *buf,
size_t len, int flags);
#undef EXTERN #undef EXTERN
#if defined(__cplusplus) #if defined(__cplusplus)
} }
+2 -2
View File
@@ -1,8 +1,8 @@
/**************************************************************************** /****************************************************************************
* net/net_poll.c * net/net_poll.c
* *
* Copyright (C) 2008-2009, 2011 Gregory Nutt. All rights reserved. * Copyright (C) 2008-2009, 2011-2012 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <spudmonkey@racsa.co.cr> * Author: Gregory Nutt <gnutt@nuttx.org>
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
+4 -4
View File
@@ -1,8 +1,8 @@
/**************************************************************************** /****************************************************************************
* net/net_sockets.c * net/net_sockets.c
* *
* Copyright (C) 2007-2009, 2011 Gregory Nutt. All rights reserved. * Copyright (C) 2007-2009, 2011-2012 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <spudmonkey@racsa.co.cr> * Author: Gregory Nutt <gnutt@nuttx.org>
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@@ -186,7 +186,7 @@ int net_releaselist(FAR struct socketlist *list)
if (crefs <= 0) if (crefs <= 0)
{ {
/* Close each open socket in the list /* Close each open socket in the list
* REVISIT: net_closesocket() will attempt to use semaphores. * REVISIT: psock_close() will attempt to use semaphores.
* If we actually are in the IDLE thread, then could this cause * If we actually are in the IDLE thread, then could this cause
* problems? Probably not, it the task has exited and crefs is * problems? Probably not, it the task has exited and crefs is
* zero, then there probably could not be a contender for the * zero, then there probably could not be a contender for the
@@ -198,7 +198,7 @@ int net_releaselist(FAR struct socketlist *list)
FAR struct socket *psock = &list->sl_sockets[ndx]; FAR struct socket *psock = &list->sl_sockets[ndx];
if (psock->s_crefs > 0) if (psock->s_crefs > 0)
{ {
(void)net_closesocket(psock); (void)psock_close(psock);
} }
} }
+2 -2
View File
@@ -1,8 +1,8 @@
/**************************************************************************** /****************************************************************************
* net/recv.c * net/recv.c
* *
* Copyright (C) 2007, 2008 Gregory Nutt. All rights reserved. * Copyright (C) 2007, 2008, 2012 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <spudmonkey@racsa.co.cr> * Author: Gregory Nutt <gnutt@nuttx.org>
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
+73 -10
View File
@@ -1,8 +1,8 @@
/**************************************************************************** /****************************************************************************
* net/recvfrom.c * net/recvfrom.c
* *
* Copyright (C) 2007-2009, 2011 Gregory Nutt. All rights reserved. * Copyright (C) 2007-2009, 2011-2012 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <spudmonkey@racsa.co.cr> * Author: Gregory Nutt <gnutt@nuttx.org>
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@@ -988,7 +988,7 @@ static ssize_t tcp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len,
****************************************************************************/ ****************************************************************************/
/**************************************************************************** /****************************************************************************
* Function: recvfrom * Function: psock_recvfrom
* *
* Description: * Description:
* recvfrom() receives messages from a socket, and may be used to receive * recvfrom() receives messages from a socket, and may be used to receive
@@ -1000,7 +1000,7 @@ static ssize_t tcp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len,
* on return to indicate the actual size of the address stored there. * on return to indicate the actual size of the address stored there.
* *
* Parameters: * Parameters:
* sockfd Socket descriptor of socket * psock A pointer to a NuttX-specific, internal socket structure
* buf Buffer to receive data * buf Buffer to receive data
* len Length of buffer * len Length of buffer
* flags Receive flags * flags Receive flags
@@ -1039,11 +1039,10 @@ static ssize_t tcp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len,
* *
****************************************************************************/ ****************************************************************************/
ssize_t recvfrom(int sockfd, FAR void *buf, size_t len, int flags, ssize_t psock_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len,
FAR struct sockaddr *from, FAR socklen_t *fromlen) int flags,FAR struct sockaddr *from,
FAR socklen_t *fromlen)
{ {
FAR struct socket *psock;
#if defined(CONFIG_NET_UDP) || defined(CONFIG_NET_TCP) #if defined(CONFIG_NET_UDP) || defined(CONFIG_NET_TCP)
#ifdef CONFIG_NET_IPv6 #ifdef CONFIG_NET_IPv6
FAR struct sockaddr_in6 *infrom = (struct sockaddr_in6 *)from; FAR struct sockaddr_in6 *infrom = (struct sockaddr_in6 *)from;
@@ -1065,10 +1064,8 @@ ssize_t recvfrom(int sockfd, FAR void *buf, size_t len, int flags,
} }
#endif #endif
/* Get the underlying socket structure */
/* Verify that the sockfd corresponds to valid, allocated socket */ /* Verify that the sockfd corresponds to valid, allocated socket */
psock = sockfd_socket(sockfd);
if (!psock || psock->s_crefs <= 0) if (!psock || psock->s_crefs <= 0)
{ {
err = EBADF; err = EBADF;
@@ -1136,4 +1133,70 @@ errout:
return ERROR; return ERROR;
} }
/****************************************************************************
* Function: recvfrom
*
* Description:
* recvfrom() receives messages from a socket, and may be used to receive
* data on a socket whether or not it is connection-oriented.
*
* If from is not NULL, and the underlying protocol provides the source
* address, this source address is filled in. The argument fromlen
* initialized to the size of the buffer associated with from, and modified
* on return to indicate the actual size of the address stored there.
*
* Parameters:
* sockfd Socket descriptor of socket
* buf Buffer to receive data
* len Length of buffer
* flags Receive flags
* from Address of source (may be NULL)
* fromlen The length of the address structure
*
* Returned Value:
* On success, returns the number of characters sent. On error,
* -1 is returned, and errno is set appropriately:
*
* EAGAIN
* The socket is marked non-blocking and the receive operation would block,
* or a receive timeout had been set and the timeout expired before data
* was received.
* EBADF
* The argument sockfd is an invalid descriptor.
* ECONNREFUSED
* A remote host refused to allow the network connection (typically because
* it is not running the requested service).
* EFAULT
* The receive buffer pointer(s) point outside the process's address space.
* EINTR
* The receive was interrupted by delivery of a signal before any data were
* available.
* EINVAL
* Invalid argument passed.
* ENOMEM
* Could not allocate memory.
* ENOTCONN
* The socket is associated with a connection-oriented protocol and has
* not been connected.
* ENOTSOCK
* The argument sockfd does not refer to a socket.
*
* Assumptions:
*
****************************************************************************/
ssize_t recvfrom(int sockfd, FAR void *buf, size_t len, int flags,
FAR struct sockaddr *from, FAR socklen_t *fromlen)
{
FAR struct socket *psock;
/* Get the underlying socket structure */
psock = sockfd_socket(sockfd);
/* Then let psock_recvfrom() do all of the work */
return psock_recvfrom(psock, buf, len, flags, from, fromlen);
}
#endif /* CONFIG_NET */ #endif /* CONFIG_NET */
+74 -6
View File
@@ -1,8 +1,8 @@
/**************************************************************************** /****************************************************************************
* net/send.c * net/send.c
* *
* Copyright (C) 2007-2011 Gregory Nutt. All rights reserved. * Copyright (C) 2007-2012 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <spudmonkey@racsa.co.cr> * Author: Gregory Nutt <gnutt@nuttx.org>
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@@ -336,7 +336,7 @@ end_wait:
****************************************************************************/ ****************************************************************************/
/**************************************************************************** /****************************************************************************
* Function: send * Function: psock_send
* *
* Description: * Description:
* The send() call may be used only when the socket is in a connected state * The send() call may be used only when the socket is in a connected state
@@ -346,7 +346,7 @@ end_wait:
* equivalent to sendto(sockfd,buf,len,flags,NULL,0). * equivalent to sendto(sockfd,buf,len,flags,NULL,0).
* *
* Parameters: * Parameters:
* sockfd Socket descriptor of socket * psock And instance of the internal socket structure.
* buf Data to send * buf Data to send
* len Length of data to send * len Length of data to send
* flags Send flags * flags Send flags
@@ -399,9 +399,8 @@ end_wait:
* *
****************************************************************************/ ****************************************************************************/
ssize_t send(int sockfd, const void *buf, size_t len, int flags) ssize_t psock_send(FAR struct socket *psock, const void *buf, size_t len, int flags)
{ {
FAR struct socket *psock = sockfd_socket(sockfd);
struct send_s state; struct send_s state;
uip_lock_t save; uip_lock_t save;
int err; int err;
@@ -525,4 +524,73 @@ errout:
return ERROR; return ERROR;
} }
/****************************************************************************
* Function: send
*
* Description:
* The send() call may be used only when the socket is in a connected state
* (so that the intended recipient is known). The only difference between
* send() and write() is the presence of flags. With zero flags parameter,
* send() is equivalent to write(). Also, send(sockfd,buf,len,flags) is
* equivalent to sendto(sockfd,buf,len,flags,NULL,0).
*
* Parameters:
* sockfd Socket descriptor of socket
* buf Data to send
* len Length of data to send
* flags Send flags
*
* Returned Value:
* On success, returns the number of characters sent. On error,
* -1 is returned, and errno is set appropriately:
*
* EAGAIN or EWOULDBLOCK
* The socket is marked non-blocking and the requested operation
* would block.
* EBADF
* An invalid descriptor was specified.
* ECONNRESET
* Connection reset by peer.
* EDESTADDRREQ
* The socket is not connection-mode, and no peer address is set.
* EFAULT
* An invalid user space address was specified for a parameter.
* EINTR
* A signal occurred before any data was transmitted.
* EINVAL
* Invalid argument passed.
* EISCONN
* The connection-mode socket was connected already but a recipient
* was specified. (Now either this error is returned, or the recipient
* specification is ignored.)
* EMSGSIZE
* The socket type requires that message be sent atomically, and the
* size of the message to be sent made this impossible.
* ENOBUFS
* The output queue for a network interface was full. This generally
* indicates that the interface has stopped sending, but may be
* caused by transient congestion.
* ENOMEM
* No memory available.
* ENOTCONN
* The socket is not connected, and no target has been given.
* ENOTSOCK
* The argument s is not a socket.
* EOPNOTSUPP
* Some bit in the flags argument is inappropriate for the socket
* type.
* EPIPE
* The local end has been shut down on a connection oriented socket.
* In this case the process will also receive a SIGPIPE unless
* MSG_NOSIGNAL is set.
*
* Assumptions:
*
****************************************************************************/
ssize_t send(int sockfd, const void *buf, size_t len, int flags)
{
return psock_send(sockfd_socket(sockfd), buf, len, flags);
}
#endif /* CONFIG_NET && CONFIG_NET_TCP */ #endif /* CONFIG_NET && CONFIG_NET_TCP */
+88 -11
View File
@@ -1,8 +1,8 @@
/**************************************************************************** /****************************************************************************
* net/sendto.c * net/sendto.c
* *
* Copyright (C) 2007-2009, 2011 Gregory Nutt. All rights reserved. * Copyright (C) 2007-2009, 2011-2012 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <spudmonkey@racsa.co.cr> * Author: Gregory Nutt <gnutt@nuttx.org>
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@@ -157,7 +157,7 @@ static uint16_t sendto_interrupt(struct uip_driver_s *dev, void *conn,
****************************************************************************/ ****************************************************************************/
/**************************************************************************** /****************************************************************************
* Function: sendto * Function: psock_sendto
* *
* Description: * Description:
* If sendto() is used on a connection-mode (SOCK_STREAM, SOCK_SEQPACKET) * If sendto() is used on a connection-mode (SOCK_STREAM, SOCK_SEQPACKET)
@@ -166,7 +166,7 @@ static uint16_t sendto_interrupt(struct uip_driver_s *dev, void *conn,
* returned when the socket was not actually connected. * returned when the socket was not actually connected.
* *
* Parameters: * Parameters:
* sockfd Socket descriptor of socket * psock A pointer to a NuttX-specific, internal socket structure
* buf Data to send * buf Data to send
* len Length of data to send * len Length of data to send
* flags Send flags * flags Send flags
@@ -221,10 +221,10 @@ static uint16_t sendto_interrupt(struct uip_driver_s *dev, void *conn,
* *
****************************************************************************/ ****************************************************************************/
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, ssize_t psock_sendto(FAR struct socket *psock, FAR const void *buf,
const struct sockaddr *to, socklen_t tolen) size_t len, int flags, FAR const struct sockaddr *to,
socklen_t tolen)
{ {
FAR struct socket *psock;
#ifdef CONFIG_NET_UDP #ifdef CONFIG_NET_UDP
FAR struct uip_udp_conn *conn; FAR struct uip_udp_conn *conn;
#ifdef CONFIG_NET_IPv6 #ifdef CONFIG_NET_IPv6
@@ -245,7 +245,7 @@ ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
if (!to || !tolen) if (!to || !tolen)
{ {
#ifdef CONFIG_NET_TCP #ifdef CONFIG_NET_TCP
return send(sockfd, buf, len, flags); return psock_send(psock, buf, len, flags);
#else #else
err = EINVAL; err = EINVAL;
goto errout; goto errout;
@@ -264,10 +264,8 @@ ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
goto errout; goto errout;
} }
/* Get the underlying socket structure */ /* Verify that the psock corresponds to valid, allocated socket */
/* Verify that the sockfd corresponds to valid, allocated socket */
psock = sockfd_socket(sockfd);
if (!psock || psock->s_crefs <= 0) if (!psock || psock->s_crefs <= 0)
{ {
err = EBADF; err = EBADF;
@@ -369,4 +367,83 @@ errout:
return ERROR; return ERROR;
} }
/****************************************************************************
* Function: sendto
*
* Description:
* If sendto() is used on a connection-mode (SOCK_STREAM, SOCK_SEQPACKET)
* socket, the parameters to and 'tolen' are ignored (and the error EISCONN
* may be returned when they are not NULL and 0), and the error ENOTCONN is
* returned when the socket was not actually connected.
*
* Parameters:
* sockfd Socket descriptor of socket
* buf Data to send
* len Length of data to send
* flags Send flags
* to Address of recipient
* tolen The length of the address structure
*
* Returned Value:
* On success, returns the number of characters sent. On error,
* -1 is returned, and errno is set appropriately:
*
* EAGAIN or EWOULDBLOCK
* The socket is marked non-blocking and the requested operation
* would block.
* EBADF
* An invalid descriptor was specified.
* ECONNRESET
* Connection reset by peer.
* EDESTADDRREQ
* The socket is not connection-mode, and no peer address is set.
* EFAULT
* An invalid user space address was specified for a parameter.
* EINTR
* A signal occurred before any data was transmitted.
* EINVAL
* Invalid argument passed.
* EISCONN
* The connection-mode socket was connected already but a recipient
* was specified. (Now either this error is returned, or the recipient
* specification is ignored.)
* EMSGSIZE
* The socket type requires that message be sent atomically, and the
* size of the message to be sent made this impossible.
* ENOBUFS
* The output queue for a network interface was full. This generally
* indicates that the interface has stopped sending, but may be
* caused by transient congestion.
* ENOMEM
* No memory available.
* ENOTCONN
* The socket is not connected, and no target has been given.
* ENOTSOCK
* The argument s is not a socket.
* EOPNOTSUPP
* Some bit in the flags argument is inappropriate for the socket
* type.
* EPIPE
* The local end has been shut down on a connection oriented socket.
* In this case the process will also receive a SIGPIPE unless
* MSG_NOSIGNAL is set.
*
* Assumptions:
*
****************************************************************************/
ssize_t sendto(int sockfd, FAR const void *buf, size_t len, int flags,
FAR const struct sockaddr *to, socklen_t tolen)
{
FAR struct socket *psock;
/* Get the underlying socket structure */
psock = sockfd_socket(sockfd);
/* And let psock_sendto do all of the work */
return psock_sendto(psock, buf, len, flags, to, tolen);
}
#endif /* CONFIG_NET */ #endif /* CONFIG_NET */