-
- /* Open and specify O_EXCL and user-execute */
- fd = open (mqname, oflag | O_EXCL | O_RDWR | O_CLOEXEC,
- mode | S_IXUSR);
- if (fd < 0)
- {
- if (errno == EEXIST && (oflag & O_EXCL) == 0)
- goto exists; /* already exists, OK */
- return (mqd_t) -1;
- }
- created = 1;
- /* First one to create the file initializes it */
- if (attr == NULL)
- attr = &defattr;
- /* Check minimum and maximum values. The max values are pretty much
- arbitrary, taken from the linux mq_overview man page. However,
- these max values make sure that the internal mq_fattr structure
- can use 32 bit types. */
- else if (attr->mq_maxmsg <= 0 || attr->mq_maxmsg > 32768
- || attr->mq_msgsize <= 0 || attr->mq_msgsize > 1048576)
- {
- set_errno (EINVAL);
- __leave;
- }
- /* Calculate and set the file size */
- msgsize = MSGSIZE (attr->mq_msgsize);
- filesize = sizeof (struct mq_hdr)
- + (attr->mq_maxmsg * (sizeof (struct msg_hdr) + msgsize));
- if (lseek64 (fd, filesize - 1, SEEK_SET) == -1)
- __leave;
- if (write (fd, "", 1) == -1)
- __leave;
-
- /* Memory map the file */
- mptr = (int8_t *) mmap64 (NULL, (size_t) filesize,
- PROT_READ | PROT_WRITE,
- MAP_SHARED, fd, 0);
- if (mptr == (int8_t *) MAP_FAILED)
- __leave;
-
- /* Allocate one mq_info{} for the queue */
- if (!(mqinfo = (struct mq_info *)
- calloc (1, sizeof (struct mq_info))))
- __leave;
- mqinfo->mqi_hdr = mqhdr = (struct mq_hdr *) mptr;
- mqinfo->mqi_magic = MQI_MAGIC;
- mqinfo->mqi_flags = nonblock;
-
- /* Initialize header at beginning of file */
- /* Create free list with all messages on it */
- mqhdr->mqh_attr.mq_flags = 0;
- mqhdr->mqh_attr.mq_maxmsg = attr->mq_maxmsg;
- mqhdr->mqh_attr.mq_msgsize = attr->mq_msgsize;
- mqhdr->mqh_attr.mq_curmsgs = 0;
- mqhdr->mqh_nwait = 0;
- mqhdr->mqh_pid = 0;
- NtAllocateLocallyUniqueId (&luid);
- __small_sprintf (mqhdr->mqh_uname, "%016X%08x%08x",
- hash_path_name (0,mqname),
- luid.HighPart, luid.LowPart);
- mqhdr->mqh_head = 0;
- mqhdr->mqh_magic = MQI_MAGIC;
- index = sizeof (struct mq_hdr);
- mqhdr->mqh_free = index;
- for (i = 0; i < attr->mq_maxmsg - 1; i++)
- {
- msghdr = (struct msg_hdr *) &mptr[index];
- index += sizeof (struct msg_hdr) + msgsize;
- msghdr->msg_next = index;
- }
- msghdr = (struct msg_hdr *) &mptr[index];
- msghdr->msg_next = 0; /* end of free list */
-
- /* Initialize mutex & condition variables */
- i = ipc_mutex_init (&mqinfo->mqi_lock, mqhdr->mqh_uname);
- if (i != 0)
- {
- set_errno (i);
- __leave;
- }
- i = ipc_cond_init (&mqinfo->mqi_waitsend, mqhdr->mqh_uname, 'S');
- if (i != 0)
- {
- set_errno (i);
- __leave;
- }
- i = ipc_cond_init (&mqinfo->mqi_waitrecv, mqhdr->mqh_uname, 'R');
- if (i != 0)
- {
- set_errno (i);
- __leave;
- }
- /* Initialization complete, turn off user-execute bit */
- if (fchmod (fd, mode) == -1)
- __leave;
- close (fd);
- return ((mqd_t) mqinfo);