svn commit: r266327 - stable/9/lib/libc/gen
Konstantin Belousov
kib at FreeBSD.org
Sat May 17 16:29:40 UTC 2014
Author: kib
Date: Sat May 17 16:29:39 2014
New Revision: 266327
URL: http://svnweb.freebsd.org/changeset/base/266327
Log:
MFC r265847:
Fix sem_unlink(3) to properly invalidate the semaphores name cache.
PR: standards/189353
Modified:
stable/9/lib/libc/gen/sem_new.c
Directory Properties:
stable/9/lib/libc/ (props changed)
Modified: stable/9/lib/libc/gen/sem_new.c
==============================================================================
--- stable/9/lib/libc/gen/sem_new.c Sat May 17 16:28:29 2014 (r266326)
+++ stable/9/lib/libc/gen/sem_new.c Sat May 17 16:29:39 2014 (r266327)
@@ -66,6 +66,8 @@ __weak_reference(_sem_wait, sem_wait);
struct sem_nameinfo {
int open_count;
char *name;
+ dev_t dev;
+ ino_t ino;
sem_t *sem;
LIST_ENTRY(sem_nameinfo) next;
};
@@ -151,37 +153,46 @@ _sem_open(const char *name, int flags, .
return (SEM_FAILED);
}
name++;
-
+ strcpy(path, SEM_PREFIX);
+ if (strlcat(path, name, sizeof(path)) >= sizeof(path)) {
+ errno = ENAMETOOLONG;
+ return (SEM_FAILED);
+ }
if (flags & ~(O_CREAT|O_EXCL)) {
errno = EINVAL;
return (SEM_FAILED);
}
-
+ if ((flags & O_CREAT) != 0) {
+ va_start(ap, flags);
+ mode = va_arg(ap, int);
+ value = va_arg(ap, int);
+ va_end(ap);
+ }
+ fd = -1;
_pthread_once(&once, sem_module_init);
_pthread_mutex_lock(&sem_llock);
LIST_FOREACH(ni, &sem_list, next) {
- if (strcmp(name, ni->name) == 0) {
- if ((flags & (O_CREAT|O_EXCL)) == (O_CREAT|O_EXCL)) {
- _pthread_mutex_unlock(&sem_llock);
- errno = EEXIST;
- return (SEM_FAILED);
- } else {
- ni->open_count++;
- sem = ni->sem;
- _pthread_mutex_unlock(&sem_llock);
- return (sem);
+ if (ni->name != NULL && strcmp(name, ni->name) == 0) {
+ fd = _open(path, flags | O_RDWR | O_CLOEXEC |
+ O_EXLOCK, mode);
+ if (fd == -1 || _fstat(fd, &sb) == -1)
+ goto error;
+ if ((flags & (O_CREAT | O_EXCL)) == (O_CREAT |
+ O_EXCL) || ni->dev != sb.st_dev ||
+ ni->ino != sb.st_ino) {
+ ni->name = NULL;
+ ni = NULL;
+ break;
}
+ ni->open_count++;
+ sem = ni->sem;
+ _pthread_mutex_unlock(&sem_llock);
+ _close(fd);
+ return (sem);
}
}
- if (flags & O_CREAT) {
- va_start(ap, flags);
- mode = va_arg(ap, int);
- value = va_arg(ap, int);
- va_end(ap);
- }
-
len = sizeof(*ni) + strlen(name) + 1;
ni = (struct sem_nameinfo *)malloc(len);
if (ni == NULL) {
@@ -192,17 +203,11 @@ _sem_open(const char *name, int flags, .
ni->name = (char *)(ni+1);
strcpy(ni->name, name);
- strcpy(path, SEM_PREFIX);
- if (strlcat(path, name, sizeof(path)) >= sizeof(path)) {
- errno = ENAMETOOLONG;
- goto error;
+ if (fd == -1) {
+ fd = _open(path, flags | O_RDWR | O_CLOEXEC | O_EXLOCK, mode);
+ if (fd == -1 || _fstat(fd, &sb) == -1)
+ goto error;
}
-
- fd = _open(path, flags|O_RDWR|O_CLOEXEC|O_EXLOCK, mode);
- if (fd == -1)
- goto error;
- if (_fstat(fd, &sb))
- goto error;
if (sb.st_size < sizeof(sem_t)) {
sem_t tmp;
@@ -228,6 +233,8 @@ _sem_open(const char *name, int flags, .
}
ni->open_count = 1;
ni->sem = sem;
+ ni->dev = sb.st_dev;
+ ni->ino = sb.st_ino;
LIST_INSERT_HEAD(&sem_list, ni, next);
_close(fd);
_pthread_mutex_unlock(&sem_llock);
More information about the svn-src-stable-9
mailing list