⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sem_open.c

📁 这是unix网络编程一书的源代码希望能对大家的学习提供一种便利
💻 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 + -