Changeset 418

Show
Ignore:
Timestamp:
Thu Feb 7 07:38:12 2008
Author:
giovannibajo
Message:

Improve the code to generate the temporary directory.

On Windows, there's no race-free library function, so we use
_tempnam which ensure uniqueness at the time of call, and then
create the directory afterwards. If it fails before of a race,
we retry a few times. Anyway, we keep the pid in the name prefix,
so that it's hard to foresee a race.

On Linux and Mac OSX, we use mkdtemp() which is totally race-free
and creates the directory for us. This part still needs testing
but should work.

Files:

Legend:

Unmodified
Added
Removed
Modified
  • branches/startup_crash/source/common/launch.c

    r417 r418  
    171 171 #endif /* _CONSOLE */  
    172 172  
    173   int testTempPath(char *buff)  
    174   {  
    175           char base[16];  
    176           int n;  
    177 173  
    178           n = strlen(buff);  
    179           if ( buff[n-1] == '/' || buff[n-1] == '\\' )  
    180                   sprintf(base, "_MEI%d", getpid());  
    181           else  
    182                   sprintf(base, "%s_MEI%d", SEP, getpid());  
    183           strcat(buff, base);  
    184 174 #ifdef WIN32  
    185           if (mkdir(buff) == 0) {  
      175  
      176 int getTempPath(char *buff)  
      177 {  
      178     int i;  
      179     char *ret;  
      180     char prefix[16];  
      181  
      182     GetTempPath(MAX_PATH, buff);  
      183     sprintf(prefix, "_MEI%d", getpid());  
      184  
      185     // Windows does not have a race-free function to create a temporary  
      186     // directory. Thus, we rely on _tempnam, and simply try several times  
      187     // to avoid stupid race conditions.  
      188     for (i=0;i<5;i++) {  
      189         ret = _tempnam(buff, prefix);  
      190         if (mkdir(ret) == 0) {  
      191             strcpy(buff, ret);  
      192             strcat(buff, "\\");  
      193             free(ret);  
      194             return 1;  
      195         }  
      196         free(ret);  
      197     }  
      198     return 0;  
      199 }  
      200  
    186 201 #else  
    187           if (mkdir(buff, 0700) == 0) {  
    188   #endif  
    189                   strcat(buff, SEP);  
    190                   return 1;  
    191           }  
    192           return 0;  
      202  
      203 int testTempPath(char *buff)  
      204 {  
      205         strcat(buff, "/_MEIXXXXXX");  
      206     if (mkdtemp(buff))  
      207     {  
      208         strcat(buff, "/");  
      209         return 1;  
      210     }  
      211     return 0;     
    193 212 }  
    194 213  
    195 214 int getTempPath(char *buff)  
    196 215 {  
    197   #ifdef WIN32  
    198           GetTempPath(MAX_PATH, buff);  
    199           if (testTempPath(buff))  
    200           return 1;  
    201   #else  
    202 216         static const char *envname[] = {  
    203 217                 "TMPDIR", "TEMP", "TMP", 0  
     
    221 235                         return 1;  
    222 236         }  
    223   #endif  
    224           buff[0] = '\0';  
    225           return 0;  
      237     return 0;  
    226 238 }  
      239  
      240 #endif  
      241  
    227 242 /*  
    228 243  * Set up paths required by rest of this module