- created = 1;
- /* First one to create the file initializes it */
- if (attr == NULL)
- attr = &defattr;
- else if (attr->mq_maxmsg <= 0 || attr->mq_msgsize <= 0)
- {
- set_errno (EINVAL);
- goto err;
- }
- /* 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)
- goto err;
- if (write (fd, "", 1) == -1)
- goto err;
-
- /* 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)
- goto err;
-
- /* Allocate one mq_info{} for the queue */
- if (!(mqinfo = (struct mq_info *) calloc (1, sizeof (struct mq_info))))
- goto err;
- 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;
- 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)
- goto pthreaderr;
-
- i = ipc_cond_init (&mqinfo->mqi_waitsend, mqhdr->mqh_uname, 'S');
- if (i != 0)
- goto pthreaderr;
-
- i = ipc_cond_init (&mqinfo->mqi_waitrecv, mqhdr->mqh_uname, 'R');
- if (i != 0)
- goto pthreaderr;
-
- /* Initialization complete, turn off user-execute bit */
- if (fchmod (fd, mode) == -1)
- goto err;
- close (fd);
- return ((mqd_t) mqinfo);
- }