diff --git a/com.oracle.truffle.r.native/fficall/jni/src/rfficall.c b/com.oracle.truffle.r.native/fficall/jni/src/rfficall.c
index a992a9515142d7fcbe0c1a16dbcf4a64f9adc750..30b78ec6aafcac1fff8add78694b974183a662d5 100644
--- a/com.oracle.truffle.r.native/fficall/jni/src/rfficall.c
+++ b/com.oracle.truffle.r.native/fficall/jni/src/rfficall.c
@@ -43,6 +43,11 @@ Java_com_oracle_truffle_r_runtime_ffi_jnr_JNI_1CallRFFI_initialize(JNIEnv *env,
 	init_listaccess(env);
 }
 
+JNIEXPORT void JNICALL
+Java_com_oracle_truffle_r_runtime_ffi_jnr_JNI_1CallRFFI_nativeSetTempDir(JNIEnv *env, jclass c, jstring tempDir) {
+	setTempDir(env, tempDir);
+}
+
 static jmp_buf error_jmpbuf;
 
 // Boilerplate methods for the actual calls
diff --git a/com.oracle.truffle.r.native/fficall/jni/src/rffiutils.h b/com.oracle.truffle.r.native/fficall/jni/src/rffiutils.h
index 1181bc5aeb6cfef4717e95d637bfe3210f5b91dd..47f4e5235d4be88ca921f14539a55c63351b5c37 100644
--- a/com.oracle.truffle.r.native/fficall/jni/src/rffiutils.h
+++ b/com.oracle.truffle.r.native/fficall/jni/src/rffiutils.h
@@ -80,6 +80,8 @@ void init_vectoraccess(JNIEnv *env);
 void init_listaccess(JNIEnv *env);
 void init_utils(JNIEnv *env);
 
+void setTempDir(JNIEnv *, jstring tempDir);
+
 extern jclass RDataFactoryClass;
 extern jclass CallRFFIHelperClass;
 extern jclass RRuntimeClass;
