//my_pxmsg_mmap/mq_open.c
			/*      */
		msgsize = MSGSIZE(attr->mq_msgsize);
		filesize = sizeof(struct mymq_hdr) + (attr->mq_maxmsg *
				   (sizeof(struct mymsg_hdr) + msgsize));
		if (lseek(fd, filesize - 1, SEEK_SET) == -1)
			goto err;
		if (write(fd, "", 1) == -1)
			goto err;

			/*     */
		mptr = mmap(NULL, filesize, PROT_READ | PROT_WRITE,
					MAP_SHARED, fd, 0);
		if (mptr == MAP_FAILED)
			goto err;

			/*   mymq_info{}   */
		if ( (mqinfo = malloc(sizeof(struct mymq_info))) == NULL)
			goto err;
		mqinfo->mqi_hdr = mqhdr = (struct mymq_hdr *) mptr;
		mqinfo->mqi_magic = MQI_MAGIC;
		mqinfo->mqi_flags = nonblock;

			/*      */
			/*     */
		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;
		mqhdr->mqh_head = 0;
		index = sizeof(struct mymq_hdr);
		mqhdr->mqh_free = index;
		for (i = 0; i < attr->mq_maxmsg - 1; i++) {
			msghdr = (struct mymsg_hdr *) &mptr[index];
			index += sizeof(struct mymsg_hdr) + msgsize;
			msghdr->msg_next = index;
		}
		msghdr = (struct mymsg_hdr *) &mptr[index];
		msghdr->msg_next = 0;		/*     */

			/*       */
		if ( (i = pthread_mutexattr_init(&mattr)) != 0)
			goto pthreaderr;
		pthread_mutexattr_setpshared(&mattr, PTHREAD_PROCESS_SHARED);
		i = pthread_mutex_init(&mqhdr->mqh_lock, &mattr);
		pthread_mutexattr_destroy(&mattr);	/*    */
		if (i != 0)
			goto pthreaderr;

		if ( (i = pthread_condattr_init(&cattr)) != 0)
			goto pthreaderr;
		pthread_condattr_setpshared(&cattr, PTHREAD_PROCESS_SHARED);
		i = pthread_cond_init(&mqhdr->mqh_wait, &cattr);
		pthread_condattr_destroy(&cattr);	/*    */
		if (i != 0)
			goto pthreaderr;

			/*  ,   user-execute */
		if (fchmod(fd, mode) == -1)
			goto err;
		close(fd);
		return((mymqd_t) mqinfo);
	}
