* @brief Opens or creates a message queue. * @param name Name of the message queue. * @param oflag Flags indicating the access mode and creation options (O_CREAT, O_EXCL, etc.). * @param ... Additional arguments for creation options (mode, attr) (ignored). * @return Upon successful completion, returns a message queue descriptor (mqd_t); * otherwise, returns (mqd_t)(-1) and s
| 101 | * and returns the file descriptor as a message queue descriptor (mqd_t). |
| 102 | */ |
| 103 | mqd_t mq_open(const char *name, int oflag, ...) |
| 104 | { |
| 105 | int mq_fd; |
| 106 | va_list arg; |
| 107 | mode_t mode; |
| 108 | struct mq_attr *attr = RT_NULL; |
| 109 | va_start(arg, oflag); |
| 110 | mode = (mode_t)va_arg(arg, unsigned int); |
| 111 | mode = (mode_t)mode; /* self-assignment avoids compiler optimization */ |
| 112 | attr = (struct mq_attr *)va_arg(arg, struct mq_attr *); |
| 113 | attr = (struct mq_attr *)attr; /* self-assignment avoids compiler optimization */ |
| 114 | va_end(arg); |
| 115 | if(*name == '/') |
| 116 | { |
| 117 | name++; |
| 118 | } |
| 119 | |
| 120 | int len = rt_strlen(name); |
| 121 | if (len > RT_NAME_MAX) |
| 122 | { |
| 123 | rt_set_errno(ENAMETOOLONG); |
| 124 | return (mqd_t)(-1); |
| 125 | } |
| 126 | rt_size_t size; |
| 127 | struct mqueue_file *mq_file; |
| 128 | mq_file = dfs_mqueue_lookup(name, &size); |
| 129 | if(mq_file != RT_NULL) |
| 130 | { |
| 131 | if (oflag & O_CREAT && oflag & O_EXCL) |
| 132 | { |
| 133 | rt_set_errno(EEXIST); |
| 134 | return (mqd_t)(-1); |
| 135 | } |
| 136 | } |
| 137 | else if (oflag & O_CREAT) |
| 138 | { |
| 139 | if (attr->mq_maxmsg <= 0) |
| 140 | { |
| 141 | rt_set_errno(EINVAL); |
| 142 | return (mqd_t)(-1); |
| 143 | } |
| 144 | struct mqueue_file *mq_file; |
| 145 | mq_file = (struct mqueue_file *) rt_malloc (sizeof(struct mqueue_file)); |
| 146 | |
| 147 | if (mq_file == RT_NULL) |
| 148 | { |
| 149 | rt_set_errno(ENFILE); |
| 150 | return (mqd_t)(-1); |
| 151 | } |
| 152 | mq_file->msg_size = attr->mq_msgsize; |
| 153 | mq_file->max_msgs = attr->mq_maxmsg; |
| 154 | mq_file->data = RT_NULL; |
| 155 | strncpy(mq_file->name, name, RT_NAME_MAX); |
| 156 | dfs_mqueue_insert_after(&(mq_file->list)); |
| 157 | } |
| 158 | else |
| 159 | { |
| 160 | rt_set_errno(ENOENT); |
no test coverage detected