make/src/native/fixpath.c
changeset 53110 50677f43ac3d
parent 47216 71c04702a3d5
equal deleted inserted replaced
53109:b99b41325d89 53110:50677f43ac3d
    22  * or visit www.oracle.com if you need additional information or have any
    22  * or visit www.oracle.com if you need additional information or have any
    23  * questions.
    23  * questions.
    24  */
    24  */
    25 
    25 
    26 #include <Windows.h>
    26 #include <Windows.h>
       
    27 #include <stdbool.h>
    27 #include <io.h>
    28 #include <io.h>
    28 #include <stdio.h>
    29 #include <stdio.h>
    29 #include <string.h>
    30 #include <string.h>
    30 #include <malloc.h>
    31 #include <malloc.h>
    31 
    32 
    51 
    52 
    52   LocalFree(lpMsgBuf);
    53   LocalFree(lpMsgBuf);
    53 }
    54 }
    54 
    55 
    55 /*
    56 /*
    56  * Test if pos points to /cygdrive/_/ where _ can
    57  * Test if pos points to /prefix/_/ where _ can
    57  * be any character.
    58  * be any character.
    58  */
    59  */
    59 int is_cygdrive_here(int pos, char const *in, int len)
    60 int is_prefix_here(int pos, char const *in, int len, const char* prefix)
    60 {
    61 {
    61   // Length of /cygdrive/c/ is 12
    62   // Length of c/ is 2
    62   if (pos+12 > len) return 0;
    63   int prefix_size = strlen(prefix);
    63   if (in[pos+11]=='/' &&
    64   if (pos+prefix_size+2 > len) return 0;
    64       in[pos+9]=='/' &&
    65   if (in[pos+prefix_size+1]=='/') {
    65       in[pos+8]=='e' &&
    66     return strncmp(in + pos, prefix, prefix_size) == 0;
    66       in[pos+7]=='v' &&
       
    67       in[pos+6]=='i' &&
       
    68       in[pos+5]=='r' &&
       
    69       in[pos+4]=='d' &&
       
    70       in[pos+3]=='g' &&
       
    71       in[pos+2]=='y' &&
       
    72       in[pos+1]=='c' &&
       
    73       in[pos+0]=='/') {
       
    74     return 1;
       
    75   }
    67   }
    76   return 0;
    68   return 0;
    77 }
    69 }
    78 
    70 
    79 /*
    71 /*
    91     memmove(out, in, len + 1);
    83     memmove(out, in, len + 1);
    92     return out;
    84     return out;
    93   }
    85   }
    94 
    86 
    95   for (i = 0, j = 0; i<len;) {
    87   for (i = 0, j = 0; i<len;) {
    96     if (is_cygdrive_here(i, in, len)) {
    88     if (is_prefix_here(i, in, len, "/cygdrive/")) {
    97       out[j++] = in[i+10];
    89       out[j++] = in[i+10];
    98       out[j++] = ':';
    90       out[j++] = ':';
    99       i+=11;
    91       i+=11;
   100     } else {
    92     } else {
   101       out[j] = in[i];
    93       out[j] = in[i];
   194   }
   186   }
   195 
   187 
   196   return str;
   188   return str;
   197 }
   189 }
   198 
   190 
       
   191 /*
       
   192  * Replace /mnt/_/ with _:/
       
   193  * Works in place since drive letter is always
       
   194  * shorter than /mnt/
       
   195  */
       
   196 char *replace_cygdrive_wsl(char const *in)
       
   197 {
       
   198   size_t len = strlen(in);
       
   199   char *out = (char*) malloc(len+1);
       
   200   int i,j;
       
   201 
       
   202   if (len < 7) {
       
   203     memmove(out, in, len + 1);
       
   204     return out;
       
   205   }
       
   206 
       
   207   for (i = 0, j = 0; i<len;) {
       
   208     if (is_prefix_here(i, in, len, "/mnt/")) {
       
   209       out[j++] = in[i+5];
       
   210       out[j++] = ':';
       
   211       i+=6;
       
   212     } else {
       
   213       out[j] = in[i];
       
   214       i++;
       
   215       j++;
       
   216     }
       
   217   }
       
   218   out[j] = '\0';
       
   219   return out;
       
   220 }
       
   221 
   199 char*(*replace_cygdrive)(char const *in) = NULL;
   222 char*(*replace_cygdrive)(char const *in) = NULL;
       
   223 bool debug_fixpath = false;
   200 
   224 
   201 char *files_to_delete[1024];
   225 char *files_to_delete[1024];
   202 int num_files_to_delete = 0;
   226 int num_files_to_delete = 0;
   203 
   227 
   204 char *fix_at_file(char const *in)
   228 char *fix_at_file(char const *in)
   248   buffer = (char*) malloc(buflen);
   272   buffer = (char*) malloc(buflen);
   249   while ((blocklen = fread(block, 1, sizeof(block), atin)) > 0) {
   273   while ((blocklen = fread(block, 1, sizeof(block), atin)) > 0) {
   250     append(&buffer, &buflen, &used, block, blocklen);
   274     append(&buffer, &buflen, &used, block, blocklen);
   251   }
   275   }
   252   buffer[used] = 0;
   276   buffer[used] = 0;
   253   if (getenv("DEBUG_FIXPATH") != NULL) {
   277   if (debug_fixpath) {
   254     fprintf(stderr, "fixpath input from @-file %s: %s\n", &in[1], buffer);
   278     fprintf(stderr, "fixpath input from @-file %s: %s\n", &in[1], buffer);
   255   }
   279   }
   256   fixed = replace_cygdrive(buffer);
   280   fixed = replace_cygdrive(buffer);
   257   if (getenv("DEBUG_FIXPATH") != NULL) {
   281   if (debug_fixpath) {
   258     fprintf(stderr, "fixpath converted to @-file %s is: %s\n", name, fixed);
   282     fprintf(stderr, "fixpath converted to @-file %s is: %s\n", name, fixed);
   259   }
   283   }
   260   fwrite(fixed, strlen(fixed), 1, atout);
   284   fwrite(fixed, strlen(fixed), 1, atout);
   261   fclose(atin);
   285   fclose(atin);
   262   fclose(atout);
   286   fclose(atout);
   360     int i, cmd;
   384     int i, cmd;
   361     DWORD exitCode = 0;
   385     DWORD exitCode = 0;
   362     DWORD processFlags = 0;
   386     DWORD processFlags = 0;
   363     BOOL processInheritHandles = TRUE;
   387     BOOL processInheritHandles = TRUE;
   364     BOOL waitForChild = TRUE;
   388     BOOL waitForChild = TRUE;
   365 
   389     char* fixpathPath;
   366     if (argc<2 || argv[1][0] != '-' || (argv[1][1] != 'c' && argv[1][1] != 'm')) {
   390 
   367         fprintf(stderr, "Usage: fixpath -c|m<path@path@...> [--detach] /cygdrive/c/WINDOWS/notepad.exe [/cygdrive/c/x/test.txt|@/cygdrive/c/x/atfile]\n");
   391     debug_fixpath = (getenv("DEBUG_FIXPATH") != NULL);
       
   392 
       
   393     if (argc<2 || argv[1][0] != '-' || (argv[1][1] != 'c' && argv[1][1] != 'm' && argv[1][1] != 'w')) {
       
   394         fprintf(stderr, "Usage: fixpath -c|m|w<path@path@...> [--detach] /cygdrive/c/WINDOWS/notepad.exe [/cygdrive/c/x/test.txt|@/cygdrive/c/x/atfile]\n");
   368         exit(0);
   395         exit(0);
   369     }
   396     }
   370 
   397 
   371     if (getenv("DEBUG_FIXPATH") != NULL) {
   398     if (debug_fixpath) {
   372       char const * cmdline = GetCommandLine();
   399       char const * cmdline = GetCommandLine();
   373       fprintf(stderr, "fixpath input line >%s<\n", strstr(cmdline, argv[1]));
   400       fprintf(stderr, "fixpath input line >%s<\n", strstr(cmdline, argv[1]));
   374     }
   401     }
   375 
   402 
   376     if (argv[1][1] == 'c' && argv[1][2] == '\0') {
   403     if (argv[1][1] == 'c' && argv[1][2] == '\0') {
   377       if (getenv("DEBUG_FIXPATH") != NULL) {
   404       if (debug_fixpath) {
   378         fprintf(stderr, "fixpath using cygwin mode\n");
   405         fprintf(stderr, "fixpath using cygwin mode\n");
   379       }
   406       }
   380       replace_cygdrive = replace_cygdrive_cygwin;
   407       replace_cygdrive = replace_cygdrive_cygwin;
   381     } else if (argv[1][1] == 'm') {
   408     } else if (argv[1][1] == 'm') {
   382       if (getenv("DEBUG_FIXPATH") != NULL) {
   409       if (debug_fixpath) {
   383         fprintf(stderr, "fixpath using msys mode, with path list: %s\n", &argv[1][2]);
   410         fprintf(stderr, "fixpath using msys mode, with path list: %s\n", &argv[1][2]);
   384       }
   411       }
   385       setup_msys_path_list(argv[1]);
   412       setup_msys_path_list(argv[1]);
   386       replace_cygdrive = replace_cygdrive_msys;
   413       replace_cygdrive = replace_cygdrive_msys;
       
   414     } else if (argv[1][1] == 'w') {
       
   415       if (debug_fixpath) {
       
   416         fprintf(stderr, "fixpath using wsl mode, with path list: %s\n", &argv[1][2]);
       
   417       }
       
   418       replace_cygdrive = replace_cygdrive_wsl;
   387     } else {
   419     } else {
   388       fprintf(stderr, "fixpath Unknown mode: %s\n", argv[1]);
   420       fprintf(stderr, "fixpath Unknown mode: %s\n", argv[1]);
   389       exit(-1);
   421       exit(-1);
   390     }
   422     }
   391 
   423 
   392     if (argv[2][0] == '-') {
   424     if (argv[2][0] == '-') {
   393       if (strcmp(argv[2], "--detach") == 0) {
   425       if (strcmp(argv[2], "--detach") == 0) {
   394         if (getenv("DEBUG_FIXPATH") != NULL) {
   426         if (debug_fixpath) {
   395           fprintf(stderr, "fixpath in detached mode\n");
   427           fprintf(stderr, "fixpath in detached mode\n");
   396         }
   428         }
   397         processFlags |= DETACHED_PROCESS;
   429         processFlags |= DETACHED_PROCESS;
   398         processInheritHandles = FALSE;
   430         processInheritHandles = FALSE;
   399         waitForChild = FALSE;
   431         waitForChild = FALSE;
   415         char *val = replace_cygdrive(assignment + 1);
   447         char *val = replace_cygdrive(assignment + 1);
   416         memmove(var, argv[i], var_len);
   448         memmove(var, argv[i], var_len);
   417         var[var_len - 1] = '\0';
   449         var[var_len - 1] = '\0';
   418         strupr(var);
   450         strupr(var);
   419 
   451 
   420         if (getenv("DEBUG_FIXPATH") != NULL) {
   452         if (debug_fixpath) {
   421           fprintf(stderr, "fixpath setting var >%s< to >%s<\n", var, val);
   453           fprintf(stderr, "fixpath setting var >%s< to >%s<\n", var, val);
   422         }
   454         }
   423 
   455 
   424         rc = SetEnvironmentVariable(var, val);
   456         rc = SetEnvironmentVariable(var, val);
   425         if (!rc) {
   457         if (!rc) {
   478       memmove(current, argv[i], len);
   510       memmove(current, argv[i], len);
   479       current += len;
   511       current += len;
   480     }
   512     }
   481     *current = '\0';
   513     *current = '\0';
   482 
   514 
   483     if (getenv("DEBUG_FIXPATH") != NULL) {
   515     if (debug_fixpath) {
   484       fprintf(stderr, "fixpath converted line >%s<\n", line);
   516       fprintf(stderr, "fixpath converted line >%s<\n", line);
   485     }
   517     }
   486 
   518 
   487     if (cmd == argc) {
   519     if (cmd == argc) {
   488        if (getenv("DEBUG_FIXPATH") != NULL) {
   520       if (debug_fixpath) {
   489          fprintf(stderr, "fixpath no command provided!\n");
   521         fprintf(stderr, "fixpath no command provided!\n");
   490        }
   522       }
   491        exit(0);
   523       exit(0);
   492     }
   524     }
   493 
   525 
   494     ZeroMemory(&si, sizeof(si));
   526     ZeroMemory(&si, sizeof(si));
   495     si.cb=sizeof(si);
   527     si.cb=sizeof(si);
   496     ZeroMemory(&pi, sizeof(pi));
   528     ZeroMemory(&pi, sizeof(pi));
   497 
   529 
   498     fflush(stderr);
   530     fflush(stderr);
   499     fflush(stdout);
   531     fflush(stdout);
       
   532 
       
   533     fixpathPath = calloc(32767, sizeof(char));
       
   534     rc = GetEnvironmentVariable("FIXPATH_PATH", fixpathPath, 32767);
       
   535     if (rc) {
       
   536       if (debug_fixpath) {
       
   537         fprintf(stderr, "Setting Path to FIXPATH_PATH: %s\n", fixpathPath);
       
   538       }
       
   539       rc = SetEnvironmentVariable("Path", fixpathPath);
       
   540       if (!rc) {
       
   541         // Could not set Path for some reason.  Try to report why.
       
   542         const int msg_len = 80 + strlen(fixpathPath);
       
   543         char * msg = (char *)alloca(msg_len);
       
   544         _snprintf_s(msg, msg_len, _TRUNCATE, "Could not set environment variable [Path=%s]", fixpathPath);
       
   545         report_error(msg);
       
   546         exit(1);
       
   547       }
       
   548     }
   500 
   549 
   501     rc = CreateProcess(NULL,
   550     rc = CreateProcess(NULL,
   502                        line,
   551                        line,
   503                        0,
   552                        0,
   504                        0,
   553                        0,
   516 
   565 
   517     if (waitForChild == TRUE) {
   566     if (waitForChild == TRUE) {
   518       WaitForSingleObject(pi.hProcess, INFINITE);
   567       WaitForSingleObject(pi.hProcess, INFINITE);
   519       GetExitCodeProcess(pi.hProcess, &exitCode);
   568       GetExitCodeProcess(pi.hProcess, &exitCode);
   520 
   569 
   521       if (getenv("DEBUG_FIXPATH") != NULL) {
   570       if (debug_fixpath) {
   522         for (i=0; i<num_files_to_delete; ++i) {
   571         for (i=0; i<num_files_to_delete; ++i) {
   523           fprintf(stderr, "fixpath Not deleting temporary file %s\n",
   572           fprintf(stderr, "fixpath Not deleting temporary file %s\n",
   524                   files_to_delete[i]);
   573                   files_to_delete[i]);
   525         }
   574         }
   526       } else {
   575       } else {
   528           remove(files_to_delete[i]);
   577           remove(files_to_delete[i]);
   529         }
   578         }
   530       }
   579       }
   531 
   580 
   532       if (exitCode != 0) {
   581       if (exitCode != 0) {
   533         if (getenv("DEBUG_FIXPATH") != NULL) {
   582         if (debug_fixpath) {
   534           fprintf(stderr, "fixpath exit code %d\n",
   583           fprintf(stderr, "fixpath exit code %d\n",
   535                   exitCode);
   584                   exitCode);
   536         }
   585         }
   537       }
   586       }
   538     } else {
   587     } else {
   539       if (getenv("DEBUG_FIXPATH") != NULL) {
   588       if (debug_fixpath) {
   540         fprintf(stderr, "fixpath Not waiting for child process");
   589         fprintf(stderr, "fixpath Not waiting for child process");
   541       }
   590       }
   542     }
   591     }
   543 
   592 
   544     exit(exitCode);
   593     exit(exitCode);