42-50 Если при вызове в качестве последнего аргумента передан нулевой указатель, очередь сообщений инициализируется со значениями атрибутов по умолчанию: 128 сообщений в очереди и 1024 байта на сообщение. Если атрибуты указаны явно, мы проверяем, что mq_maxmsg и mq_msgsize имеют положительные значения.
Вторая часть функции 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)