Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement SO_ERROR for getsockopt() #3

Merged
merged 1 commit into from
Dec 24, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions include/nuttx/net/net.h
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,7 @@ struct 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) */
int s_error; /* Last error that occurred on this socket */
#ifdef CONFIG_NET_SOLINGER
socktimeo_t s_linger; /* Linger timeout value (in deciseconds) */
#endif
Expand Down
2 changes: 1 addition & 1 deletion net/socket/accept.c
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,7 @@ int accept(int sockfd, FAR struct sockaddr *addr, FAR socklen_t *addrlen)
errout:
leave_cancellation_point();

set_errno(errcode);
_SO_SETERRNO(psock, errcode);
return ERROR;
}

2 changes: 1 addition & 1 deletion net/socket/bind.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
2 changes: 1 addition & 1 deletion net/socket/connect.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
2 changes: 1 addition & 1 deletion net/socket/getpeername.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
2 changes: 1 addition & 1 deletion net/socket/getsockname.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
12 changes: 11 additions & 1 deletion net/socket/getsockopt.c
Original file line number Diff line number Diff line change
Expand Up @@ -261,10 +261,20 @@ 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;
}
*(int *)value = 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 */
Expand Down
4 changes: 2 additions & 2 deletions net/socket/listen.c
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ int listen(int sockfd, int backlog)
errcode = EBADF;
}

set_errno(errcode);
_SO_SETERRNO(psock, errcode);
return ERROR;
}

Expand All @@ -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;
}

Expand Down
4 changes: 2 additions & 2 deletions net/socket/net_sendfile.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand All @@ -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;
}

Expand Down
11 changes: 8 additions & 3 deletions net/socket/recvfrom.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
11 changes: 8 additions & 3 deletions net/socket/send.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
2 changes: 1 addition & 1 deletion net/socket/sendto.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
8 changes: 8 additions & 0 deletions net/socket/socket.h
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,14 @@
#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) if (s != NULL) { s->s_error = e; } set_errno(e)
#else
#define _SO_SETERRNO(s,e) set_errno(e)
#endif /* CONFIG_NET_SOCKOPTS */

/****************************************************************************
* Public Data
****************************************************************************/
Expand Down