about summary refs log tree commit diff homepage
path: root/runtime/POSIX/misc.c
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/POSIX/misc.c')
-rw-r--r--runtime/POSIX/misc.c87
1 files changed, 87 insertions, 0 deletions
diff --git a/runtime/POSIX/misc.c b/runtime/POSIX/misc.c
new file mode 100644
index 00000000..12ff2f58
--- /dev/null
+++ b/runtime/POSIX/misc.c
@@ -0,0 +1,87 @@
+//===-- misc.c ------------------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <assert.h>
+#include <unistd.h>
+#include <sys/syscall.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <klee/klee.h>
+#include <string.h>
+
+#if 0
+#define MAX_SYM_ENV_SIZE 32
+typedef struct {
+  char name[MAX_SYM_ENV_SIZE];
+  char *value;
+} sym_env_var;
+
+static sym_env_var *__klee_sym_env = 0;
+static unsigned __klee_sym_env_count = 0;
+static unsigned __klee_sym_env_nvars = 0;
+static unsigned __klee_sym_env_var_size = 0;
+void __klee_init_environ(unsigned nvars, 
+                         unsigned var_size) {
+  assert(var_size);
+  __klee_sym_env = malloc(sizeof(*__klee_sym_env) * nvars);
+  assert(__klee_sym_env);
+
+  __klee_sym_env_nvars = nvars;
+  __klee_sym_env_var_size = var_size;  
+}
+
+static unsigned __strlen(const char *s) {
+  const char *s2 = s;
+  while (*s2) ++s2;
+  return s2-s;
+}
+
+extern char *__getenv(const char *name);
+char *getenv(const char *name) {
+  char *res = __getenv(name);
+
+  if (!__klee_sym_env_nvars)
+    return res;
+
+  /* If it exists in the system environment fork and return the actual
+     result or 0. */
+  if (res) {
+    return klee_range(0, 2, name) ? res : 0;
+  } else {
+    unsigned i, len = __strlen(name);
+
+    if (len>=MAX_SYM_ENV_SIZE) {
+      /* Don't deal with strings to large to fit in our name. */
+      return 0;
+    } else {
+      /* Check for existing entry */
+      for (i=0; i<__klee_sym_env_count; ++i)
+        if (memcmp(__klee_sym_env[i].name, name, len+1)==0)
+          return __klee_sym_env[i].value;
+      
+      /* Otherwise create if room and we choose to */
+      if (__klee_sym_env_count < __klee_sym_env_nvars) {
+        if (klee_range(0, 2, name)) {
+          char *s = malloc(__klee_sym_env_var_size+1);
+          klee_make_symbolic(s, __klee_sym_env_var_size+1);
+          s[__klee_sym_env_var_size] = '\0';
+          
+          memcpy(__klee_sym_env[__klee_sym_env_count].name, name, len+1);
+          __klee_sym_env[__klee_sym_env_count].value = s;
+          ++__klee_sym_env_count;
+          
+          return s;
+        }
+      }
+      
+      return 0;
+    }
+  }
+}
+#endif