summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/librthread/rthread_sem.c81
1 files changed, 37 insertions, 44 deletions
diff --git a/lib/librthread/rthread_sem.c b/lib/librthread/rthread_sem.c
index bb6a9e1b483..20c7aecef29 100644
--- a/lib/librthread/rthread_sem.c
+++ b/lib/librthread/rthread_sem.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rthread_sem.c,v 1.15 2013/11/22 07:48:41 deraadt Exp $ */
+/* $OpenBSD: rthread_sem.c,v 1.16 2013/11/26 11:24:43 fgsch Exp $ */
/*
* Copyright (c) 2004,2005,2013 Ted Unangst <tedu@openbsd.org>
* All Rights Reserved.
@@ -20,7 +20,6 @@
#include <sys/mman.h>
#include <sys/stat.h>
-#include <err.h>
#include <errno.h>
#include <fcntl.h>
#include <sha2.h>
@@ -114,50 +113,42 @@ _sem_post(sem_t sem)
int
sem_init(sem_t *semp, int pshared, unsigned int value)
{
- sem_t sem, *sempshared;
- int i, oerrno;
char name[SEM_RANDOM_NAME_LEN];
+ sem_t sem, *sempshared;
+ int i;
- if (!semp) {
+ if (value > SEM_VALUE_MAX) {
errno = EINVAL;
return (-1);
}
if (pshared) {
- while (1) {
+ for (;;) {
for (i = 0; i < SEM_RANDOM_NAME_LEN - 1; i++)
name[i] = arc4random_uniform(255) + 1;
name[SEM_RANDOM_NAME_LEN - 1] = '\0';
- sempshared = sem_open(name, O_CREAT|O_EXCL);
- if (sempshared)
+ sempshared = sem_open(name, O_CREAT | O_EXCL, 0, value);
+ if (sempshared != SEM_FAILED)
break;
if (errno == EEXIST)
continue;
- if (errno != EINVAL && errno != EPERM)
+ if (errno != EPERM)
errno = ENOSPC;
return (-1);
}
/* unnamed semaphore should not be opened twice */
if (sem_unlink(name) == -1) {
- oerrno = errno;
sem_close(sempshared);
- errno = oerrno;
+ errno = ENOSPC;
return (-1);
}
- sem = *sempshared;
- sem->value = value;
- *semp = sem;
+ *semp = *sempshared;
free(sempshared);
return (0);
}
- if (value > SEM_VALUE_MAX) {
- errno = EINVAL;
- return (-1);
- }
-
sem = calloc(1, sizeof(*sem));
if (!sem) {
errno = ENOSPC;
@@ -313,79 +304,80 @@ sem_open(const char *name, int oflag, ...)
{
char sempath[SEM_PATH_SIZE];
struct stat sb;
- int created = 0, fd, oerrno;
- sem_t sem;
- sem_t *semp = SEM_FAILED;
- mode_t unusedmode;
- unsigned value = 0;
+ sem_t sem, *semp;
+ unsigned int value = 0;
+ int created = 0, fd;
if (oflag & ~(O_CREAT | O_EXCL)) {
errno = EINVAL;
- return (semp);
+ return (SEM_FAILED);
}
if (oflag & O_CREAT) {
va_list ap;
va_start(ap, oflag);
- unusedmode = va_arg(ap, mode_t);
+ /* 3rd parameter mode is not used */
+ va_arg(ap, mode_t);
value = va_arg(ap, unsigned);
va_end(ap);
+
+ if (value > SEM_VALUE_MAX) {
+ errno = EINVAL;
+ return (SEM_FAILED);
+ }
}
makesempath(name, sempath, sizeof(sempath));
fd = open(sempath, O_RDWR | O_NOFOLLOW | oflag, 0600);
if (fd == -1)
- return (semp);
+ return (SEM_FAILED);
if (fstat(fd, &sb) == -1 || !S_ISREG(sb.st_mode)) {
close(fd);
errno = EINVAL;
- return (semp);
+ return (SEM_FAILED);
}
if (sb.st_uid != getuid()) {
close(fd);
errno = EPERM;
- return (semp);
+ return (SEM_FAILED);
}
if (sb.st_size != SEM_MMAP_SIZE) {
if (!(oflag & O_CREAT)) {
close(fd);
errno = EINVAL;
- return (semp);
+ return (SEM_FAILED);
}
if (sb.st_size != 0) {
close(fd);
errno = EINVAL;
- return (semp);
+ return (SEM_FAILED);
}
if (ftruncate(fd, SEM_MMAP_SIZE) == -1) {
- oerrno = errno;
close(fd);
- errno = oerrno;
- /* XXX can set errno to EIO, ENOTDIR... */
- return (semp);
+ errno = EINVAL;
+ return (SEM_FAILED);
}
+
created = 1;
}
sem = mmap(NULL, SEM_MMAP_SIZE, PROT_READ | PROT_WRITE,
MAP_FILE | MAP_SHARED | MAP_HASSEMAPHORE, fd, 0);
- oerrno = errno;
close(fd);
if (sem == MAP_FAILED) {
- errno = oerrno;
- return (semp);
- }
- if (created) {
- sem->lock = _SPINLOCK_UNLOCKED_ASSIGN;
- sem->value = value;
+ errno = EINVAL;
+ return (SEM_FAILED);
}
- sem->shared = 1;
semp = malloc(sizeof(*semp));
if (!semp) {
- free(semp);
munmap(sem, SEM_MMAP_SIZE);
errno = ENOSPC;
return (SEM_FAILED);
}
+ if (created) {
+ sem->lock = _SPINLOCK_UNLOCKED_ASSIGN;
+ sem->value = value;
+ sem->shared = 1;
+ }
*semp = sem;
return (semp);
@@ -401,6 +393,7 @@ sem_close(sem_t *semp)
return (-1);
}
+ *semp = NULL;
munmap(sem, SEM_MMAP_SIZE);
free(semp);