diff options
-rw-r--r-- | nptl/ChangeLog | 6 | ||||
-rw-r--r-- | nptl/Makefile | 1 | ||||
-rw-r--r-- | nptl/sem_open.c | 29 | ||||
-rw-r--r-- | nptl/tst-sem8.c | 76 | ||||
-rw-r--r-- | nptl/tst-sem9.c | 83 |
5 files changed, 180 insertions, 15 deletions
diff --git a/nptl/ChangeLog b/nptl/ChangeLog index 1f9c523..dc78ad8 100644 --- a/nptl/ChangeLog +++ b/nptl/ChangeLog @@ -1,5 +1,11 @@ 2003-05-31 Ulrich Drepper <drepper@redhat.com> + * Makefile (tests): Add tst-sem8 and tst-sem9. + * tst-sem8.c: New file. + * tst-sem9.c: New file. + * sem_open.c: Fix creation of in_use record if the file exists but + no internal record. + * posix-timer.h: Remove old, unused timer_id2ptr and timer_ptr2id definitions. diff --git a/nptl/Makefile b/nptl/Makefile index 5af2f43..426ac07 100644 --- a/nptl/Makefile +++ b/nptl/Makefile @@ -150,6 +150,7 @@ tests = tst-attr1 tst-attr2 \ tst-once1 tst-once2 tst-once3 tst-once4 \ tst-key1 tst-key2 tst-key3 tst-key4 \ tst-sem1 tst-sem2 tst-sem3 tst-sem4 tst-sem5 tst-sem6 tst-sem7 \ + tst-sem8 tst-sem9 \ tst-barrier1 tst-barrier2 tst-barrier3 \ tst-align \ tst-basic1 tst-basic2 tst-basic3 tst-basic4 tst-basic5 tst-basic6 \ diff --git a/nptl/sem_open.c b/nptl/sem_open.c index 374c7d8..a4b2f5b 100644 --- a/nptl/sem_open.c +++ b/nptl/sem_open.c @@ -177,15 +177,20 @@ check_add_mapping (const char *name, size_t namelen, int fd, sem_t *existing) result = (*foundp)->sem; ++(*foundp)->refcnt; } - else if (existing != SEM_FAILED) + else { - /* We haven't found a mapping but the caller has a mapping. - Install it. */ + /* We haven't found a mapping. Install ione. */ struct inuse_sem *newp; newp = (struct inuse_sem *) malloc (sizeof (*newp) + namelen); if (newp != NULL) { + /* If the caller hasn't provided any map it now. */ + if (existing == SEM_FAILED) + existing = (sem_t *) mmap (NULL, sizeof (sem_t), + PROT_READ | PROT_WRITE, MAP_SHARED, + fd, 0); + newp->dev = st.st_dev; newp->ino = st.st_ino; newp->refcnt = 1; @@ -193,7 +198,8 @@ check_add_mapping (const char *name, size_t namelen, int fd, sem_t *existing) memcpy (newp->name, name, namelen); /* Insert the new value. */ - if (tsearch (newp, &__sem_mappings, __sem_search) != NULL) + if (existing != MAP_FAILED + && tsearch (newp, &__sem_mappings, __sem_search) != NULL) /* Successful. */ result = existing; else @@ -207,7 +213,7 @@ check_add_mapping (const char *name, size_t namelen, int fd, sem_t *existing) lll_unlock (__sem_mappings_lock); } - if (result != existing && existing != SEM_FAILED) + if (result != existing && existing != SEM_FAILED && existing != MAP_FAILED) { /* Do not disturb errno. */ INTERNAL_SYSCALL_DECL (err); @@ -268,16 +274,9 @@ sem_open (const char *name, int oflag, ...) /* Return. errno is already set. */ } else - { - /* Check whether we already have this semaphore mapped. */ - result = check_add_mapping (name, namelen, fd, SEM_FAILED); - - /* Map the sem_t structure from the file. */ - if (result == SEM_FAILED) - result = (sem_t *) mmap (NULL, sizeof (sem_t), - PROT_READ | PROT_WRITE, MAP_SHARED, - fd, 0); - } + /* Check whether we already have this semaphore mapped and + create one if necessary. */ + result = check_add_mapping (name, namelen, fd, SEM_FAILED); } else { diff --git a/nptl/tst-sem8.c b/nptl/tst-sem8.c new file mode 100644 index 0000000..876c319 --- /dev/null +++ b/nptl/tst-sem8.c @@ -0,0 +1,76 @@ +/* Copyright (C) 2003 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@redhat.com>, 2003. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <errno.h> +#include <fcntl.h> +#include <semaphore.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> + + +static void +remove_sem (int status, void *arg) +{ + sem_unlink (arg); +} + + +int +main (void) +{ + sem_t *s; + sem_t *s2; + sem_t *s3; + int i; + + on_exit (remove_sem, (void *) "/glibc-tst-sem8"); + + for (i = 0; i < 3; ++i) + { + s = sem_open ("/glibc-tst-sem8", O_CREAT, 0600, 1); + if (s == SEM_FAILED) + { + if (errno == ENOSYS) + { + puts ("sem_open not supported. Oh well."); + return 0; + } + + /* Maybe the shm filesystem has strict permissions. */ + if (errno == EACCES) + { + puts ("sem_open not allowed. Oh well."); + return 0; + } + + printf ("sem_open: %m\n"); + return 1; + } + + /* Now close the handle. */ + if (sem_close (s) != 0) + { + puts ("sem_close failed"); + return 1; + } + } + + return 0; +} diff --git a/nptl/tst-sem9.c b/nptl/tst-sem9.c new file mode 100644 index 0000000..2b35446 --- /dev/null +++ b/nptl/tst-sem9.c @@ -0,0 +1,83 @@ +/* Copyright (C) 2003 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@redhat.com>, 2003. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <errno.h> +#include <fcntl.h> +#include <semaphore.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> + + +static void +remove_sem (int status, void *arg) +{ + sem_unlink (arg); +} + + +int +main (void) +{ + sem_t *s; + sem_t *s2; + sem_t *s3; + int i; + + on_exit (remove_sem, (void *) "/glibc-tst-sem9"); + + for (i = 0; i < 3; ++i) + { + s = sem_open ("/glibc-tst-sem9", O_CREAT, 0600, 1); + if (s == SEM_FAILED) + { + if (errno == ENOSYS) + { + puts ("sem_open not supported. Oh well."); + return 0; + } + + /* Maybe the shm filesystem has strict permissions. */ + if (errno == EACCES) + { + puts ("sem_open not allowed. Oh well."); + return 0; + } + + printf ("sem_open: %m\n"); + return 1; + } + + /* Now close the handle. */ + if (sem_close (s) != 0) + { + puts ("sem_close failed"); + return 1; + } + + /* And remove it. */ + if (sem_unlink ("/glibc-tst-sem9") != 0) + { + puts ("sem_unlink failed"); + return 1; + } + } + + return 0; +} |