Changeset: b9886517465a for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=b9886517465a
Modified Files:
        monetdb5/extras/rapi/rapi.c
Branch: RIntegration
Log Message:

R API: Fixed stack smashing issue


diffs (145 lines):

diff --git a/monetdb5/extras/rapi/rapi.c b/monetdb5/extras/rapi/rapi.c
--- a/monetdb5/extras/rapi/rapi.c
+++ b/monetdb5/extras/rapi/rapi.c
@@ -27,15 +27,19 @@
 #include "mal_linker.h"
 
 #include "rapi.h"
-//
+
 // R headers
+
+#define R_INTERFACE_PTRS 1
+#define CSTACK_DEFNS 1
+
 #include <Rembedded.h>
 #include <Rdefines.h>
-#define R_INTERFACE_PTRS
 #include <Rinterface.h>
 #include <Rinternals.h>
 #include <R_ext/Parse.h>
 
+// other headers
 #include <string.h>
 
 #define BAT_TO_INTSXP(bat,tpe,retsxp) { \
@@ -120,44 +124,64 @@ void writeConsoleEx(const char * buf, in
        THRprintf(GDKout, "%s", buf);
 }
 
-static void RAPIinitialize(void) {
+static int RAPIinitialize(void) {
        char *rargv[] = { "whatever", "--quiet", "--no-save", 
"--no-restore-data" };
-       char* rhome = "/usr/lib64/R"; // TODO: get this from ./configure or a 
call to system()
+       int rargc = 4;
        int evalErr;
        ParseStatus status;
        char rlibs[BUFSIZ];
        char rapiinclude[BUFSIZ];
 
-
-
+       // adapted from Rinit.c (JRI package)
        MT_lock_init(&rapiLock, "rapi_lock");
 
+    if (!getenv("R_HOME")) {
+        return 1;
+    }
+
+       // TODO: put this into dbfarm
        snprintf(rlibs, BUFSIZ, "%s%c%s%c%s%c%s",
                 LOCALSTATEDIR, DIR_SEP, "monetdb5", DIR_SEP, "rapi",
                 DIR_SEP, "libs");
 
-       snprintf(rapiinclude, BUFSIZ, "source(\"%s\")",
-                       locate_file("rapi",".R",0));
 
-       setenv("R_HOME",rhome,TRUE);
        setenv("R_LIBS_USER",rlibs,TRUE);
 
-       R_SignalHandlers = 0;
+#ifdef RIF_HAS_RSIGHAND
+    R_SignalHandlers=0;
+#endif
+    {
+      int stat=Rf_initialize_R(rargc, rargv);
+      if (stat<0) {
+        return 2;
+      }
+    }
 
-       Rf_initEmbeddedR(4, rargv);
+#ifdef RIF_HAS_RSIGHAND
+    R_SignalHandlers=0;
+#endif
+    /* disable stack checking, because threads will thow it off */
+    R_CStackLimit = (uintptr_t) -1;
 
+    R_Interactive = 0;
        ptr_R_WriteConsole = writeConsole;
        ptr_R_WriteConsoleEx = writeConsoleEx;
        R_Outputfile = NULL;
        R_Consolefile = NULL;
 
+       // big boy here
+       setup_Rmainloop();
+
        // run the R environment initialization script rapi.R
+       snprintf(rapiinclude, BUFSIZ, "source(\"%s\")",
+               locate_file("rapi",".R",0));
        R_tryEval(
                VECTOR_ELT(
                        R_ParseVector(
                                mkString(rapiinclude),1, &status, R_NilValue), 
0),R_GlobalEnv,&evalErr);
 
        rapiInitialized++;
+       return 0;
 }
 
 str RAPIparser(int *ret, str *rcall){
@@ -189,10 +213,8 @@ str RAPIeval(Client cntxt, MalBlkPtr mb,
        char *msg = createException(MAL, "rapi.eval", "NYI");
        BAT *b;
        BUN cnt;
+       int initstatus = 0;
 
-       /* startup internal R environment if needed */
-       if (!rapiInitialized)
-               RAPIinitialize();
 
        rcall = malloc(strlen(exprStr) + sizeof(argnames) + 100);
        if (rcall==NULL) {
@@ -205,6 +227,16 @@ str RAPIeval(Client cntxt, MalBlkPtr mb,
                throw(MAL, "rapi.eval", MAL_MALLOC_FAIL);
        }
 
+       /* startup internal R environment if needed */
+       if (!rapiInitialized) {
+               initstatus = RAPIinitialize();
+               if (initstatus != 0) {
+                       msg = createException(MAL, "rapi.eval",
+                                       "failed to initialize R environment 
(%i)",initstatus);
+                       goto wrapup;
+               }
+       }
+
 #ifdef _RAPI_DEBUG_
        mnstr_printf(cntxt->fdout, "# User R expression: %s\n", exprStr);
 #else
@@ -424,13 +456,14 @@ str RAPIeval(Client cntxt, MalBlkPtr mb,
                BBPkeepref(b->batCacheid);
                msg = MAL_SUCCEED;
        }
+       /* unprotect environment, so it will be eaten by the GC. */
+       UNPROTECT(1);
        wrapup:
        MT_lock_unset(&rapiLock, "rapi.evaluate");
        free(rcall);
        GDKfree(args);
 
-       /* unprotect environment, so it will be eaten by the GC. */
-       UNPROTECT(1);
+
        return msg;
 }
 
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to