summaryrefslogtreecommitdiff
path: root/nptl
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2003-05-31 19:58:46 +0000
committerUlrich Drepper <drepper@redhat.com>2003-05-31 19:58:46 +0000
commitdcfc8224315f0c38a595be5e208b7925596ac4cd (patch)
tree74f39e55132353edead4c12ae08cdb0e5044a7ed /nptl
parent49b650430eb51350cc96adf7dd621560eb40af04 (diff)
Update.
* 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.
Diffstat (limited to 'nptl')
-rw-r--r--nptl/ChangeLog6
-rw-r--r--nptl/Makefile1
-rw-r--r--nptl/sem_open.c29
-rw-r--r--nptl/tst-sem8.c76
-rw-r--r--nptl/tst-sem9.c83
5 files changed, 180 insertions, 15 deletions
diff --git a/nptl/ChangeLog b/nptl/ChangeLog
index 1f9c523137..dc78ad8ed4 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 5af2f4331a..426ac07653 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 374c7d84e9..a4b2f5b3ac 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 0000000000..876c319ba5
--- /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 0000000000..2b35446b46
--- /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;
+}