source: rtems/cpukit/posix/src/mqueuecreatesupp.c @ f26145b

4.104.114.84.95
Last change on this file since f26145b was 58accdd, checked in by Joel Sherrill <joel.sherrill@…>, on 05/21/04 at 20:11:48

2004-05-21 Joel Sherrill <joel@…>

PR 629/rtems

  • cpukit/src/mqueuecreatesupp.c: Return EINVAL is mq_maxmsg is <= 0, not <.
  • Property mode set to 100644
File size: 4.5 KB
Line 
1/*
2 *  NOTE:  The structure of the routines is identical to that of POSIX
3 *         Message_queues to leave the option of having unnamed message
4 *         queues at a future date.  They are currently not part of the
5 *         POSIX standard but unnamed message_queues are.  This is also
6 *         the reason for the apparently unnecessary tracking of
7 *         the process_shared attribute.  [In addition to the fact that
8 *         it would be trivial to add pshared to the mq_attr structure
9 *         and have process private message queues.]
10 *
11 *         This code ignores the O_RDONLY/O_WRONLY/O_RDWR flag at open
12 *         time.
13 *
14 *  $Id$
15 */
16
17#if HAVE_CONFIG_H
18#include "config.h"
19#endif
20
21#include <string.h>
22#include <stdarg.h>
23#include <stdlib.h>
24
25#include <pthread.h>
26#include <limits.h>
27#include <errno.h>
28#include <fcntl.h>
29#include <mqueue.h>
30
31#include <rtems/system.h>
32#include <rtems/score/watchdog.h>
33#include <rtems/score/wkspace.h>
34#include <rtems/seterr.h>
35#include <rtems/posix/mqueue.h>
36#include <rtems/posix/time.h>
37
38/* pure ANSI mode does not have this prototype */
39size_t strnlen(const char *, size_t);
40
41/*PAGE
42 *
43 *  _POSIX_Message_queue_Create_support
44 *
45 *  This routine does the actual creation and initialization of
46 *  a poxix message queue.
47 */
48
49int _POSIX_Message_queue_Create_support(
50  const char                    *name_arg,
51  int                            pshared,
52  struct mq_attr                *attr_ptr,
53  POSIX_Message_queue_Control  **message_queue
54)
55{
56  POSIX_Message_queue_Control   *the_mq;
57  CORE_message_queue_Attributes *the_mq_attr;
58  struct mq_attr                 attr;
59  char                          *name;
60  size_t                         n;
61
62  n = strnlen( name_arg, NAME_MAX );
63  if ( n > NAME_MAX )
64    return ENAMETOOLONG;
65
66  _Thread_Disable_dispatch();
67
68  /*
69   *  There is no real basis for the default values.  They will work
70   *  but were not compared against any existing implementation for
71   *  compatibility.  See README.mqueue for an example program we
72   *  think will print out the defaults.  Report anything you find with it.
73   */
74
75  if ( attr_ptr == NULL ) {
76    attr.mq_maxmsg  = 10;
77    attr.mq_msgsize = 16;
78  } else {
79    if ( attr_ptr->mq_maxmsg <= 0 ){
80      _Thread_Enable_dispatch();
81      rtems_set_errno_and_return_minus_one( EINVAL );
82    }
83
84    if ( attr_ptr->mq_msgsize <= 0 ){
85      _Thread_Enable_dispatch();
86      rtems_set_errno_and_return_minus_one( EINVAL );
87    }
88
89    attr = *attr_ptr;
90  }
91
92#if 0 && defined(RTEMS_MULTIPROCESSING)
93  if ( pshared == PTHREAD_PROCESS_SHARED &&
94       !( _Objects_MP_Allocate_and_open( &_POSIX_Message_queue_Information, 0,
95                            the_mq->Object.id, FALSE ) ) ) {
96    _POSIX_Message_queue_Free( the_mq );
97    _Thread_Enable_dispatch();
98    rtems_set_errno_and_return_minus_one( ENFILE );
99  }
100#endif
101
102  the_mq = _POSIX_Message_queue_Allocate();
103  if ( !the_mq ) {
104    _Thread_Enable_dispatch();
105    rtems_set_errno_and_return_minus_one( ENFILE );
106  }
107
108  the_mq->process_shared  = pshared;
109  the_mq->named = TRUE;
110  the_mq->open_count = 1;
111  the_mq->linked = TRUE;
112
113  /*
114   * Make a copy of the user's string for name just in case it was
115   * dynamically constructed.
116   */
117
118  name = _Workspace_Allocate(n);
119  if (!name) {
120    _POSIX_Message_queue_Free( the_mq );
121    _Thread_Enable_dispatch();
122    rtems_set_errno_and_return_minus_one( ENOMEM );
123  }
124  strcpy( name, name_arg );
125
126  /* XXX
127   *
128   *  Note that thread blocking discipline should be based on the
129   *  current scheduling policy.
130   */
131
132  the_mq_attr = &the_mq->Message_queue.Attributes;
133  the_mq_attr->discipline = CORE_MESSAGE_QUEUE_DISCIPLINES_FIFO;
134
135  if ( ! _CORE_message_queue_Initialize(
136           &the_mq->Message_queue,
137           the_mq_attr,
138           attr.mq_maxmsg,
139           attr.mq_msgsize
140      ) ) {
141
142#if 0 && defined(RTEMS_MULTIPROCESSING)
143    if ( pshared == PTHREAD_PROCESS_SHARED )
144      _Objects_MP_Close( &_POSIX_Message_queue_Information, the_mq->Object.id );
145#endif
146
147    _POSIX_Message_queue_Free( the_mq );
148    _Workspace_Free(name);
149    _Thread_Enable_dispatch();
150    rtems_set_errno_and_return_minus_one( ENOSPC );
151  }
152
153  _Objects_Open(
154    &_POSIX_Message_queue_Information,
155    &the_mq->Object,
156    (char *) name
157  );
158
159  *message_queue = the_mq;
160
161#if 0 && defined(RTEMS_MULTIPROCESSING)
162  if ( pshared == PTHREAD_PROCESS_SHARED )
163    _POSIX_Message_queue_MP_Send_process_packet(
164      POSIX_MESSAGE_QUEUE_MP_ANNOUNCE_CREATE,
165      the_mq->Object.id,
166      (char *) name,
167      0                          /* Not used */
168    );
169#endif
170
171  _Thread_Enable_dispatch();
172  return 0;
173}
Note: See TracBrowser for help on using the repository browser.