OSDN Git Service

libc: Add canonicalize_file_name function
authorCarmelo Amoroso <carmelo.amoroso@st.com>
Thu, 16 Sep 2010 10:22:34 +0000 (12:22 +0200)
committerCarmelo Amoroso <carmelo.amoroso@st.com>
Thu, 16 Sep 2010 10:22:34 +0000 (12:22 +0200)
Add canonicalize_file_name function and its related tests.
Required by elfutils and coreutils (readlink).

Signed-off-by: Salvatore Cro <salvatore.cro@st.com>
Signed-off-by: Carmelo Amoroso <carmelo.amoroso@st.com>
include/stdlib.h
libc/stdlib/Makefile.in
libc/stdlib/canonicalize.c [new file with mode: 0644]
libc/stdlib/realpath.c
test/stdlib/test-canon2.c [new file with mode: 0644]

index 155b8f1..ce92ccd 100644 (file)
@@ -655,22 +655,21 @@ extern int system (__const char *__command) __wur;
 __END_NAMESPACE_STD
 
 
-#if 0 /* def   __USE_GNU */
+#ifdef __USE_GNU
 /* Return a malloc'd string containing the canonical absolute name of the
    existing named file.  */
 extern char *canonicalize_file_name (__const char *__name)
      __THROW __nonnull ((1)) __wur;
 #endif
 
-/* Return the canonical absolute name of file NAME.  If RESOLVED is
-   null, the result is malloc'd; otherwise, if the canonical name is
-   PATH_MAX chars or more, returns null with `errno' set to
-   ENAMETOOLONG; if the name fits in fewer than PATH_MAX chars,
-   returns the name in RESOLVED.  */
+/* Return the canonical absolute name of file NAME. If the
+   canonical name is PATH_MAX chars or more, returns null
+   with `errno' set to ENAMETOOLONG; if the name fits in
+        fewer than PATH_MAX chars, returns the name in RESOLVED. */
 /* we choose to handle __resolved==NULL as crash :) */
 extern char *realpath (__const char *__restrict __name,
                       char *__restrict __resolved) __THROW __wur;
-
+libc_hidden_proto(realpath)
 
 /* Shorthand for type of comparison functions.  */
 #ifndef __COMPAR_FN_T
index 0f174ee..760ccf7 100644 (file)
@@ -12,7 +12,7 @@ include $(top_srcdir)libc/stdlib/malloc-simple/Makefile.in
 include $(top_srcdir)libc/stdlib/malloc-standard/Makefile.in
 
 CSRC-y := \
-       abort.c getenv.c mkdtemp.c realpath.c mkstemp.c \
+       abort.c getenv.c mkdtemp.c realpath.c canonicalize.c mkstemp.c \
        rand.c random.c random_r.c setenv.c div.c ldiv.c lldiv.c \
        getpt.c drand48-iter.c jrand48.c \
        jrand48_r.c lrand48.c lrand48_r.c mrand48.c mrand48_r.c nrand48.c \
diff --git a/libc/stdlib/canonicalize.c b/libc/stdlib/canonicalize.c
new file mode 100644 (file)
index 0000000..06e710a
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * canonicalize.c -- Return a malloc'd string containing the canonical
+ * absolute name of the named file.  The last file name component need
+ * not exist, and may be a symlink to a nonexistent file.
+ * Copyright (C) 2009 STMicroelectronics
+ * Author: Salvatore Cro <salvatore.cro@st.com>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#include <stdlib.h>
+#include <limits.h>
+
+#ifdef __USE_GNU
+
+#ifndef PATH_MAX
+# ifdef _POSIX_VERSION
+#  define PATH_MAX _POSIX_PATH_MAX
+# else
+#  ifdef MAXPATHLEN
+#   define PATH_MAX MAXPATHLEN
+#  else
+#   define PATH_MAX 1024
+#  endif
+# endif
+#endif
+
+char * canonicalize_file_name (const char *name)
+{
+       char *buf = (char *) malloc(PATH_MAX);
+
+       if(unlikely(buf == NULL))
+               return NULL;
+
+       *buf='\0';
+       return realpath (name, buf);
+}
+#endif
index 80c25f0..cf9d45f 100644 (file)
@@ -159,3 +159,4 @@ char *realpath(const char *path, char got_path[])
        *new_path = '\0';
        return got_path;
 }
+libc_hidden_def(realpath)
diff --git a/test/stdlib/test-canon2.c b/test/stdlib/test-canon2.c
new file mode 100644 (file)
index 0000000..f182e95
--- /dev/null
@@ -0,0 +1,75 @@
+/* Test for realpath/canonicalize function.
+   Copyright (C) 1998 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
+
+   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 <string.h>
+
+
+/* Prototype for our test function.  */
+extern void do_prepare (int argc, char *argv[]);
+extern int do_test (int argc, char *argv[]);
+
+/* We have a preparation function.  */
+#define PREPARE do_prepare
+
+#include <test-skeleton.c>
+
+/* Name of the temporary files we create.  */
+char *name1;
+char *name2;
+
+/* Preparation.  */
+void
+do_prepare (int argc, char *argv[])
+{
+  size_t test_dir_len;
+
+  test_dir_len = strlen (test_dir);
+
+  /* Generate the circular symlinks.  */
+  name1 = malloc (test_dir_len + sizeof ("/canonXXXXXX"));
+  mempcpy (mempcpy (name1, test_dir, test_dir_len),
+          "/canonXXXXXX", sizeof ("/canonXXXXXX"));
+  name2 = strdup (name1);
+
+  add_temp_file (mktemp (name1));
+  add_temp_file (mktemp (name2));
+}
+
+
+/* Run the test.  */
+int
+do_test (int argc, char *argv[])
+{
+  char *canon;
+
+  printf ("create symlinks from %s to %s and vice versa\n", name1, name2);
+  if (symlink (name1, name2) == -1
+      || symlink (name2, name1) == -1)
+    /* We cannot test this.  */
+    return 0;
+
+  /* Call the function.  This is equivalent the using `realpath' but the
+     function allocates the room for the result.  */
+  errno = 0;
+  canon = canonicalize_file_name (name1);
+
+  return canon != NULL || errno != ELOOP;
+}