Update.
authorUlrich Drepper <drepper@redhat.com>
Sat, 31 May 2003 19:58:46 +0000 (19:58 +0000)
committerUlrich Drepper <drepper@redhat.com>
Sat, 31 May 2003 19:58:46 +0000 (19:58 +0000)
* 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.

nptl/ChangeLog
nptl/Makefile
nptl/sem_open.c
nptl/tst-sem8.c [new file with mode: 0644]
nptl/tst-sem9.c [new file with mode: 0644]

index 1f9c523..dc78ad8 100644 (file)
@@ -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.
 
index 5af2f43..426ac07 100644 (file)
@@ -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 \
index 374c7d8..a4b2f5b 100644 (file)
@@ -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 (file)
index 0000000..876c319
--- /dev/null
@@ -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 (file)
index 0000000..2b35446
--- /dev/null
@@ -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;
+}