2013/11/21 Ted Unangst <t...@tedunangst.com>: > Read the standard again and discovered some more missing features. > > 1. sem_open allows setting the value via a fourth argument. Fixed. > > 2. Multiple sem_open calls of the same path in the same process are > supposed to return the same pointer. Not the same semaphore, the same > pointer. This is mind boggling and hard to accomplish with this > implementation. Not fixed. > > 3. There are also some requirements that sem_open be atomic in > ways that it is not. We're publishing, via the filesystem, the new > semaphore before we're done initializing it. This is fixable, but > requires bizarro filesystem rename hijinks. Maybe another diff.
And we also could return some errors that are not specified in POSIX, too (I've added XXX for the path I found, there could be others). Not sure, what's worse: not following standard or hiding errors. > Index: rthread_sem.c > =================================================================== > RCS file: /cvs/src/lib/librthread/rthread_sem.c,v > retrieving revision 1.13 > diff -u -p -r1.13 rthread_sem.c > --- rthread_sem.c 20 Nov 2013 23:18:17 -0000 1.13 > +++ rthread_sem.c 21 Nov 2013 03:34:03 -0000 > @@ -24,6 +24,7 @@ > #include <errno.h> > #include <fcntl.h> > #include <sha2.h> > +#include <stdarg.h> > #include <stdlib.h> > #include <stdio.h> > #include <string.h> > @@ -315,12 +316,22 @@ sem_open(const char *name, int oflag, .. > int created = 0, fd, oerrno; > sem_t sem; > sem_t *semp = SEM_FAILED; > + mode_t unusedmode; > + unsigned value = 0; > > if (oflag & ~(O_CREAT | O_EXCL)) { > errno = EINVAL; > return (semp); > } > > + if (oflag & O_CREAT) { > + va_list ap; > + va_start(ap, oflag); > + unusedmode = va_arg(ap, mode_t); > + value = va_arg(ap, unsigned); > + va_end(ap); > + } > + > makesempath(name, sempath, sizeof(sempath)); > fd = open(sempath, O_RDWR | O_NOFOLLOW | oflag, 0600); > if (fd == -1) > @@ -363,8 +374,10 @@ sem_open(const char *name, int oflag, .. > errno = oerrno; > return (semp); > } > - if (created) > + if (created) { > sem->lock = _SPINLOCK_UNLOCKED_ASSIGN; > + sem->value = value; > + } > sem->shared = 1; > semp = malloc(sizeof(*semp)); > if (!semp) { > @@ -382,7 +395,7 @@ int > sem_close(sem_t *semp) > { > sem_t sem; > - > + > if (!semp || !(sem = *semp) || !sem->shared) { > errno = EINVAL; > return (-1); > okay zhuk@