mq_notify() was not setting errno on failures

git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@4133 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
patacongo
2011-12-04 18:08:33 +00:00
parent bc29aea397
commit 655afdb84e
2 changed files with 92 additions and 50 deletions
+2
View File
@@ -2233,3 +2233,5 @@
corresponding sans serif bold fonts. corresponding sans serif bold fonts.
* drivers/input/ads7843e.c and tsc2007.c: Fix some errors in the poll * drivers/input/ads7843e.c and tsc2007.c: Fix some errors in the poll
setup error checking that was cloned into both drivers. setup error checking that was cloned into both drivers.
* sched/mq_notify.c: Set errno appropriately on failures. There are
still severl message queue functions that do not set errno!
+56 -16
View File
@@ -1,7 +1,7 @@
/************************************************************************ /************************************************************************
* sched/mq_notify.c * sched/mq_notify.c
* *
* Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved. * Copyright (C) 2007, 2009, 2011 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <spudmonkey@racsa.co.cr> * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@@ -42,6 +42,8 @@
#include <signal.h> #include <signal.h>
#include <mqueue.h> #include <mqueue.h>
#include <sched.h> #include <sched.h>
#include <errno.h>
#include "os_internal.h" #include "os_internal.h"
#include "mq_internal.h" #include "mq_internal.h"
@@ -95,7 +97,17 @@
* sigev_value - Value associated with the signal * sigev_value - Value associated with the signal
* *
* Return Value: * Return Value:
* None * On success mq_notify() returns 0; on error, -1 is returned, with
* errno set to indicate the error.
*
* EBADF The descriptor specified in mqdes is invalid.
* EBUSY Another process has already registered to receive notification
* for this message queue.
* EINVAL sevp->sigev_notify is not one of the permitted values; or
* sevp->sigev_notify is SIGEV_SIGNAL and sevp->sigev_signo is not a
* valid signal number.
* ENOMEM
* Insufficient memory.
* *
* Assumptions: * Assumptions:
* *
@@ -117,14 +129,21 @@ int mq_notify(mqd_t mqdes, const struct sigevent *notification)
{ {
_TCB *rtcb; _TCB *rtcb;
msgq_t *msgq; msgq_t *msgq;
int ret = ERROR; int errval;
if (mqdes) /* Was a valid message queue descriptor provided? */
if (!mqdes)
{ {
sched_lock(); /* No.. return EBADF */
errval = EBADF;
goto errout;
}
/* Get a pointer to the message queue */ /* Get a pointer to the message queue */
sched_lock();
msgq = mqdes->msgq; msgq = mqdes->msgq;
/* Get the current process ID */ /* Get the current process ID */
@@ -135,19 +154,26 @@ int mq_notify(mqd_t mqdes, const struct sigevent *notification)
if (!msgq->ntmqdes) if (!msgq->ntmqdes)
{ {
/* No... Have we been asked to establish one? Make /* No... Have we been asked to establish one? */
* sure a good signal number has been provided
*/
if (notification && GOOD_SIGNO(notification->sigev_signo)) if (notification)
{ {
/* Yes... Was a valid signal number supplied? */
if (!GOOD_SIGNO(notification->sigev_signo))
{
/* No... Return EINVAL */
errval = EINVAL;
goto errout;
}
/* Yes... Assign it to the current task. */ /* Yes... Assign it to the current task. */
msgq->ntvalue.sival_ptr = notification->sigev_value.sival_ptr; msgq->ntvalue.sival_ptr = notification->sigev_value.sival_ptr;
msgq->ntsigno = notification->sigev_signo; msgq->ntsigno = notification->sigev_signo;
msgq->ntpid = rtcb->pid; msgq->ntpid = rtcb->pid;
msgq->ntmqdes = mqdes; msgq->ntmqdes = mqdes;
ret = OK;
} }
} }
@@ -155,18 +181,32 @@ int mq_notify(mqd_t mqdes, const struct sigevent *notification)
* Is it trying to remove it? * Is it trying to remove it?
*/ */
else if ((msgq->ntpid == rtcb->pid) && (!notification)) else if ((msgq->ntpid != rtcb->pid) || (notification))
{ {
/* Yes... Detach the notification */ /* This thread does not own the notification OR it is
* not trying to remove it. Return EBUSY.
*/
errval = EBUSY;
goto errout;
}
else
{
/* Yes, the notification belongs to this thread. Allow the
* thread to detach the notification.
*/
msgq->ntpid = INVALID_PROCESS_ID; msgq->ntpid = INVALID_PROCESS_ID;
msgq->ntsigno = 0; msgq->ntsigno = 0;
msgq->ntvalue.sival_ptr = NULL; msgq->ntvalue.sival_ptr = NULL;
msgq->ntmqdes = NULL; msgq->ntmqdes = NULL;
ret = OK;
}
sched_unlock();
} }
return ret; sched_unlock();
return OK;
errout:
set_errno(errval);
sched_unlock();
return ERROR;
} }