You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by gn...@apache.org on 2019/12/24 14:10:57 UTC
[incubator-nuttx] branch master updated: This change implements the
SO_ERROR socket option that is used to obtain the last error reported by
the network.
This is an automated email from the ASF dual-hosted git repository.
gnutt pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git
The following commit(s) were added to refs/heads/master by this push:
new ce63457 This change implements the SO_ERROR socket option that is used to obtain the last error reported by the network.
ce63457 is described below
commit ce634578ddbdcc1f847eb74fa1efcb69ad3de6e6
Author: liuhuahang <li...@xiaomi.com>
AuthorDate: Tue Dec 24 08:09:55 2019 -0600
This change implements the SO_ERROR socket option that is used to obtain the last error reported by the network.
Squashed commit of the following:
Author: Gregory Nutt <gn...@nuttx.org>
net/: Trivial changes to PR from review. Biggest difference: type of s_error changed to int16_t to save a byte or two.
Author: liuhuahang <li...@xiaomi.com>
Implement SO_ERROR for getsockopt()
---
include/nuttx/net/net.h | 3 ++-
net/socket/accept.c | 2 +-
net/socket/bind.c | 2 +-
net/socket/connect.c | 2 +-
net/socket/getpeername.c | 2 +-
net/socket/getsockname.c | 2 +-
net/socket/getsockopt.c | 15 +++++++++++++--
net/socket/listen.c | 4 ++--
net/socket/net_sendfile.c | 4 ++--
net/socket/recvfrom.c | 15 ++++++++++-----
net/socket/send.c | 11 ++++++++---
net/socket/sendto.c | 2 +-
net/socket/socket.h | 17 +++++++++++++++++
13 files changed, 60 insertions(+), 21 deletions(-)
diff --git a/include/nuttx/net/net.h b/include/nuttx/net/net.h
index 325bb8b..5ad141b 100644
--- a/include/nuttx/net/net.h
+++ b/include/nuttx/net/net.h
@@ -1,7 +1,7 @@
/****************************************************************************
* include/nuttx/net/net.h
*
- * Copyright (C) 2007, 2009-2014, 2016-2018 Gregory Nutt. All rights
+ * Copyright (C) 2007, 2009-2014, 2016-2019 Gregory Nutt. All rights
* reserved.
* Author: Gregory Nutt <gn...@nuttx.org>
*
@@ -234,6 +234,7 @@ struct socket
/* Socket options */
#ifdef CONFIG_NET_SOCKOPTS
+ int16_t s_error; /* Last error that occurred on this socket */
sockopt_t s_options; /* Selected socket options */
socktimeo_t s_rcvtimeo; /* Receive timeout value (in deciseconds) */
socktimeo_t s_sndtimeo; /* Send timeout value (in deciseconds) */
diff --git a/net/socket/accept.c b/net/socket/accept.c
index bcfc368..39ed7a8 100644
--- a/net/socket/accept.c
+++ b/net/socket/accept.c
@@ -302,7 +302,7 @@ errout_with_socket:
errout:
leave_cancellation_point();
- set_errno(errcode);
+ _SO_SETERRNO(psock, errcode);
return ERROR;
}
diff --git a/net/socket/bind.c b/net/socket/bind.c
index 13c6e19..00e0796 100644
--- a/net/socket/bind.c
+++ b/net/socket/bind.c
@@ -159,7 +159,7 @@ int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
ret = psock_bind(psock, addr, addrlen);
if (ret < 0)
{
- set_errno(-ret);
+ _SO_SETERRNO(psock, -ret);
return ERROR;
}
diff --git a/net/socket/connect.c b/net/socket/connect.c
index 9e2c9aa..3fdaac8 100644
--- a/net/socket/connect.c
+++ b/net/socket/connect.c
@@ -246,7 +246,7 @@ int connect(int sockfd, FAR const struct sockaddr *addr, socklen_t addrlen)
ret = psock_connect(psock, addr, addrlen);
if (ret < 0)
{
- set_errno(-ret);
+ _SO_SETERRNO(psock, -ret);
ret = ERROR;
}
diff --git a/net/socket/getpeername.c b/net/socket/getpeername.c
index 0988032..4181117 100644
--- a/net/socket/getpeername.c
+++ b/net/socket/getpeername.c
@@ -169,7 +169,7 @@ int getpeername(int sockfd, FAR struct sockaddr *addr, FAR socklen_t *addrlen)
ret = psock_getpeername(psock, addr, addrlen);
if (ret < 0)
{
- set_errno(-ret);
+ _SO_SETERRNO(psock, -ret);
return ERROR;
}
diff --git a/net/socket/getsockname.c b/net/socket/getsockname.c
index d267278..bed6217 100644
--- a/net/socket/getsockname.c
+++ b/net/socket/getsockname.c
@@ -165,7 +165,7 @@ int getsockname(int sockfd, FAR struct sockaddr *addr, FAR socklen_t *addrlen)
ret = psock_getsockname(psock, addr, addrlen);
if (ret < 0)
{
- set_errno(-ret);
+ _SO_SETERRNO(psock, -ret);
return ERROR;
}
diff --git a/net/socket/getsockopt.c b/net/socket/getsockopt.c
index d027da2..487642c 100644
--- a/net/socket/getsockopt.c
+++ b/net/socket/getsockopt.c
@@ -1,7 +1,7 @@
/****************************************************************************
* net/socket/getsockopt.c
*
- * Copyright (C) 2007-2009, 2012, 2014, 2017-2018 Gregory Nutt. All rights
+ * Copyright (C) 2007-2009, 2012, 2014, 2017-2019 Gregory Nutt. All rights
* reserved.
* Author: Gregory Nutt <gn...@nuttx.org>
*
@@ -261,10 +261,21 @@ static int psock_socketlevel_option(FAR struct socket *psock, int option,
}
break;
+ case SO_ERROR: /* Reports and clears error status. */
+ {
+ if (*value_len != sizeof(int))
+ {
+ return -EINVAL;
+ }
+
+ *(FAR int *)value = (int)psock->s_error;
+ psock->s_error = 0;
+ }
+ break;
+
/* The following are not yet implemented (return values other than {0,1) */
case SO_ACCEPTCONN: /* Reports whether socket listening is enabled */
- case SO_ERROR: /* Reports and clears error status. */
case SO_LINGER: /* Lingers on a close() if data is present */
case SO_RCVBUF: /* Sets receive buffer size */
case SO_RCVLOWAT: /* Sets the minimum number of bytes to input */
diff --git a/net/socket/listen.c b/net/socket/listen.c
index 0b3f117..d267b38 100644
--- a/net/socket/listen.c
+++ b/net/socket/listen.c
@@ -164,7 +164,7 @@ int listen(int sockfd, int backlog)
errcode = EBADF;
}
- set_errno(errcode);
+ _SO_SETERRNO(psock, errcode);
return ERROR;
}
@@ -175,7 +175,7 @@ int listen(int sockfd, int backlog)
ret = psock_listen(psock, backlog);
if (ret < 0)
{
- set_errno(-ret);
+ _SO_SETERRNO(psock, -ret);
return ERROR;
}
diff --git a/net/socket/net_sendfile.c b/net/socket/net_sendfile.c
index faf715e..a499504 100644
--- a/net/socket/net_sendfile.c
+++ b/net/socket/net_sendfile.c
@@ -131,7 +131,7 @@ ssize_t net_sendfile(int outfd, FAR struct file *infile, FAR off_t *offset,
if (psock != NULL || psock->s_crefs <= 0)
{
nerr("ERROR: Invalid socket\n");
- set_errno(EBADF);
+ _SO_SETERRNO(psock, EBADF);
return ERROR;
}
@@ -152,7 +152,7 @@ ssize_t net_sendfile(int outfd, FAR struct file *infile, FAR off_t *offset,
if (ret < 0)
{
- set_errno(-ret);
+ _SO_SETERRNO(psock, -ret);
return ERROR;
}
diff --git a/net/socket/recvfrom.c b/net/socket/recvfrom.c
index 4396255..79944c2 100644
--- a/net/socket/recvfrom.c
+++ b/net/socket/recvfrom.c
@@ -1,7 +1,7 @@
/****************************************************************************
* net/socket/recvfrom.c
*
- * Copyright (C) 2007-2009, 2011-2017 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2007-2009, 2011-2017, 2019 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gn...@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@@ -93,7 +93,7 @@ ssize_t psock_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len,
/* Verify that non-NULL pointers were passed */
#ifdef CONFIG_DEBUG_FEATURES
- if (!buf)
+ if (buf == NULL)
{
return -EINVAL;
}
@@ -226,18 +226,23 @@ ssize_t nx_recvfrom(int sockfd, FAR void *buf, size_t len, int flags,
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;
ssize_t ret;
/* recvfrom() is a cancellation point */
(void)enter_cancellation_point();
- /* Let nx_recvfrom and psock_recvfrom() do all of the work */
+ /* Get the underlying socket structure */
+
+ psock = sockfd_socket(sockfd);
+
+ /* Let psock_recvfrom() do all of the work */
- ret = nx_recvfrom(sockfd, buf, len, flags, from, fromlen);
+ ret = psock_recvfrom(psock, buf, len, flags, from, fromlen);
if (ret < 0)
{
- set_errno(-ret);
+ _SO_SETERRNO(psock, -ret);
ret = ERROR;
}
diff --git a/net/socket/send.c b/net/socket/send.c
index 7d95a6f..f75fdc3 100644
--- a/net/socket/send.c
+++ b/net/socket/send.c
@@ -225,18 +225,23 @@ ssize_t nx_send(int sockfd, FAR const void *buf, size_t len, int flags)
ssize_t send(int sockfd, FAR const void *buf, size_t len, int flags)
{
+ FAR struct socket *psock;
ssize_t ret;
/* send() is a cancellation point */
(void)enter_cancellation_point();
- /* Let nx_send() and psock_send() do all of the work */
+ /* Get the underlying socket structure */
+
+ psock = sockfd_socket(sockfd);
+
+ /* Let psock_send() do all of the work */
- ret = nx_send(sockfd, buf, len, flags);
+ ret = psock_send(psock, buf, len, flags);
if (ret < 0)
{
- set_errno((int)-ret);
+ _SO_SETERRNO(psock, -ret);
ret = ERROR;
}
diff --git a/net/socket/sendto.c b/net/socket/sendto.c
index dbbe701..417afb9 100644
--- a/net/socket/sendto.c
+++ b/net/socket/sendto.c
@@ -254,7 +254,7 @@ ssize_t sendto(int sockfd, FAR const void *buf, size_t len, int flags,
ret = psock_sendto(psock, buf, len, flags, to, tolen);
if (ret < 0)
{
- set_errno((int)-ret);
+ _SO_SETERRNO(psock, -ret);
ret = ERROR;
}
diff --git a/net/socket/socket.h b/net/socket/socket.h
index 608e44a..f826337 100644
--- a/net/socket/socket.h
+++ b/net/socket/socket.h
@@ -131,6 +131,23 @@
#define _SO_GETVALID(o) (((unsigned int)(o)) <= _SO_MAXOPT)
#define _SO_SETVALID(o) ((((unsigned int)(o)) <= _SO_MAXOPT) && !_SO_GETONLY(o))
+/* Macro to set socket errors */
+
+#ifdef CONFIG_NET_SOCKOPTS
+# define _SO_SETERRNO(s,e) \
+ do \
+ { \
+ if (s != NULL) \
+ { \
+ s->s_error = (int16_t)e; \
+ } \
+ set_errno(e); \
+ } \
+ while (0)
+#else
+# define _SO_SETERRNO(s,e) set_errno(e)
+#endif /* CONFIG_NET_SOCKOPTS */
+
/****************************************************************************
* Public Data
****************************************************************************/