diff options
author | patacongo <patacongo@7fd9a85b-ad96-42d3-883c-3090e2eb8679> | 2012-03-02 19:57:52 +0000 |
---|---|---|
committer | patacongo <patacongo@7fd9a85b-ad96-42d3-883c-3090e2eb8679> | 2012-03-02 19:57:52 +0000 |
commit | bb41cf1b703eaa552f3769c3fb0f91fdbd3891a4 (patch) | |
tree | 7b52c3598438fa217047a649dacee77294f4b06a /nuttx/net | |
parent | 4f617d5be7d8e6622c825da85f4c7b0b7e81b7c9 (diff) | |
download | px4-firmware-bb41cf1b703eaa552f3769c3fb0f91fdbd3891a4.tar.gz px4-firmware-bb41cf1b703eaa552f3769c3fb0f91fdbd3891a4.tar.bz2 px4-firmware-bb41cf1b703eaa552f3769c3fb0f91fdbd3891a4.zip |
Add more low-level, thread-independent socket interfaces
git-svn-id: https://nuttx.svn.sourceforge.net/svnroot/nuttx/trunk@4445 7fd9a85b-ad96-42d3-883c-3090e2eb8679
Diffstat (limited to 'nuttx/net')
-rw-r--r-- | nuttx/net/bind.c | 66 | ||||
-rw-r--r-- | nuttx/net/getsockopt.c | 93 | ||||
-rw-r--r-- | nuttx/net/net_sockets.c | 1 | ||||
-rw-r--r-- | nuttx/net/setsockopt.c | 99 | ||||
-rw-r--r-- | nuttx/net/socket.c | 113 |
5 files changed, 290 insertions, 82 deletions
diff --git a/nuttx/net/bind.c b/nuttx/net/bind.c index e0e9676dd..da912e017 100644 --- a/nuttx/net/bind.c +++ b/nuttx/net/bind.c @@ -1,8 +1,8 @@ /**************************************************************************** * net/bind.c * - * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt <spudmonkey@racsa.co.cr> + * Copyright (C) 2007-2009, 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 @@ -51,16 +51,16 @@ ****************************************************************************/ /**************************************************************************** - * Function: bind + * Function: psock_bind * * Description: - * bind() gives the socket 'sockfd' the local address 'addr'. 'addr' is + * bind() gives the socket 'psock' the local address 'addr'. 'addr' is * 'addrlen' bytes long. Traditionally, this is called "assigning a name to * a socket." When a socket is created with socket, it exists in a name * space (address family) but has no name assigned. * * Parameters: - * sockfd Socket descriptor from socket + * psock Socket structure of the socket to bind * addr Socket local address * addrlen Length of 'addr' * @@ -71,21 +71,18 @@ * The address is protected, and the user is not the superuser. * EADDRINUSE * The given address is already in use. - * EBADF - * sockfd is not a valid descriptor. * EINVAL * The socket is already bound to an address. * ENOTSOCK - * sockfd is a descriptor for a file, not a socket. + * psock is a descriptor for a file, not a socket. * * Assumptions: * ****************************************************************************/ -int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen) +int psock_bind(FAR struct socket *psock, const struct sockaddr *addr, + socklen_t addrlen) { - FAR struct socket *psock = sockfd_socket(sockfd); - #if defined(CONFIG_NET_TCP) || defined(CONFIG_NET_UDP) #ifdef CONFIG_NET_IPv6 FAR const struct sockaddr_in6 *inaddr = (const struct sockaddr_in6 *)addr; @@ -97,11 +94,11 @@ int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen) int err; int ret; - /* Verify that the sockfd corresponds to valid, allocated socket */ + /* Verify that the psock corresponds to valid, allocated socket */ if (!psock || psock->s_crefs <= 0) { - err = EBADF; + err = ENOTSOCK; goto errout; } @@ -154,4 +151,47 @@ errout: return ERROR; } +/**************************************************************************** + * Function: bind + * + * Description: + * bind() gives the socket 'sockfd' the local address 'addr'. 'addr' is + * 'addrlen' bytes long. Traditionally, this is called "assigning a name to + * a socket." When a socket is created with socket, it exists in a name + * space (address family) but has no name assigned. + * + * Parameters: + * sockfd Socket descriptor of the socket to bind + * addr Socket local address + * addrlen Length of 'addr' + * + * Returned Value: + * 0 on success; -1 on error with errno set appropriately + * + * EACCES + * The address is protected, and the user is not the superuser. + * EADDRINUSE + * The given address is already in use. + * EBADF + * sockfd is not a valid descriptor. + * EINVAL + * The socket is already bound to an address. + * ENOTSOCK + * sockfd is a descriptor for a file, not a socket. + * + * Assumptions: + * + ****************************************************************************/ + +int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen) +{ + /* Make the socket descriptor to the underlying socket structure */ + + FAR struct socket *psock = sockfd_socket(sockfd); + + /* Then let psock_bind do all of the work */ + + return psock_bind(psock, addr, addrlen); +} + #endif /* CONFIG_NET */ diff --git a/nuttx/net/getsockopt.c b/nuttx/net/getsockopt.c index 94cfb5ec7..c3afb29c9 100644 --- a/nuttx/net/getsockopt.c +++ b/nuttx/net/getsockopt.c @@ -1,8 +1,8 @@ /**************************************************************************** * net/getsockopt.c * - * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt <spudmonkey@racsa.co.cr> + * Copyright (C) 2007-2009, 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 @@ -51,11 +51,11 @@ ****************************************************************************/ /**************************************************************************** - * Function: getsockopt + * Function: psock_getsockopt * * Description: * getsockopt() retrieve thse value for the option specified by the - * 'option' argument for the socket specified by the 'sockfd' argument. If + * 'option' argument for the socket specified by the 'psock' argument. If * the size of the option value is greater than 'value_len', the value * stored in the object pointed to by the 'value' argument will be silently * truncated. Otherwise, the length pointed to by the 'value_len' argument @@ -68,7 +68,7 @@ * See <sys/socket.h> a complete list of values for the 'option' argument. * * Parameters: - * sockfd Socket descriptor of socket + * psock Socket structure of the socket to query * level Protocol level to set the option * option identifies the option to get * value Points to the argument value @@ -76,15 +76,13 @@ * * Returned Value: * - * EBADF - * The 'sockfd' argument is not a valid socket descriptor. * EINVAL * The specified option is invalid at the specified socket 'level' or the * socket has been shutdown. * ENOPROTOOPT * The 'option' is not supported by the protocol. * ENOTSOCK - * The 'sockfd' argument does not refer to a socket. + * The 'psock' argument does not refer to a socket. * ENOBUFS * Insufficient resources are available in the system to complete the * call. @@ -93,21 +91,11 @@ * ****************************************************************************/ -int getsockopt(int sockfd, int level, int option, void *value, socklen_t *value_len) +int psock_getsockopt(FAR struct socket *psock, int level, int option, + FAR void *value, FAR socklen_t *value_len) { - FAR struct socket *psock; int err; - /* Get the underlying socket structure */ - /* Verify that the sockfd corresponds to valid, allocated socket */ - - psock = sockfd_socket(sockfd); - if (!psock || psock->s_crefs <= 0) - { - err = EBADF; - goto errout; - } - /* Verify that the socket option if valid (but might not be supported ) */ if (!_SO_GETVALID(option) || !value || !value_len) @@ -117,6 +105,7 @@ int getsockopt(int sockfd, int level, int option, void *value, socklen_t *value_ } /* Process the option */ + switch (option) { /* The following options take a point to an integer boolean value. @@ -231,8 +220,70 @@ int getsockopt(int sockfd, int level, int option, void *value, socklen_t *value_ return OK; errout: - *get_errno_ptr() = err; + set_errno(err); return ERROR; } +/**************************************************************************** + * Function: getsockopt + * + * Description: + * getsockopt() retrieve thse value for the option specified by the + * 'option' argument for the socket specified by the 'sockfd' argument. If + * the size of the option value is greater than 'value_len', the value + * stored in the object pointed to by the 'value' argument will be silently + * truncated. Otherwise, the length pointed to by the 'value_len' argument + * will be modified to indicate the actual length of the'value'. + * + * The 'level' argument specifies the protocol level of the option. To + * retrieve options at the socket level, specify the level argument as + * SOL_SOCKET. + * + * See <sys/socket.h> a complete list of values for the 'option' argument. + * + * Parameters: + * sockfd Socket descriptor of socket + * level Protocol level to set the option + * option identifies the option to get + * value Points to the argument value + * value_len The length of the argument value + * + * Returned Value: + * + * EBADF + * The 'sockfd' argument is not a valid socket descriptor. + * EINVAL + * The specified option is invalid at the specified socket 'level' or the + * socket has been shutdown. + * ENOPROTOOPT + * The 'option' is not supported by the protocol. + * ENOTSOCK + * The 'sockfd' argument does not refer to a socket. + * ENOBUFS + * Insufficient resources are available in the system to complete the + * call. + * + * Assumptions: + * + ****************************************************************************/ + +int getsockopt(int sockfd, int level, int option, void *value, socklen_t *value_len) +{ + FAR struct socket *psock; + + /* Get the underlying socket structure */ + /* Verify that the sockfd corresponds to valid, allocated socket */ + + psock = sockfd_socket(sockfd); + if (!psock || psock->s_crefs <= 0) + { + set_errno(EBADF); + return ERROR; + } + + /* Then let psock_getsockopt() do all of the work */ + + return psock_getsockopt(psock, level, option, value, value_len); +} + #endif /* CONFIG_NET && CONFIG_NET_SOCKOPTS */ diff --git a/nuttx/net/net_sockets.c b/nuttx/net/net_sockets.c index 0ff4b57ad..05363167c 100644 --- a/nuttx/net/net_sockets.c +++ b/nuttx/net/net_sockets.c @@ -242,6 +242,7 @@ int sockfd_allocate(int minsd) } _net_semgive(list); } + return ERROR; } diff --git a/nuttx/net/setsockopt.c b/nuttx/net/setsockopt.c index f8de93cff..ad52ff53d 100644 --- a/nuttx/net/setsockopt.c +++ b/nuttx/net/setsockopt.c @@ -1,8 +1,8 @@ /**************************************************************************** * net/setsockopt.c * - * Copyright (C) 2007, 2008, 2011 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt <spudmonkey@racsa.co.cr> + * Copyright (C) 2007, 2008, 2011-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 @@ -52,13 +52,12 @@ ****************************************************************************/ /**************************************************************************** - * Function: setsockopt + * Function: psock_setsockopt * * Description: - * setsockopt() sets the option specified by the 'option' argument, + * psock_setsockopt() sets the option specified by the 'option' argument, * at the protocol level specified by the 'level' argument, to the value - * pointed to by the 'value' argument for the socket associated with the - * file descriptor specified by the 'sockfd' argument. + * pointed to by the 'value' argument for the socket on the 'psock' argument. * * The 'level' argument specifies the protocol level of the option. To set * options at the socket level, specify the level argument as SOL_SOCKET. @@ -66,7 +65,7 @@ * See <sys/socket.h> a complete list of values for the 'option' argument. * * Parameters: - * sockfd Socket descriptor of socket + * psock Socket structure of socket to operate on * level Protocol level to set the option * option identifies the option to set * value Points to the argument value @@ -75,8 +74,6 @@ * Returned Value: * 0 on success; -1 on failure * - * EBADF - * The 'sockfd' argument is not a valid socket descriptor. * EDOM * The send and receive timeout values are too big to fit into the * timeout fields in the socket structure. @@ -100,22 +97,12 @@ * ****************************************************************************/ -int setsockopt(int sockfd, int level, int option, const void *value, socklen_t value_len) +int psock_setsockopt(FAR struct socket *psock, int level, int option, + FAR const void *value, socklen_t value_len) { - FAR struct socket *psock; uip_lock_t flags; int err; - /* Get the underlying socket structure */ - /* Verify that the sockfd corresponds to valid, allocated socket */ - - psock = sockfd_socket(sockfd); - if (!psock || psock->s_crefs <= 0) - { - err = EBADF; - goto errout; - } - /* Verify that the socket option if valid (but might not be supported ) */ if (!_SO_SETVALID(option) || !value) @@ -242,8 +229,76 @@ int setsockopt(int sockfd, int level, int option, const void *value, socklen_t v return OK; errout: - *get_errno_ptr() = err; + set_errno(err); return ERROR; } +/**************************************************************************** + * Function: setsockopt + * + * Description: + * setsockopt() sets the option specified by the 'option' argument, + * at the protocol level specified by the 'level' argument, to the value + * pointed to by the 'value' argument for the socket associated with the + * file descriptor specified by the 'sockfd' argument. + * + * The 'level' argument specifies the protocol level of the option. To set + * options at the socket level, specify the level argument as SOL_SOCKET. + * + * See <sys/socket.h> a complete list of values for the 'option' argument. + * + * Parameters: + * sockfd Socket descriptor of socket + * level Protocol level to set the option + * option identifies the option to set + * value Points to the argument value + * value_len The length of the argument value + * + * Returned Value: + * 0 on success; -1 on failure + * + * EBADF + * The 'sockfd' argument is not a valid socket descriptor. + * EDOM + * The send and receive timeout values are too big to fit into the + * timeout fields in the socket structure. + * EINVAL + * The specified option is invalid at the specified socket 'level' or the + * socket has been shut down. + * EISCONN + * The socket is already connected, and a specified option cannot be set + * while the socket is connected. + * ENOPROTOOPT + * The 'option' is not supported by the protocol. + * ENOTSOCK + * The 'sockfd' argument does not refer to a socket. + * ENOMEM + * There was insufficient memory available for the operation to complete. + * ENOBUFS + * Insufficient resources are available in the system to complete the + * call. + * + * Assumptions: + * + ****************************************************************************/ + +int setsockopt(int sockfd, int level, int option, const void *value, socklen_t value_len) +{ + FAR struct socket *psock; + + /* Get the underlying socket structure */ + /* Verify that the sockfd corresponds to valid, allocated socket */ + + psock = sockfd_socket(sockfd); + if (!psock || psock->s_crefs <= 0) + { + set_errno(EBADF); + return ERROR; + } + + /* Then let psock_setockopt() do all of the work */ + + return psock_setsockopt(psock, level, option, value, value_len); +} + #endif /* CONFIG_NET && CONFIG_NET_SOCKOPTS */ diff --git a/nuttx/net/socket.c b/nuttx/net/socket.c index 3bbdd848c..a6befc5d7 100644 --- a/nuttx/net/socket.c +++ b/nuttx/net/socket.c @@ -1,8 +1,8 @@ /**************************************************************************** * net/socket.c * - * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt <spudmonkey@racsa.co.cr> + * Copyright (C) 2007-2009, 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 @@ -52,15 +52,17 @@ ****************************************************************************/ /**************************************************************************** - * Function: socket + * Function: psock_socket * * Description: - * socket() creates an endpoint for communication and returns a descriptor. + * socket() creates an endpoint for communication and returns a socket + * structure. * * Parameters: * domain (see sys/socket.h) * type (see sys/socket.h) * protocol (see sys/socket.h) + * psock A pointer to a user allocated socket structure to be initialized. * * Returned Value: * 0 on success; -1 on error with errno set appropriately @@ -87,10 +89,8 @@ * ****************************************************************************/ -int socket(int domain, int type, int protocol) +int psock_socket(int domain, int type, int protocol, FAR struct socket *psock) { - FAR struct socket *psock; - int sockfd; int err = ENFILE; /* Only PF_INET or PF_INET6 domains supported */ @@ -123,23 +123,7 @@ int socket(int domain, int type, int protocol) goto errout; } - /* Everything looks good. Allocate a socket descriptor */ - - sockfd = sockfd_allocate(0); - if (sockfd < 0) - { - goto errout; /* with err == ENFILE */ - } - - /* Initialize the socket structure */ - - psock = sockfd_socket(sockfd); - if (!psock) - { - err = ENOSYS; /* should not happen */ - goto errout; - } - + /* Everything looks good. Initialize the socket structure */ /* Save the protocol type */ psock->s_type = type; @@ -209,17 +193,94 @@ int socket(int domain, int type, int protocol) { /* Failed to reserve a connection structure */ - sockfd_release(sockfd); goto errout; /* With err == ENFILE or ENOMEM */ } - return sockfd; + return OK; errout: errno = err; return ERROR; } +/**************************************************************************** + * Function: socket + * + * Description: + * socket() creates an endpoint for communication and returns a descriptor. + * + * Parameters: + * domain (see sys/socket.h) + * type (see sys/socket.h) + * protocol (see sys/socket.h) + * + * Returned Value: + * A non-negative socket descriptor on success; -1 on error with errno set + * appropriately. + * + * EACCES + * Permission to create a socket of the specified type and/or protocol + * is denied. + * EAFNOSUPPORT + * The implementation does not support the specified address family. + * EINVAL + * Unknown protocol, or protocol family not available. + * EMFILE + * Process file table overflow. + * ENFILE + * The system limit on the total number of open files has been reached. + * ENOBUFS or ENOMEM + * Insufficient memory is available. The socket cannot be created until + * sufficient resources are freed. + * EPROTONOSUPPORT + * The protocol type or the specified protocol is not supported within + * this domain. + * + * Assumptions: + * + ****************************************************************************/ + +int socket(int domain, int type, int protocol) +{ + FAR struct socket *psock; + int sockfd; + int ret; + + /* Allocate a socket descriptor */ + + sockfd = sockfd_allocate(0); + if (sockfd < 0) + { + set_errno(ENFILE); + return ERROR; + } + + /* Get the underlying socket structure */ + + psock = sockfd_socket(sockfd); + if (!psock) + { + set_errno(ENOSYS); /* should not happen */ + goto errout; + } + + /* Initialize the socket structure */ + + ret = psock_socket(domain, type, protocol, psock); + if (ret < 0) + { + /* Error already set by psock_socket() */ + + goto errout; + } + + return sockfd; + +errout: + sockfd_release(sockfd); + return ERROR; +} + #endif /* CONFIG_NET */ |