diff --git a/include/nuttx/net/net.h b/include/nuttx/net/net.h index 27a8e2148b8..2e3206de041 100644 --- a/include/nuttx/net/net.h +++ b/include/nuttx/net/net.h @@ -227,6 +227,14 @@ void net_unlock(net_lock_t flags); * Description: * Atomically wait for sem while temporarily releasing g_netlock. * + * Input Parameters: + * sem - A reference to the semaphore to be taken. + * + * Returned value: + * The returned value is the same as sem_wait(): Zero (OK) is returned + * on success; -1 (ERROR) is returned on a failure with the errno value + * set appropriately. + * ****************************************************************************/ #ifdef CONFIG_NET_NOINTS diff --git a/net/socket/accept.c b/net/socket/accept.c index f9ba0dc1382..46622d318ef 100644 --- a/net/socket/accept.c +++ b/net/socket/accept.c @@ -301,6 +301,7 @@ int accept(int sockfd, FAR struct sockaddr *addr, FAR socklen_t *addrlen) { err = EBADF; } + goto errout; } @@ -431,12 +432,25 @@ int accept(int sockfd, FAR struct sockaddr *addr, FAR socklen_t *addrlen) conn->accept = accept_interrupt; /* Wait for the send to complete or an error to occur: NOTES: (1) - * net_lockedwait will also terminate if a signal is received, (2) interrupts - * may be disabled! They will be re-enabled while the task sleeps and - * automatically re-enabled when the task restarts. + * net_lockedwait will also terminate if a signal is received, (2) + * interrupts may be disabled! They will be re-enabled while the + * task sleeps and automatically re-enabled when the task restarts. */ ret = net_lockedwait(&state.acpt_sem); + if (ret < 0) + { + /* The value returned by net_lockedwait() the same as the value + * returned by sem_wait(): Zero (OK) is returned on success; -1 + * (ERROR) is returned on a failure with the errno value set + * appropriately. + * + * We have to preserve the errno value here because it may be + * altered by intervening operations. + */ + + err = get_errno(); + } /* Make sure that no further interrupts are processed */ @@ -449,7 +463,7 @@ int accept(int sockfd, FAR struct sockaddr *addr, FAR socklen_t *addrlen) psock->s_flags = _SS_SETSTATE(psock->s_flags, _SF_IDLE); - /* Check for a errors. Errors are signaled by negative errno values + /* Check for a errors. Errors are signalled by negative errno values * for the send length. */ @@ -459,13 +473,13 @@ int accept(int sockfd, FAR struct sockaddr *addr, FAR socklen_t *addrlen) goto errout_with_lock; } - /* If net_lockedwait failed, then we were probably reawakened by a signal. In - * this case, net_lockedwait will have set errno appropriately. + /* If net_lockedwait failed, then we were probably reawakened by a + * signal. In this case, logic above will have set 'err' to the + * ernno value returned by net_lockedwait(). */ if (ret < 0) { - err = -ret; goto errout_with_lock; } } @@ -493,7 +507,7 @@ errout_with_socket: sockfd_release(newfd); errout: - errno = err; + set_errno(err); return ERROR; } diff --git a/net/utils/net_lock.c b/net/utils/net_lock.c index e0446690a78..a8ee355ab02 100644 --- a/net/utils/net_lock.c +++ b/net/utils/net_lock.c @@ -1,7 +1,7 @@ /**************************************************************************** * net/utils/net_lock.c * - * Copyright (C) 2011-2012, 2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2011-2012, 2014-2015 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -178,6 +178,14 @@ void net_unlock(net_lock_t flags) * Description: * Atomically wait for sem while temporarily releasing g_netlock. * + * Input Parameters: + * sem - A reference to the semaphore to be taken. + * + * Returned value: + * The returned value is the same as sem_wait(): Zero (OK) is returned + * on success; -1 (ERROR) is returned on a failure with the errno value + * set appropriately. + * ****************************************************************************/ int net_lockedwait(sem_t *sem)