OSDN Git Service

mkostemp: fix implementation
[uclinux-h8/uClibc.git] / libpthread / nptl / sem_open.c
index 25389f0..3a72079 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2006, 2007, 2009 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -13,9 +13,8 @@
    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.  */
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
 
 #include <errno.h>
 #include <fcntl.h>
 
 
 /* Compatibility defines. */
-#define __endmntent                    endmntent
-#define __fxstat64(vers, fd, buf)      fstat64(fd, buf)
-#define __getmntent_r                  getmntent_r
-#define __setmntent                    setmntent
-#define __statfs                       statfs
-#define __libc_close                   close
-#define __libc_open                    open
-#define __libc_write                   write
+#define __endmntent                    endmntent
+#define __getmntent_r                  getmntent_r
+#define __setmntent                    setmntent
+#define __statfs                       statfs
+#define __libc_close                   close
+#ifdef __UCLIBC_HAS_LFS__
+# define __libc_open                    open64
+# define __fxstat64(vers, fd, buf)             fstat64(fd, buf)
+#else
+# define __libc_open                    open
+# define __fxstat64(vers, fd, buf)             fstat(fd, buf)
+# define stat64                                                        stat
+#endif
+#define __libc_write                   write
+
 
 /* Information about the mount point.  */
 struct mountpoint_info mountpoint attribute_hidden;
@@ -84,10 +90,10 @@ __where_is_shmfs (void)
   /* OK, do it the hard way.  Look through the /proc/mounts file and if
      this does not exist through /etc/fstab to find the mount point.  */
   fp = __setmntent ("/proc/mounts", "r");
-  if (__builtin_expect (fp == NULL, 0))
+  if (unlikely (fp == NULL))
     {
       fp = __setmntent (_PATH_MNTTAB, "r");
-      if (__builtin_expect (fp == NULL, 0))
+      if (unlikely (fp == NULL))
        /* There is nothing we can do.  Blind guesses are not helpful.  */
        return;
     }
@@ -157,7 +163,7 @@ __sem_search (const void *a, const void *b)
 void *__sem_mappings attribute_hidden;
 
 /* Lock to protect the search tree.  */
-lll_lock_t __sem_mappings_lock = LLL_LOCK_INITIALIZER;
+int __sem_mappings_lock attribute_hidden = LLL_LOCK_INITIALIZER;
 
 
 /* Search for existing mapping and if possible add the one provided.  */
@@ -167,16 +173,11 @@ check_add_mapping (const char *name, size_t namelen, int fd, sem_t *existing)
   sem_t *result = SEM_FAILED;
 
   /* Get the information about the file.  */
-#ifdef __UCLIBC_HAS_LFS__
   struct stat64 st;
   if (__fxstat64 (_STAT_VER, fd, &st) == 0)
-#else
-  struct stat st;
-  if (fstat (fd, &st) == 0)
-#endif
     {
       /* Get the lock.  */
-      lll_lock (__sem_mappings_lock);
+      lll_lock (__sem_mappings_lock, LLL_PRIVATE);
 
       /* Search for an existing mapping given the information we have.  */
       struct inuse_sem *fake;
@@ -225,7 +226,7 @@ check_add_mapping (const char *name, size_t namelen, int fd, sem_t *existing)
        }
 
       /* Release the lock.  */
-      lll_unlock (__sem_mappings_lock);
+      lll_unlock (__sem_mappings_lock, LLL_PRIVATE);
     }
 
   if (result != existing && existing != SEM_FAILED && existing != MAP_FAILED)
@@ -247,7 +248,7 @@ sem_open (const char *name, int oflag, ...)
   int fd;
 
   /* Determine where the shmfs is mounted.  */
-  __pthread_once (&__namedsem_once, __where_is_shmfs);
+  INTUSE(__pthread_once) (&__namedsem_once, __where_is_shmfs);
 
   /* If we don't know the mount points there is nothing we can do.  Ever.  */
   if (mountpoint.dir == NULL)
@@ -317,24 +318,29 @@ sem_open (const char *name, int oflag, ...)
        }
 
       /* Create the initial file content.  */
-      sem_t initsem;
+      union
+      {
+       sem_t initsem;
+       struct new_sem newsem;
+      } sem;
 
-      struct sem *iinitsem = (struct sem *) &initsem;
-      iinitsem->count = value;
+      sem.newsem.value = value;
+      sem.newsem.private = 0;
+      sem.newsem.nwaiters = 0;
 
       /* Initialize the remaining bytes as well.  */
-      memset ((char *) &initsem + sizeof (struct sem), '\0',
-             sizeof (sem_t) - sizeof (struct sem));
+      memset ((char *) &sem.initsem + sizeof (struct new_sem), '\0',
+             sizeof (sem_t) - sizeof (struct new_sem));
 
       tmpfname = (char *) alloca (mountpoint.dirlen + 6 + 1);
-      char *xxxxxx = mempcpy (tmpfname, mountpoint.dir, mountpoint.dirlen);
-      strcpy (xxxxxx, "XXXXXX");
+      mempcpy (mempcpy (tmpfname, mountpoint.dir, mountpoint.dirlen),
+       "XXXXXX", 7);
 
-      fd = __gen_tempname (tmpfname, __GT_FILE, mode);
+      fd = __gen_tempname (tmpfname, __GT_FILE, 0, mode);
       if (fd == -1)
-          return SEM_FAILED;
+        return SEM_FAILED;
 
-      if (TEMP_FAILURE_RETRY (__libc_write (fd, &initsem, sizeof (sem_t)))
+      if (TEMP_FAILURE_RETRY (__libc_write (fd, &sem.initsem, sizeof (sem_t)))
          == sizeof (sem_t)
          /* Map the sem_t structure from the file.  */
          && (result = (sem_t *) mmap (NULL, sizeof (sem_t),