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