Листинг 10.38. Функция sem_open: вторая половина
//my_pxsem_svsem/sem_open.c
55 /*
56 * (O_CREAT не указан) или
57 * (O_CREAT без O_EXCL и семафор уже существует).
58 * Нужно открыть семафор и проверить, что он уже проинициализирован.
59 */
60 if ((key = ftok(pathname, 0)) == (key_t) –1)
61 goto err;
62 if ((semid = semget(key, 0, semflag)) == –1)
63 goto err;
64 arg.buf = &seminfo;
65 for (i = 0; i < MAX_TRIES; i++) {
66 if (semctl(semid, 0, IPC_STAT, arg) == –1)
67 goto err;
68 if (arg.buf->sem_otime != 0)
69 goto finish;
70 sleep(1);
71 }
72 errno = ETIMEDOUT;
73 err:
74 save_errno = errno; /* не даем вызову semctl() изменить значение errno */
75 if (semid != –1)
76 semctl(semid, 0, IPC_RMID);
77 errno = save_errno;
78 return(SEM_FAILED);
79 finish:
80 if ((sem = malloc(sizeof(mysem_t))) == NULL)
81 goto err;
82 sem->sem_semid = semid;
83 sem->sem_magic = SEM_MAGIC;
84 return(sem);
85 }