Листинг 10.29. Функция sem_open: вторая половина
//my_pxsem_mmap/sem_open.с
69 exists:
70 if ((fd = open(pathname, O_RDWR)) < 0) {
71 if (errno == ENOENT && (oflag & O_CREAT))
72 goto again;
73 goto err;
74 }
75 sem = mmap(NULL, sizeof(mysem_t), PROT_READ | PROT_WRITE,
76 MAP_SHARED, fd, 0);
77 if (sem == MAP_FAILED)
78 goto err;
79 /* удостоверимся, что инициализация завершена */
80 for (i = 0; i < MAX TRIES; i++) {
81 if (stat(pathname, &statbuff) == –1) {
82 if (errno == ENOENT && (oflag & O_CREAT)) {
83 close(fd);
84 goto again;
85 }
86 goto err;
87 }
88 if ((statbuff.st_mode & S_IXUSR) == 0) {
89 close(fd);
90 sem->sem_magic = SEM_MAGIC;
91 return(sem);
92 }
93 sleep(1);
94 }
95 errno = ETIMEDOUT;
96 goto err;
97 pthreaderr:
98 errno = i;
99 err:
100 /* не даем вызовам unlink и munmap изменить код errno */
101 save_errno = errno;
102 if (created)
103 unlink(pathname);
104 if (sem != MAP_FAILED)
105 munmap(sem, sizeof(mysem_t));
106 close(fd);
107 errno = save_errno;
108 return(SEM_FAILED);
109 }