Вторая часть функции mq_open приведена в листинге 5.18. Она завершает инициализацию новой очереди сообщений.
//my_pxmsg_mmap/mq_open.с
51 /* вычисление и установка размера файла */
52 msgsize = MSGSIZE(attr-mq_msgsize);
53 filesize = sizeof(struct mymq_hdr) + (attr-mq_maxmsg *
54 (sizeof(struct mymsg_hdr) + msgsize));
55 if (lseek(fd, filesize – 1, SEEK_SET) == –1)
56 goto err;
57 if (write(fd, "", 1) == –1)
58 goto err;
59 /* отображение файла в память */
60 mptr = mmap(NULL, filesize, PROT_READ | PROT_WRITE,
61 MAP_SHARED, fd, 0);
62 if (mptr == MAP_FAILED)
63 goto err;
64 /* выделение структуры mymq_info{} для очереди */
65 if ((mqinfo = mallос (sizeof (struct mymq_info))) == NULL)
66 goto err;
67 mqinfo-mqi_hdr = mqhdr = (struct mymq_hdr *) mptr;
68 mqinfo-mqi_magic = MQI_MAGIC;
69 mqinfo-mqi_flags = nonblock;
70 /* инициализация заголовка в начале файла */
71 /* создание списка пустых сообщений */
72 mqhdr-mqh_attr.mq_flags = 0;
73 mqhdr-mqh_attr.mq_maxmsg = attr-mq_maxmsg;
74 mqhdr-mqh_attr.mq_msgsize = attr-mq_msgsize;
75 mqhdr-mqh_attr.mq_curmsgs = 0;
76 mqhdr-mqh_nwait = 0;
77 mqhdr-mqh_pid = 0;
78 mqhdr-mqh_head = 0;
79 index = sizeof(struct mymq_hdr);
80 mqhdr-mqh_free = index;
81 for (i = 0; i attr-mq_maxmsg – 1; i++) {
82 msghdr = (struct mymsg_hdr *) mptr[index];
83 index += sizeof(struct mymsg_hdr) + msgsize;
84 msghdr-msg_next = index;
85 }
86 msghdr = (struct mymsg_hdr *) mptr[index];
87 msghdr-msg_next = 0; /* конец списка пустых сообщений */
88 /* инициализация взаимного исключения и условной переменной */
89 if ((i = pthread_mutexattr_init(mattr)) != 0)
90 goto pthreaderr;
91 pthread_mutexattr_setpshared(mattr, PTHREAD_PROCESS_SHARED);
92 i = pthread_mutex_init(mqhdr-mqh_lock, mattr);
93 pthread_mutexattr_destroy(mattr); /* обязательно нужно удалить */
94 if (i != 0)
95 goto pthreaderr:
96 if ((i = pthread_condattr_init(cattr)) != 0)
97 goto pthreaderr;
98 pthread_condattr_setpshared(cattr, PTHREAD_PROCESS_SHARED);
99 i = pthread_cond_init(mqhdr-mqh_wait, cattr);
100 pthread_condattr_destroy(cattr); /* обязательно нужно удалить */
101 if (i != 0)
102 goto pthreaderr;
103 /* инициализация завершена, снимаем бит user-execute */
104 if (fchmod(fd, mode) == –1)
105 goto err;
106 close(fd);
107 return((mymqd_t) mqinfo);
108 }