📄 sem_open.c
字号:
/* include sem_open1 */
#include "unpipc.h"
#include "semaphore.h"
#include <stdarg.h> /* for variable arg lists */
#define MAX_TRIES 10 /* for waiting for initialization */
mysem_t *
mysem_open(const char *pathname, int oflag, ... )
{
int i, fd, semflag, semid, save_errno;
key_t key;
mode_t mode;
va_list ap;
mysem_t *sem;
union semun arg;
unsigned int value;
struct semid_ds seminfo;
struct sembuf initop;
/* 4no mode for sem_open() w/out O_CREAT; guess */
semflag = SVSEM_MODE;
semid = -1;
if (oflag & O_CREAT) {
va_start(ap, oflag); /* init ap to final named argument */
mode = va_arg(ap, va_mode_t);
value = va_arg(ap, unsigned int);
va_end(ap);
/* 4convert to key that will identify System V semaphore */
if ( (fd = open(pathname, oflag, mode)) == -1)
return(SEM_FAILED);
close(fd);
if ( (key = ftok(pathname, 0)) == (key_t) -1)
return(SEM_FAILED);
semflag = IPC_CREAT | (mode & 0777);
if (oflag & O_EXCL)
semflag |= IPC_EXCL;
/* 4create the System V semaphore with IPC_EXCL */
if ( (semid = semget(key, 1, semflag | IPC_EXCL)) >= 0) {
/* 4success, we're the first so initialize to 0 */
arg.val = 0;
if (semctl(semid, 0, SETVAL, arg) == -1)
goto err;
/* 4then increment by value to set sem_otime nonzero */
if (value > SEMVMX) {
errno = EINVAL;
goto err;
}
initop.sem_num = 0;
initop.sem_op = value;
initop.sem_flg = 0;
if (semop(semid, &initop, 1) == -1)
goto err;
goto finish;
} else if (errno != EEXIST || (semflag & IPC_EXCL) != 0)
goto err;
/* else fall through */
}
/* end sem_open1 */
/* include sem_open2 */
/*
* (O_CREAT not secified) or
* (O_CREAT without O_EXCL and semaphore already exists).
* Must open semaphore and make certain it has been initialized.
*/
if ( (key = ftok(pathname, 0)) == (key_t) -1)
goto err;
if ( (semid = semget(key, 0, semflag)) == -1)
goto err;
arg.buf = &seminfo;
for (i = 0; i < MAX_TRIES; i++) {
if (semctl(semid, 0, IPC_STAT, arg) == -1)
goto err;
if (arg.buf->sem_otime != 0)
goto finish;
sleep(1);
}
errno = ETIMEDOUT;
err:
save_errno = errno; /* don't let semctl() change errno */
if (semid != -1)
semctl(semid, 0, IPC_RMID);
errno = save_errno;
return(SEM_FAILED);
finish:
/* *INDENT-OFF* */
if ( (sem = malloc(sizeof(mysem_t))) == NULL)
goto err;
/* *INDENT-ON* */
sem->sem_semid = semid;
sem->sem_magic = SEM_MAGIC;
return(sem);
}
/* end sem_open2 */
mysem_t *
Mysem_open(const char *pathname, int oflag, ... )
{
va_list ap;
mode_t mode;
mysem_t *sem;
unsigned int value;
if (oflag & O_CREAT) {
va_start(ap, oflag); /* init ap to final named argument */
mode = va_arg(ap, va_mode_t);
value = va_arg(ap, unsigned int);
if ( (sem = mysem_open(pathname, oflag, mode, value)) == SEM_FAILED)
err_sys("mysem_open error for %s", pathname);
va_end(ap);
} else {
if ( (sem = mysem_open(pathname, oflag)) == SEM_FAILED)
err_sys("mysem_open error for %s", pathname);
}
return(sem);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -