From jeff.horner at vanderbilt.edu  Fri Sep  1 17:03:21 2006
From: jeff.horner at vanderbilt.edu (Jeffrey Horner)
Date: Fri, 01 Sep 2006 10:03:21 -0500
Subject: [Rd] Overriding InitTempDir
In-Reply-To: <44F75DA4.6000209@vanderbilt.edu>
References: <44F75DA4.6000209@vanderbilt.edu>
Message-ID: <44F84BB9.5050107@vanderbilt.edu>

Jeffrey Horner wrote:
> For embedded projects, one may want to eliminate the per-session temp 
> directory created by InitTempDir() and just use a system-specific temp 
> directory. Here's my solution:
> 
> extern char *R_TempDir;
> 
> void my_InitTempDir()
> {
>      char *tmp;
> 
>      if (R_TempDir){
>          if (rmdir(R_TempDir) != 0){
>              perror("Fatal Error: could not remove R's TempDir!");
>              exit(1);
>          }
>      }
> 
>      tmp = getenv("TMPDIR");
>      if (tmp == NULL) {
>          tmp = getenv("TMP");
>              if (tmp == NULL) {
>                  tmp = getenv("TEMP");
>                  if (tmp == NULL)
>                      tmp = "/tmp";
>              }
>      }
> 
>      R_TempDir=tmp;
> 
>      if (setenv("R_SESSION_TMPDIR",tmp,1) != 0){
>          perror("Fatal Error: couldn't set/replace R_SESSION_TMPDIR!");
>          exit(1);
>      }
> }
> 
> This function is called after Rf_initEmbeddedR; it's seems like a hack 
> but it works. Does anyone have other solutions?

I just found a fault with the above solution, but only if a program that 
embeds R calls the R edit function; highly unlikely. Nevertheless, It 
turns out that soon after InitTempDir is called, InitEd is called and 
sets the variable DefaultFileName (which is hidden by storage class 
static, unlike R_TempDir) to a temporary filename located in the 
directory which was just deleted by my_initTempDir.

> Maybe InitTempDir could check if R_TempDir was not NULL and then just 
> return.

So it would be nice if the above (InitTempDir only creating a directory 
when R_TempDir is NULL) could be added to R-trunk.

Note also that in the case that R_TempDir is set to a system-specific 
temp directory, the program would then have to set it back to NULL as 
the new function Rf_endEmbeddedR now tests to see if R_TempDir has been set:

/* use fatal !=0 for emergency bail out */
void Rf_endEmbeddedR(int fatal)
{
     unsigned char buf[1024];
     char * tmpdir;

     R_RunExitFinalizers();
     CleanEd();
     if(!fatal) KillAllDevices();
     if((tmpdir = R_TempDir)) {
     snprintf((char *)buf, 1024, "rm -rf %s", tmpdir);
     R_system((char *)buf);
     }
     if(!fatal && R_CollectWarnings)
     PrintWarnings();    /* from device close and .Last */
     fpu_setup(FALSE);
}

Jeff
-- 
http://biostat.mc.vanderbilt.edu/JeffreyHorner




[Rd] Overriding InitTempDir
Jeffrey Horner