Листинг 5.19. Третья часть функции mq_open: открытие существующей очереди сообщений
//my_pxmsg_mmap/mq_open.с
109 exists:
110 /* открытие файла и отображение его в память */
111 if ((fd = open(pathname, O_RDWR)) < 0) {
112 if (errno == ENOENT && (oflag & O_CREAT))
113 goto again;
114 goto err;
115 }
116 /* проверяем, что инициализация завершена */
117 for (i = 0; i < MAX TRIES; i++) {
118 if (stat(pathname, &statbuff) == –1) {
119 if (errno == ENOENT && (oflag & O_CREAT)) {
120 close(fd);
121 goto again;
122 }
123 goto err;
124 }
125 if ((statbuff.st_mode & S_IXUSR) == 0)
126 break;
127 sleep(1);
128 }
129 if (i == MAX_TRIES) {
130 errno = ETIMEDOUT;
131 goto err;
132 }
133 filesize = statbuff.st_size;
134 mptr = mmap(NULL, filesize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
135 if (mptr == MAP_FAILED)
136 goto err;
137 close(fd);
138 /* выделяем одну mymq_info{} для каждого вызова open */
139 if ((mqinfo = malloc(sizeof(struct mymq_info))) == NULL)
140 goto err;
141 rnqinfo->mqi_hdr = (struct mymq_hdr *) mptr;
142 mqinfo->mqi_magic = MQI_MAGIC;
143 mqinfo->mqi_flags = nonblock;
144 return((mymqd_t) mqinfo);
145 pthreaderr:
146 errno = i;
147 err:
148 /* не даем следующим вызовам изменить errno */
149 save_errno = errno;
150 if (created)
151 unlink(pathname);
152 if (mptr != MAP_FAILED)
153 munmap(mptr, filesize);
154 if (mqinfo != NULL)
155 free(mqinfo);
156 close(fd);
157 errno = save_errno;
158 return((mymqd_t) –1);
159 }