about summary refs log tree commit diff homepage
diff options
context:
space:
mode:
-rw-r--r--runtime/POSIX/stubs.c12
-rw-r--r--test/Runtime/POSIX/CanonicalizeFileName.c16
2 files changed, 25 insertions, 3 deletions
diff --git a/runtime/POSIX/stubs.c b/runtime/POSIX/stubs.c
index bb528ad4..6b87ad8d 100644
--- a/runtime/POSIX/stubs.c
+++ b/runtime/POSIX/stubs.c
@@ -7,8 +7,6 @@
 //
 //===----------------------------------------------------------------------===//
 
-#define _XOPEN_SOURCE 700
-
 #include <errno.h>
 #include <limits.h>
 #include <signal.h>
@@ -265,7 +263,15 @@ gnu_dev_type gnu_dev_makedev(unsigned int __major, unsigned int __minor) {
 
 char *canonicalize_file_name (const char *name) __attribute__((weak));
 char *canonicalize_file_name (const char *name) {
-  return realpath(name, NULL);
+  // Although many C libraries allocate resolved_name in realpath() if it is NULL,
+  // this behaviour is implementation-defined (POSIX) and not implemented in uclibc.
+  char * resolved_name = malloc(PATH_MAX);
+  if (!resolved_name) return NULL;
+  if (!realpath(name, resolved_name)) {
+    free(resolved_name);
+    return NULL;
+  }
+  return resolved_name;
 }
 
 int getloadavg(double loadavg[], int nelem) __attribute__((weak));
diff --git a/test/Runtime/POSIX/CanonicalizeFileName.c b/test/Runtime/POSIX/CanonicalizeFileName.c
new file mode 100644
index 00000000..56b02327
--- /dev/null
+++ b/test/Runtime/POSIX/CanonicalizeFileName.c
@@ -0,0 +1,16 @@
+// REQUIRES: not-darwin
+// RUN: %llvmgcc %s -Wall -emit-llvm -g -O0 -c -o %t.bc
+// RUN: rm -rf %t.klee-out
+// RUN: %klee --output-dir=%t.klee-out --libc=uclibc --posix-runtime --exit-on-error %t.bc
+
+#define _GNU_SOURCE
+#include <limits.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+int main(int argc, char * argv[]) {
+  char cwd[PATH_MAX] = {0};
+
+  if (!getcwd(cwd, PATH_MAX)) exit(EXIT_FAILURE);
+  if (!canonicalize_file_name(cwd)) exit(EXIT_FAILURE);
+}