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@

Reply via email to