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
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list