about summary refs log tree commit diff
path: root/catgets
diff options
context:
space:
mode:
Diffstat (limited to 'catgets')
-rw-r--r--catgets/catgets.c95
-rw-r--r--catgets/open_catalog.c27
2 files changed, 50 insertions, 72 deletions
diff --git a/catgets/catgets.c b/catgets/catgets.c
index 55de30ee46..c6fd13d4b4 100644
--- a/catgets/catgets.c
+++ b/catgets/catgets.c
@@ -33,23 +33,12 @@ nl_catd
 catopen (const char *cat_name, int flag)
 {
   __nl_catd result;
-  const char *env_var;
-  const char *nlspath;
-
-  result = (__nl_catd) malloc (sizeof (*result));
-  if (result == NULL)
-    /* We cannot get enough memory.  */
-    return (nl_catd) -1;
-
-  result->status = closed;
-
-  result->cat_name = __strdup (cat_name);
-  if (result->cat_name == NULL)
-    {
-      free (result);
-      __set_errno (ENOMEM);
-      return (nl_catd) -1;
-    }
+  const char *env_var = NULL;
+  const char *nlspath = NULL;
+  size_t cat_name_len = strlen (cat_name) + 1;
+  size_t env_var_len = 0;
+  size_t nlspath_len = 0;
+  char *endp;
 
   if (strchr (cat_name, '/') == NULL)
     {
@@ -57,32 +46,19 @@ catopen (const char *cat_name, int flag)
 	{
 	  env_var = getenv ("LC_ALL");
 	  if (env_var == NULL)
-	    {
-	      env_var = getenv ("LC_MESSAGES");
-	      if (env_var == NULL)
-		{
-		  env_var = getenv ("LANG");
-		  if (env_var == NULL)
-		    env_var = "C";
-		}
-	    }
-	}
-      else
-	{
-	  env_var = getenv ("LANG");
-	  if (env_var == NULL)
-	    env_var = "C";
-	}
+	    env_var = getenv ("LC_MESSAGES");
 
-      result->env_var = __strdup (env_var);
-      if (result->env_var == NULL)
-	{
-	  free ((void *) result->cat_name);
-	  free ((void *) result);
-	  __set_errno (ENOMEM);
-	  return (nl_catd) -1;
+	  if (env_var != NULL)
+	    goto have_env_var;
 	}
 
+      env_var = getenv ("LANG");
+      if (env_var == NULL)
+	env_var = "C";
+
+    have_env_var:
+      env_var_len = strlen (env_var) + 1;
+
       nlspath = __secure_getenv ("NLSPATH");
       if (nlspath != NULL && *nlspath != '\0')
 	{
@@ -92,25 +68,32 @@ catopen (const char *cat_name, int flag)
 
 	  __stpcpy (__stpcpy (__stpcpy (tmp, nlspath), ":"), NLSPATH);
 	  nlspath = tmp;
+
+	  nlspath_len = len;
 	}
       else
-	nlspath = NLSPATH;
-
-      result->nlspath = __strdup (nlspath);
-      if (result->nlspath == NULL)
 	{
-	  free ((void *) result->cat_name);
-	  free ((void *) result->env_var);
-	  free ((void *) result);
-	  __set_errno (ENOMEM);
-	  return (nl_catd) -1;
+	  nlspath = NLSPATH;
+
+	  nlspath_len = sizeof NLSPATH;
 	}
     }
-  else
-    {
-      result->env_var = NULL;
-      result->nlspath = NULL;
-    }
+
+  result = (__nl_catd) malloc (sizeof (*result) + cat_name_len
+			       + env_var_len + nlspath_len);
+  if (result == NULL)
+    /* We cannot get enough memory.  */
+    return (nl_catd) -1;
+
+  result->status = closed;
+  result->cat_name = endp = (char *) (result + 1);
+  endp = __mempcpy (endp, cat_name, cat_name_len);
+
+  result->env_var = cat_name_len != 0 ? endp : NULL;
+  endp = __mempcpy (endp, env_var, env_var_len);
+
+  result->nlspath = nlspath_len != 0 ? endp : NULL;
+  memcpy (endp, nlspath, nlspath_len);
 
   __libc_lock_init (result->lock);
 
@@ -179,10 +162,6 @@ catclose (nl_catd catalog_desc)
 	return -1;
       }
 
-  if (catalog->nlspath)
-    free ((void *) catalog->nlspath);
-  if (catalog->env_var)
-    free ((void *) catalog->env_var);
   free ((void *) catalog);
 
   return 0;
diff --git a/catgets/open_catalog.c b/catgets/open_catalog.c
index e4b61d779a..4b619e49e9 100644
--- a/catgets/open_catalog.c
+++ b/catgets/open_catalog.c
@@ -1,6 +1,6 @@
-/* Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
+/* Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
-   Contributed by Ulrich Drepper, <drepper@gnu.ai.mit.edu>.
+   Contributed by Ulrich Drepper, <drepper@gnu.org>.
 
    The GNU C Library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public License as
@@ -182,10 +182,13 @@ __open_catalog (__nl_catd catalog)
     }
 
   /* Avoid dealing with directories and block devices */
-  if (fd < 0 || __fstat (fd, &st) < 0)
+  if (fd < 0)
+    goto unlock_return;
+
+  if (__fxstat (_STAT_VER, fd, &st) < 0)
     {
       catalog->status = nonexisting;
-      goto unlock_return;
+      goto close_unlock_return;
     }
   if (!S_ISREG (st.st_mode) || st.st_size < sizeof (struct catalog_obj))
     {
@@ -193,7 +196,7 @@ __open_catalog (__nl_catd catalog)
 	 Use an reasonable error value.  */
       __set_errno (EINVAL);
       catalog->status = nonexisting;
-      goto unlock_return;
+      goto close_unlock_return;
     }
 
   catalog->file_size = st.st_size;
@@ -226,7 +229,7 @@ __open_catalog (__nl_catd catalog)
       if (catalog->file_ptr == NULL)
 	{
 	  catalog->status = nonexisting;
-	  goto unlock_return;
+	  goto close_unlock_return;
 	}
       todo = st.st_size;
       /* Save read, handle partial reads.  */
@@ -238,7 +241,7 @@ __open_catalog (__nl_catd catalog)
 	    {
 	      free ((void *) catalog->file_ptr);
 	      catalog->status = nonexisting;
-	      goto unlock_return;
+	      goto close_unlock_return;
 	    }
 	  todo -= now;
 	}
@@ -246,10 +249,6 @@ __open_catalog (__nl_catd catalog)
       catalog->status = malloced;
     }
 
-  /* We don't need the file anymore.  */
-  __close (fd);
-  fd = -1;
-
   /* Determine whether the file is a catalog file and if yes whether
      it is written using the correct byte order.  Else we have to swap
      the values.  */
@@ -269,7 +268,7 @@ __open_catalog (__nl_catd catalog)
 #endif	/* _POSIX_MAPPED_FILES */
 	free (catalog->file_ptr);
       catalog->status = nonexisting;
-      goto unlock_return;
+      goto close_unlock_return;
     }
 
 #define SWAP(x) (swapping ? SWAPU32 (x) : (x))
@@ -320,8 +319,8 @@ __open_catalog (__nl_catd catalog)
     }
 
   /* Release the lock again.  */
+ close_unlock_return:
+  __close (fd);
  unlock_return:
-  if (fd != -1)
-    __close (fd);
   __libc_lock_unlock (catalog->lock);
 }