diff --git a/com.oracle.truffle.r.native/fficall/jni/src/variables.c b/com.oracle.truffle.r.native/fficall/jni/src/variables.c
index 07776f29085fd07f70028d94fe69c8bd7c26d330..c461839e551d6b22a85769fed57d161e60d43155 100644
--- a/com.oracle.truffle.r.native/fficall/jni/src/variables.c
+++ b/com.oracle.truffle.r.native/fficall/jni/src/variables.c
@@ -171,8 +171,6 @@ void init_variables(JNIEnv *env, jobjectArray initialValues) {
 		if (value != NULL) {
 			if (strcmp(nameChars, "R_Home") == 0) {
 				R_Home = (*env)->GetStringUTFChars(env, value, NULL);
-			} else if (strcmp(nameChars, "R_TempDir") == 0) {
-				R_TempDir = (*env)->GetStringUTFChars(env, value, NULL);
 			} else if (strcmp(nameChars, "R_NaN") == 0) {
 				R_NaN = (*env)->CallDoubleMethod(env, value, doubleValueMethodID);
 			} else if (strcmp(nameChars, "R_PosInf") == 0) {
@@ -274,3 +272,7 @@ void init_variables(JNIEnv *env, jobjectArray initialValues) {
 	}
 }
 
+void setTempDir(JNIEnv *env, jstring tempDir) {
+	R_TempDir = (*env)->GetStringUTFChars(env, tempDir, NULL);
+}
+
diff --git a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jnr/RFFIUtils.java b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/RFFIUtils.java
similarity index 53%
rename from com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jnr/RFFIUtils.java
rename to com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/RFFIUtils.java
index ff4f1dbe6318b82093f6350502dc926a5dc854ae..243996320a724189216a0b4d44a9ce6202c7bc2f 100644
--- a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jnr/RFFIUtils.java
+++ b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/RFFIUtils.java
@@ -20,28 +20,54 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-package com.oracle.truffle.r.runtime.ffi.jnr;
+package com.oracle.truffle.r.runtime.ffi;
 
 import java.io.IOException;
 
 import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
+import com.oracle.truffle.r.runtime.FastROptions;
+import com.oracle.truffle.r.runtime.data.RPairList;
+import com.oracle.truffle.r.runtime.data.RTypedValue;
 
 public class RFFIUtils {
-    static byte[] wrapChar(char v) {
+    public static byte[] wrapChar(char v) {
         return new byte[]{(byte) v};
     }
 
-    static int[] wrapInt(int v) {
+    public static int[] wrapInt(int v) {
         return new int[]{v};
     }
 
-    static double[] wrapDouble(double v) {
+    public static double[] wrapDouble(double v) {
         return new double[]{v};
     }
 
     @TruffleBoundary
-    static IOException ioex(String errMsg) throws IOException {
+    public static IOException ioex(String errMsg) throws IOException {
         throw new IOException(errMsg);
     }
 
+    public static void traceCall(String name, Object... args) {
+        if (FastROptions.TraceNativeCalls.getBooleanValue()) {
+            System.out.print("CallRFFI " + name + ": ");
+            printArgs(args);
+            System.out.println();
+        }
+    }
+
+    private static void printArgs(Object[] args) {
+        for (Object arg : args) {
+            System.out.print(" ");
+            System.out.print(arg == null ? "" : arg.getClass().getSimpleName());
+            if (arg instanceof RPairList) {
+                System.out.print("[");
+                printArgs(((RPairList) arg).toRList().getDataCopy());
+                System.out.print("]");
+            }
+            if (!(arg instanceof RTypedValue)) {
+                System.out.print("(" + arg + ")");
+            }
+        }
+    }
+
 }
diff --git a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/RVariables.java b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/RFFIVariables.java
similarity index 94%
rename from com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/RVariables.java
rename to com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/RFFIVariables.java
index ca92588fa01e720c92232cd1ec00a5b97c8f16cb..47948a1b3c010df9e44b7d330f883968267769f2 100644
--- a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/RVariables.java
+++ b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/RFFIVariables.java
@@ -30,9 +30,9 @@ import com.oracle.truffle.r.runtime.data.RNull;
 import com.oracle.truffle.r.runtime.data.RUnboundValue;
 import com.oracle.truffle.r.runtime.env.REnvironment;
 
-public enum RVariables {
+public enum RFFIVariables {
     R_Home(REnvVars.rHome()),
-    R_TempDir("/tmp/R_TMP"), // TODO: supply proper temp directory
+    R_TempDir(null), // Set later with setTmpDir
     R_NilValue(RNull.instance),
     R_UnboundValue(RUnboundValue.instance),
     R_MissingArg(RMissing.instance),
@@ -81,13 +81,17 @@ public enum RVariables {
     R_FalseValue(RRuntime.LOGICAL_FALSE),
     R_LogicalNAValue(RRuntime.LOGICAL_NA);
 
-    private final Object value;
+    private Object value;
 
-    RVariables(Object value) {
+    RFFIVariables(Object value) {
         this.value = value;
     }
 
     public Object getValue() {
         return value;
     }
+
+    public static void setTempDir(String tempDir) {
+        R_TempDir.value = tempDir;
+    }
 }
diff --git a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jnr/JNI_CallRFFI.java b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jnr/JNI_CallRFFI.java
index 897796c020205b7c308fba898b6fab7a209c6aee..0adb3750888e6f8407ec84e442aeef69ea89f01f 100644
--- a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jnr/JNI_CallRFFI.java
+++ b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jnr/JNI_CallRFFI.java
@@ -22,6 +22,8 @@
  */
 package com.oracle.truffle.r.runtime.ffi.jnr;
 
+import static com.oracle.truffle.r.runtime.ffi.RFFIUtils.traceCall;
+
 import java.util.concurrent.Semaphore;
 
 import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
@@ -31,7 +33,7 @@ import com.oracle.truffle.r.runtime.data.RPairList;
 import com.oracle.truffle.r.runtime.data.RTypedValue;
 import com.oracle.truffle.r.runtime.ffi.CallRFFI;
 import com.oracle.truffle.r.runtime.ffi.DLL;
-import com.oracle.truffle.r.runtime.ffi.RVariables;
+import com.oracle.truffle.r.runtime.ffi.RFFIVariables;
 import com.oracle.truffle.r.runtime.ffi.DLL.DLLException;
 import com.oracle.truffle.r.runtime.ffi.LibPaths;
 
@@ -67,17 +69,14 @@ public class JNI_CallRFFI implements CallRFFI {
             throw new RInternalError(ex, "error while loading " + librffiPath);
         }
         System.load(librffiPath);
-        initialize(RVariables.values());
+        traceCall("initialize");
+        initialize(RFFIVariables.values());
     }
 
     private static final Semaphore inCritical = new Semaphore(1, false);
 
     public Object invokeCall(long address, String name, Object[] args) {
-        if (FastROptions.TraceNativeCalls.getBooleanValue()) {
-            System.out.print("calling " + name + ": ");
-            printArgs(args);
-            System.out.println();
-        }
+        traceCall(name, args);
         try {
             inCritical.acquire();
             switch (args.length) {
@@ -103,22 +102,9 @@ public class JNI_CallRFFI implements CallRFFI {
         }
     }
 
-    private void printArgs(Object[] args) {
-        for (Object arg : args) {
-            System.out.print(" ");
-            System.out.print(arg == null ? "" : arg.getClass().getSimpleName());
-            if (arg instanceof RPairList) {
-                System.out.print("[");
-                printArgs(((RPairList) arg).toRList().getDataCopy());
-                System.out.print("]");
-            }
-            if (!(arg instanceof RTypedValue)) {
-                System.out.print("(" + arg + ")");
-            }
-        }
-    }
+    private static native void initialize(RFFIVariables[] variables);
 
-    private static native void initialize(RVariables[] variables);
+    private static native void nativeSetTempDir(String tempDir);
 
     private static native Object call(long address, Object[] args);
 
@@ -143,11 +129,7 @@ public class JNI_CallRFFI implements CallRFFI {
     private static native Object call9(long address, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7, Object arg8, Object arg9);
 
     public void invokeVoidCall(long address, String name, Object[] args) {
-        if (FastROptions.TraceNativeCalls.getBooleanValue()) {
-            System.out.print("void-calling " + name + ": ");
-            printArgs(args);
-            System.out.println();
-        }
+        traceCall(name, args);
         try {
             inCritical.acquire();
             switch (args.length) {
@@ -165,4 +147,16 @@ public class JNI_CallRFFI implements CallRFFI {
 
     private static native void callVoid1(long address, Object arg1);
 
+    public void setTempDir(String tempDir) {
+        traceCall("setTempDir", tempDir);
+        try {
+            inCritical.acquire();
+            RFFIVariables.setTempDir(tempDir);
+            nativeSetTempDir(tempDir);
+        } catch (InterruptedException ex) {
+        } finally {
+            inCritical.release();
+        }
+    }
+
 }
diff --git a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jnr/JNR_Base.java b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jnr/JNR_Base.java
index fc6e3b43cc3ffe8762bdff694c4efbc89572e3fb..2cd54b6db4db2885ecc9cad9b20232375c9c4257 100644
--- a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jnr/JNR_Base.java
+++ b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jnr/JNR_Base.java
@@ -22,7 +22,7 @@
  */
 package com.oracle.truffle.r.runtime.ffi.jnr;
 
-import static com.oracle.truffle.r.runtime.ffi.jnr.RFFIUtils.ioex;
+import static com.oracle.truffle.r.runtime.ffi.RFFIUtils.ioex;
 
 import java.io.IOException;
 import java.nio.ByteBuffer;
diff --git a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jnr/JNR_Lapack.java b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jnr/JNR_Lapack.java
index eeef7857f90f96701e3918db5a46d2b9a0871266..fedfd56ad65c45322cb822f29f80139e04bfe08a 100644
--- a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jnr/JNR_Lapack.java
+++ b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jnr/JNR_Lapack.java
@@ -22,9 +22,9 @@
  */
 package com.oracle.truffle.r.runtime.ffi.jnr;
 
-import static com.oracle.truffle.r.runtime.ffi.jnr.RFFIUtils.wrapChar;
-import static com.oracle.truffle.r.runtime.ffi.jnr.RFFIUtils.wrapDouble;
-import static com.oracle.truffle.r.runtime.ffi.jnr.RFFIUtils.wrapInt;
+import static com.oracle.truffle.r.runtime.ffi.RFFIUtils.wrapChar;
+import static com.oracle.truffle.r.runtime.ffi.RFFIUtils.wrapDouble;
+import static com.oracle.truffle.r.runtime.ffi.RFFIUtils.wrapInt;
 import jnr.ffi.LibraryLoader;
 import jnr.ffi.annotations.In;
 import jnr.ffi.annotations.Out;
diff --git a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jnr/JNR_RAppl.java b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jnr/JNR_RAppl.java
index 90522b8bce43d4b11c404b08952da623ca8d4fbe..3038ba1ff00fc32bb494dda3325842bd0c26edc5 100644
--- a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jnr/JNR_RAppl.java
+++ b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jnr/JNR_RAppl.java
@@ -22,8 +22,8 @@
  */
 package com.oracle.truffle.r.runtime.ffi.jnr;
 
-import static com.oracle.truffle.r.runtime.ffi.jnr.RFFIUtils.wrapDouble;
-import static com.oracle.truffle.r.runtime.ffi.jnr.RFFIUtils.wrapInt;
+import static com.oracle.truffle.r.runtime.ffi.RFFIUtils.wrapDouble;
+import static com.oracle.truffle.r.runtime.ffi.RFFIUtils.wrapInt;
 import jnr.ffi.LibraryLoader;
 import jnr.ffi.annotations.In;
 import jnr.ffi.annotations.Out;
diff --git a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jnr/JNR_Stats.java b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jnr/JNR_Stats.java
index 31814b04f6cc85b1097a1390d2af48de16faac5b..b012dbca503412095153feff304c5d60b34b9f2c 100644
--- a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jnr/JNR_Stats.java
+++ b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jnr/JNR_Stats.java
@@ -22,7 +22,7 @@
  */
 package com.oracle.truffle.r.runtime.ffi.jnr;
 
-import static com.oracle.truffle.r.runtime.ffi.jnr.RFFIUtils.*;
+import static com.oracle.truffle.r.runtime.ffi.RFFIUtils.*;
 import jnr.ffi.LibraryLoader;
 import jnr.ffi.annotations.In;
 
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/TempPathName.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/TempPathName.java
index 9f497a9c02e4be0cf0e1c9428906a3156bc0dd67..babcda198be0be8a0558eebdab2ef30b95c242ae 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/TempPathName.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/TempPathName.java
@@ -68,6 +68,7 @@ public class TempPathName {
             } else {
                 Utils.fail("cannot create 'R_TempDir'");
             }
+            RFFIFactory.getRFFI().getCallRFFI().setTempDir(tempDirPath);
         }
     }
 
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/CallRFFI.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/CallRFFI.java
index 1565fe9c605e9960e198154fea66849fecb89ef2..57aaccd52db9cf7d102cb569d1d1b67215f2436b 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/CallRFFI.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/CallRFFI.java
@@ -41,4 +41,10 @@ public interface CallRFFI {
      * Variant that does not return a result (primarily for library "init" methods).
      */
     void invokeVoidCall(long address, String name, Object[] args);
+
+    /**
+     * This interface is initialized very early, before the {@code tempDir} is established. This
+     * call sets the value.
+     */
+    void setTempDir(String tempDir);
 }