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

📄 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		fd, i, created, save_errno;	mode_t	mode;	va_list	ap;	mysem_t	*sem, seminit;	struct stat	statbuff;	unsigned int	value;	pthread_mutexattr_t	mattr;	pthread_condattr_t	cattr;	created = 0;	sem = MAP_FAILED;				/* [sic] */again:	if (oflag & O_CREAT) {		va_start(ap, oflag);		/* init ap to final named argument */		mode = va_arg(ap, va_mode_t) & ~S_IXUSR;		value = va_arg(ap, unsigned int);		va_end(ap);			/* 4open and specify O_EXCL and user-execute */		fd = open(pathname, oflag | O_EXCL | O_RDWR, mode | S_IXUSR);		if (fd < 0) {			if (errno == EEXIST && (oflag & O_EXCL) == 0)				goto exists;		/* already exists, OK */			else				return(SEM_FAILED);		}		created = 1;			/* 4first one to create the file initializes it */			/* 4set the file size */		bzero(&seminit, sizeof(seminit));		if (write(fd, &seminit, sizeof(seminit)) != sizeof(seminit))			goto err;			/* 4memory map the file */		sem = mmap(NULL, sizeof(mysem_t), PROT_READ | PROT_WRITE,				   MAP_SHARED, fd, 0);		if (sem == MAP_FAILED)			goto err;			/* 4initialize mutex, condition variable, and value */		if ( (i = pthread_mutexattr_init(&mattr)) != 0)			goto pthreaderr;		pthread_mutexattr_setpshared(&mattr, PTHREAD_PROCESS_SHARED);		i = pthread_mutex_init(&sem->sem_mutex, &mattr);		pthread_mutexattr_destroy(&mattr);	/* be sure to destroy */		if (i != 0)			goto pthreaderr;		if ( (i = pthread_condattr_init(&cattr)) != 0)			goto pthreaderr;		pthread_condattr_setpshared(&cattr, PTHREAD_PROCESS_SHARED);		i = pthread_cond_init(&sem->sem_cond, &cattr);		pthread_condattr_destroy(&cattr);	/* be sure to destroy */		if (i != 0)			goto pthreaderr;		if ( (sem->sem_count = value) > sysconf(_SC_SEM_VALUE_MAX)) {			errno = EINVAL;			goto err;		}			/* 4initialization complete, turn off user-execute bit */		if (fchmod(fd, mode) == -1)			goto err;		close(fd);		sem->sem_magic = SEM_MAGIC;		return(sem);	}/* end sem_open1 *//* include sem_open2 */exists:	if ( (fd = open(pathname, O_RDWR)) < 0) {		if (errno == ENOENT && (oflag & O_CREAT))			goto again;		goto err;	}	sem = mmap(NULL, sizeof(mysem_t), PROT_READ | PROT_WRITE,			   MAP_SHARED, fd, 0);	if (sem == MAP_FAILED)		goto err;		/* 4make certain initialization is complete */	for (i = 0; i < MAX_TRIES; i++) {		if (stat(pathname, &statbuff) == -1) {			if (errno == ENOENT && (oflag & O_CREAT)) {				close(fd);				goto again;			}			goto err;		}		if ((statbuff.st_mode & S_IXUSR) == 0) {			close(fd);			sem->sem_magic = SEM_MAGIC;			return(sem);		}		sleep(1);	}	errno = ETIMEDOUT;	goto err;pthreaderr:	errno = i;err:		/* 4don't let munmap() or close() change errno */	save_errno = errno;	if (created)		unlink(pathname);	if (sem != MAP_FAILED)		munmap(sem, sizeof(mysem_t));	close(fd);	errno = save_errno;	return(SEM_FAILED);}/* 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);		va_end(ap);		if ( (sem = mysem_open(pathname, oflag, mode, value)) == SEM_FAILED)			err_sys("mysem_open error for %s", pathname);	} 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 + -