Fix places where the errno value was being overwritten by subsequent actions so that the returned errno value was incorrect. From Max Neklyudov.
This commit is contained in:
parent
4521e082a9
commit
127951e029
@ -103,6 +103,7 @@ int select(int nfds, FAR fd_set *readfds, FAR fd_set *writefds,
|
||||
FAR fd_set *exceptfds, FAR struct timeval *timeout)
|
||||
{
|
||||
struct pollfd *pollset;
|
||||
int errcode;
|
||||
int fd;
|
||||
int npfds;
|
||||
int msec;
|
||||
@ -198,6 +199,12 @@ int select(int nfds, FAR fd_set *readfds, FAR fd_set *writefds,
|
||||
/* Then let poll do all of the real work. */
|
||||
|
||||
ret = poll(pollset, npfds, msec);
|
||||
if (ret < 0)
|
||||
{
|
||||
/* poll() failed! Save the errno value */
|
||||
|
||||
errcode = get_errno();
|
||||
}
|
||||
|
||||
/* Now set up the return values */
|
||||
|
||||
@ -263,6 +270,16 @@ int select(int nfds, FAR fd_set *readfds, FAR fd_set *writefds,
|
||||
}
|
||||
|
||||
kmm_free(pollset);
|
||||
|
||||
/* Did poll() fail above? */
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
/* Yes.. restore the errno value */
|
||||
|
||||
set_errno(errcode);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -167,7 +167,7 @@ int sem_timedwait(FAR sem_t *sem, FAR const struct timespec *abstime)
|
||||
FAR struct tcb_s *rtcb = (FAR struct tcb_s *)g_readytorun.head;
|
||||
irqstate_t flags;
|
||||
int ticks;
|
||||
int err;
|
||||
int errcode;
|
||||
int ret = ERROR;
|
||||
|
||||
DEBUGASSERT(up_interrupt_context() == false && rtcb->waitdog == NULL);
|
||||
@ -179,7 +179,7 @@ int sem_timedwait(FAR sem_t *sem, FAR const struct timespec *abstime)
|
||||
#ifdef CONFIG_DEBUG
|
||||
if (!abstime || !sem)
|
||||
{
|
||||
err = EINVAL;
|
||||
errcode = EINVAL;
|
||||
goto errout;
|
||||
}
|
||||
#endif
|
||||
@ -192,7 +192,7 @@ int sem_timedwait(FAR sem_t *sem, FAR const struct timespec *abstime)
|
||||
rtcb->waitdog = wd_create();
|
||||
if (!rtcb->waitdog)
|
||||
{
|
||||
err = ENOMEM;
|
||||
errcode = ENOMEM;
|
||||
goto errout;
|
||||
}
|
||||
|
||||
@ -225,7 +225,7 @@ int sem_timedwait(FAR sem_t *sem, FAR const struct timespec *abstime)
|
||||
|
||||
if (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000)
|
||||
{
|
||||
err = EINVAL;
|
||||
errcode = EINVAL;
|
||||
goto errout_disabled;
|
||||
}
|
||||
|
||||
@ -233,31 +233,37 @@ int sem_timedwait(FAR sem_t *sem, FAR const struct timespec *abstime)
|
||||
* disabled here so that this time stays valid until the wait begins.
|
||||
*/
|
||||
|
||||
err = clock_abstime2ticks(CLOCK_REALTIME, abstime, &ticks);
|
||||
errcode = clock_abstime2ticks(CLOCK_REALTIME, abstime, &ticks);
|
||||
|
||||
/* If the time has already expired return immediately. */
|
||||
|
||||
if (err == OK && ticks <= 0)
|
||||
if (errcode == OK && ticks <= 0)
|
||||
{
|
||||
err = ETIMEDOUT;
|
||||
errcode = ETIMEDOUT;
|
||||
goto errout_disabled;
|
||||
}
|
||||
|
||||
/* Handle any time-related errors */
|
||||
|
||||
if (err != OK)
|
||||
if (errcode != OK)
|
||||
{
|
||||
goto errout_disabled;
|
||||
}
|
||||
|
||||
/* Start the watchdog */
|
||||
|
||||
err = OK;
|
||||
errcode = OK;
|
||||
wd_start(rtcb->waitdog, ticks, (wdentry_t)sem_timeout, 1, getpid());
|
||||
|
||||
/* Now perform the blocking wait */
|
||||
|
||||
ret = sem_wait(sem);
|
||||
if (ret < 0)
|
||||
{
|
||||
/* sem_wait() failed. Save the errno value */
|
||||
|
||||
errcode = get_errno();
|
||||
}
|
||||
|
||||
/* Stop the watchdog timer */
|
||||
|
||||
@ -275,6 +281,13 @@ int sem_timedwait(FAR sem_t *sem, FAR const struct timespec *abstime)
|
||||
* cases.
|
||||
*/
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
/* On failure, restore the errno value returned by sem_wait */
|
||||
|
||||
set_errno(errcode);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
/* Error exits */
|
||||
@ -285,6 +298,6 @@ errout_disabled:
|
||||
rtcb->waitdog = NULL;
|
||||
|
||||
errout:
|
||||
set_errno(err);
|
||||
set_errno(errcode);
|
||||
return ERROR;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user