< prev index next >

make/src/native/fixpath.c

Print this page




   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 #include <Windows.h>

  27 #include <io.h>
  28 #include <stdio.h>
  29 #include <string.h>
  30 #include <malloc.h>
  31 
  32 void report_error(char const * msg)
  33 {
  34   LPVOID lpMsgBuf;
  35   DWORD dw = GetLastError();
  36 
  37   FormatMessage(
  38       FORMAT_MESSAGE_ALLOCATE_BUFFER |
  39       FORMAT_MESSAGE_FROM_SYSTEM |
  40       FORMAT_MESSAGE_IGNORE_INSERTS,
  41       NULL,
  42       dw,
  43       MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
  44       (LPTSTR) &lpMsgBuf,
  45       0,
  46       NULL);
  47 
  48   fprintf(stderr,
  49           "%s  Failed with error %d: %s\n",
  50           msg, dw, lpMsgBuf);
  51 
  52   LocalFree(lpMsgBuf);
  53 }
  54 
  55 /*
  56  * Test if pos points to /cygdrive/_/ where _ can
  57  * be any character.
  58  */
  59 int is_cygdrive_here(int pos, char const *in, int len)
  60 {
  61   // Length of /cygdrive/c/ is 12
  62   if (pos+12 > len) return 0;
  63   if (in[pos+11]=='/' &&
  64       in[pos+9]=='/' &&
  65       in[pos+8]=='e' &&
  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   }
  76   return 0;
  77 }
  78 
  79 /*
  80  * Replace /cygdrive/_/ with _:/
  81  * Works in place since drive letter is always
  82  * shorter than /cygdrive/
  83  */
  84 char *replace_cygdrive_cygwin(char const *in)
  85 {
  86   size_t len = strlen(in);
  87   char *out = (char*) malloc(len+1);
  88   int i,j;
  89 
  90   if (len < 12) {
  91     memmove(out, in, len + 1);
  92     return out;
  93   }
  94 
  95   for (i = 0, j = 0; i<len;) {
  96     if (is_cygdrive_here(i, in, len)) {
  97       out[j++] = in[i+10];
  98       out[j++] = ':';
  99       i+=11;
 100     } else {
 101       out[j] = in[i];
 102       i++;
 103       j++;
 104     }
 105   }
 106   out[j] = '\0';
 107   return out;
 108 }
 109 
 110 void append(char **b, size_t *bl, size_t *u, char *add, size_t addlen)
 111 {
 112   while ((addlen+*u+1) > *bl) {
 113     *bl *= 2;
 114     *b = (char*) realloc(*b, *bl);
 115   }
 116   memcpy(*b+*u, add, addlen);


 179   char* str;
 180   char* prefix;
 181   char* p;
 182 
 183   str = strdup(in);
 184 
 185   // For each prefix in the path list, search for it and replace /c/... with c:/...
 186   for (prefix = msys_path_list; prefix < msys_path_list_end && prefix != NULL; prefix += strlen(prefix)+1) {
 187     p=str;
 188     while ((p = strstr(p, prefix))) {
 189       char* drive_letter = p+1;
 190       *p = *drive_letter;
 191       *drive_letter = ':';
 192       p++;
 193     }
 194   }
 195 
 196   return str;
 197 }
 198 































 199 char*(*replace_cygdrive)(char const *in) = NULL;

 200 
 201 char *files_to_delete[1024];
 202 int num_files_to_delete = 0;
 203 
 204 char *fix_at_file(char const *in)
 205 {
 206   char *tmpdir;
 207   char name[2048];
 208   char *atname;
 209   char *buffer;
 210   size_t buflen=65536;
 211   size_t used=0;
 212   size_t len;
 213   int rc;
 214   FILE *atout;
 215   FILE *atin;
 216   char block[2048];
 217   size_t blocklen;
 218   char *fixed;
 219 


 233   }
 234   _snprintf(name, sizeof(name), "%s\\atfile_XXXXXX", tmpdir);
 235 
 236   rc = _mktemp_s(name, strlen(name)+1);
 237   if (rc) {
 238     fprintf(stderr, "Could not create temporary file name for at file!\n");
 239     exit(-1);
 240   }
 241 
 242   atout = fopen(name, "w");
 243   if (atout == NULL) {
 244     fprintf(stderr, "Could not open temporary file for writing! %s\n", name);
 245     exit(-1);
 246   }
 247 
 248   buffer = (char*) malloc(buflen);
 249   while ((blocklen = fread(block, 1, sizeof(block), atin)) > 0) {
 250     append(&buffer, &buflen, &used, block, blocklen);
 251   }
 252   buffer[used] = 0;
 253   if (getenv("DEBUG_FIXPATH") != NULL) {
 254     fprintf(stderr, "fixpath input from @-file %s: %s\n", &in[1], buffer);
 255   }
 256   fixed = replace_cygdrive(buffer);
 257   if (getenv("DEBUG_FIXPATH") != NULL) {
 258     fprintf(stderr, "fixpath converted to @-file %s is: %s\n", name, fixed);
 259   }
 260   fwrite(fixed, strlen(fixed), 1, atout);
 261   fclose(atin);
 262   fclose(atout);
 263   free(fixed);
 264   free(buffer);
 265   files_to_delete[num_files_to_delete] = (char*) malloc(strlen(name)+1);
 266   strcpy(files_to_delete[num_files_to_delete], name);
 267   num_files_to_delete++;
 268   atname = (char*) malloc(strlen(name)+2);
 269   atname[0] = '@';
 270   strcpy(atname+1, name);
 271   return atname;
 272 }
 273 
 274 // given an argument, convert it to the windows command line safe quoted version
 275 // using rules from:
 276 // http://blogs.msdn.com/b/twistylittlepassagesallalike/archive/2011/04/23/everyone-quotes-arguments-the-wrong-way.aspx
 277 // caller is responsible for freeing both input and output.


 346   *(current - 1) = '"';
 347   *current = '\0';
 348 
 349   return quoted;
 350 }
 351 
 352 int main(int argc, char const ** argv)
 353 {
 354     STARTUPINFO si;
 355     PROCESS_INFORMATION pi;
 356     unsigned short rc;
 357 
 358     char *line;
 359     char *current;
 360     int i, cmd;
 361     DWORD exitCode = 0;
 362     DWORD processFlags = 0;
 363     BOOL processInheritHandles = TRUE;
 364     BOOL waitForChild = TRUE;
 365 
 366     if (argc<2 || argv[1][0] != '-' || (argv[1][1] != 'c' && argv[1][1] != 'm')) {
 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");


 368         exit(0);
 369     }
 370 
 371     if (getenv("DEBUG_FIXPATH") != NULL) {
 372       char const * cmdline = GetCommandLine();
 373       fprintf(stderr, "fixpath input line >%s<\n", strstr(cmdline, argv[1]));
 374     }
 375 
 376     if (argv[1][1] == 'c' && argv[1][2] == '\0') {
 377       if (getenv("DEBUG_FIXPATH") != NULL) {
 378         fprintf(stderr, "fixpath using cygwin mode\n");
 379       }
 380       replace_cygdrive = replace_cygdrive_cygwin;
 381     } else if (argv[1][1] == 'm') {
 382       if (getenv("DEBUG_FIXPATH") != NULL) {
 383         fprintf(stderr, "fixpath using msys mode, with path list: %s\n", &argv[1][2]);
 384       }
 385       setup_msys_path_list(argv[1]);
 386       replace_cygdrive = replace_cygdrive_msys;





 387     } else {
 388       fprintf(stderr, "fixpath Unknown mode: %s\n", argv[1]);
 389       exit(-1);
 390     }
 391 
 392     if (argv[2][0] == '-') {
 393       if (strcmp(argv[2], "--detach") == 0) {
 394         if (getenv("DEBUG_FIXPATH") != NULL) {
 395           fprintf(stderr, "fixpath in detached mode\n");
 396         }
 397         processFlags |= DETACHED_PROCESS;
 398         processInheritHandles = FALSE;
 399         waitForChild = FALSE;
 400       } else {
 401         fprintf(stderr, "fixpath Unknown argument: %s\n", argv[2]);
 402         exit(-1);
 403       }
 404       i = 3;
 405     } else {
 406       i = 2;
 407     }
 408 
 409     // handle assignments
 410     while (i < argc) {
 411       char const * assignment = strchr(argv[i], '=');
 412       if (assignment != NULL && assignment != argv[i]) {
 413         size_t var_len = (size_t) (assignment - argv[i] + (ptrdiff_t) 1);
 414         char *var = (char *) calloc(var_len, sizeof(char));
 415         char *val = replace_cygdrive(assignment + 1);
 416         memmove(var, argv[i], var_len);
 417         var[var_len - 1] = '\0';
 418         strupr(var);
 419 
 420         if (getenv("DEBUG_FIXPATH") != NULL) {
 421           fprintf(stderr, "fixpath setting var >%s< to >%s<\n", var, val);
 422         }
 423 
 424         rc = SetEnvironmentVariable(var, val);
 425         if (!rc) {
 426           // Could not set var for some reason.  Try to report why.
 427           const int msg_len = 80 + var_len + strlen(val);
 428           char * msg = (char *) alloca(msg_len);
 429           _snprintf_s(msg, msg_len, _TRUNCATE, "Could not set environment variable [%s=%s]", var, val);
 430           report_error(msg);
 431           exit(1);
 432         }
 433         free(var);
 434         free(val);
 435       } else {
 436         // no more assignments;
 437         break;
 438       }
 439       i++;
 440     }


 463     for (i = cmd; i < argc; i++) {
 464       line += (ptrdiff_t) strlen(argv[i]);
 465     }
 466     // spaces and null
 467     line += (ptrdiff_t) (argc - cmd + 1);
 468     // allocate
 469     line = (char*) calloc(line - (char*) NULL, sizeof(char));
 470 
 471     // copy in args.
 472     current = line;
 473     for (i = cmd; i < argc; i++) {
 474       ptrdiff_t len = strlen(argv[i]);
 475       if (i != cmd) {
 476         *current++ = ' ';
 477       }
 478       memmove(current, argv[i], len);
 479       current += len;
 480     }
 481     *current = '\0';
 482 
 483     if (getenv("DEBUG_FIXPATH") != NULL) {
 484       fprintf(stderr, "fixpath converted line >%s<\n", line);
 485     }
 486 
 487     if (cmd == argc) {
 488        if (getenv("DEBUG_FIXPATH") != NULL) {
 489          fprintf(stderr, "fixpath no command provided!\n");
 490        }
 491        exit(0);
 492     }
 493 
 494     ZeroMemory(&si, sizeof(si));
 495     si.cb=sizeof(si);
 496     ZeroMemory(&pi, sizeof(pi));
 497 
 498     fflush(stderr);
 499     fflush(stdout);
 500 
 501     rc = CreateProcess(NULL,
 502                        line,
 503                        0,
 504                        0,
 505                        processInheritHandles,
 506                        processFlags,
 507                        NULL,
 508                        NULL,
 509                        &si,
 510                        &pi);
 511     if (!rc) {
 512       // Could not start process for some reason.  Try to report why:
 513       report_error("Could not start process!");
 514       exit(126);
 515     }
 516 
 517     if (waitForChild == TRUE) {
 518       WaitForSingleObject(pi.hProcess, INFINITE);
 519       GetExitCodeProcess(pi.hProcess, &exitCode);
 520 
 521       if (getenv("DEBUG_FIXPATH") != NULL) {
 522         for (i=0; i<num_files_to_delete; ++i) {
 523           fprintf(stderr, "fixpath Not deleting temporary file %s\n",
 524                   files_to_delete[i]);
 525         }
 526       } else {
 527         for (i=0; i<num_files_to_delete; ++i) {
 528           remove(files_to_delete[i]);
 529         }
 530       }
 531 
 532       if (exitCode != 0) {
 533         if (getenv("DEBUG_FIXPATH") != NULL) {
 534           fprintf(stderr, "fixpath exit code %d\n",
 535                   exitCode);
 536         }
 537       }
 538     } else {
 539       if (getenv("DEBUG_FIXPATH") != NULL) {
 540         fprintf(stderr, "fixpath Not waiting for child process");
 541       }
 542     }
 543 
 544     exit(exitCode);
 545 }


   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 #include <Windows.h>
  27 #include <stdbool.h>
  28 #include <io.h>
  29 #include <stdio.h>
  30 #include <string.h>
  31 #include <malloc.h>
  32 
  33 void report_error(char const * msg)
  34 {
  35   LPVOID lpMsgBuf;
  36   DWORD dw = GetLastError();
  37 
  38   FormatMessage(
  39       FORMAT_MESSAGE_ALLOCATE_BUFFER |
  40       FORMAT_MESSAGE_FROM_SYSTEM |
  41       FORMAT_MESSAGE_IGNORE_INSERTS,
  42       NULL,
  43       dw,
  44       MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
  45       (LPTSTR) &lpMsgBuf,
  46       0,
  47       NULL);
  48 
  49   fprintf(stderr,
  50           "%s  Failed with error %d: %s\n",
  51           msg, dw, lpMsgBuf);
  52 
  53   LocalFree(lpMsgBuf);
  54 }
  55 
  56 /*
  57  * Test if pos points to /prefix/_/ where _ can
  58  * be any character.
  59  */
  60 int is_prefix_here(int pos, char const *in, int len, const char* prefix)
  61 {
  62   // Length of c/ is 2
  63   int prefix_size = strlen(prefix);
  64   if (pos+prefix_size+2 > len) return 0;
  65   if (in[pos+prefix_size+1]=='/') {
  66     return strncmp(in + pos, prefix, prefix_size) == 0;









  67   }
  68   return 0;
  69 }
  70 
  71 /*
  72  * Replace /cygdrive/_/ with _:/
  73  * Works in place since drive letter is always
  74  * shorter than /cygdrive/
  75  */
  76 char *replace_cygdrive_cygwin(char const *in)
  77 {
  78   size_t len = strlen(in);
  79   char *out = (char*) malloc(len+1);
  80   int i,j;
  81 
  82   if (len < 12) {
  83     memmove(out, in, len + 1);
  84     return out;
  85   }
  86 
  87   for (i = 0, j = 0; i<len;) {
  88     if (is_prefix_here(i, in, len, "/cygdrive/")) {
  89       out[j++] = in[i+10];
  90       out[j++] = ':';
  91       i+=11;
  92     } else {
  93       out[j] = in[i];
  94       i++;
  95       j++;
  96     }
  97   }
  98   out[j] = '\0';
  99   return out;
 100 }
 101 
 102 void append(char **b, size_t *bl, size_t *u, char *add, size_t addlen)
 103 {
 104   while ((addlen+*u+1) > *bl) {
 105     *bl *= 2;
 106     *b = (char*) realloc(*b, *bl);
 107   }
 108   memcpy(*b+*u, add, addlen);


 171   char* str;
 172   char* prefix;
 173   char* p;
 174 
 175   str = strdup(in);
 176 
 177   // For each prefix in the path list, search for it and replace /c/... with c:/...
 178   for (prefix = msys_path_list; prefix < msys_path_list_end && prefix != NULL; prefix += strlen(prefix)+1) {
 179     p=str;
 180     while ((p = strstr(p, prefix))) {
 181       char* drive_letter = p+1;
 182       *p = *drive_letter;
 183       *drive_letter = ':';
 184       p++;
 185     }
 186   }
 187 
 188   return str;
 189 }
 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 
 222 char*(*replace_cygdrive)(char const *in) = NULL;
 223 bool debug_fixpath = false;
 224 
 225 char *files_to_delete[1024];
 226 int num_files_to_delete = 0;
 227 
 228 char *fix_at_file(char const *in)
 229 {
 230   char *tmpdir;
 231   char name[2048];
 232   char *atname;
 233   char *buffer;
 234   size_t buflen=65536;
 235   size_t used=0;
 236   size_t len;
 237   int rc;
 238   FILE *atout;
 239   FILE *atin;
 240   char block[2048];
 241   size_t blocklen;
 242   char *fixed;
 243 


 257   }
 258   _snprintf(name, sizeof(name), "%s\\atfile_XXXXXX", tmpdir);
 259 
 260   rc = _mktemp_s(name, strlen(name)+1);
 261   if (rc) {
 262     fprintf(stderr, "Could not create temporary file name for at file!\n");
 263     exit(-1);
 264   }
 265 
 266   atout = fopen(name, "w");
 267   if (atout == NULL) {
 268     fprintf(stderr, "Could not open temporary file for writing! %s\n", name);
 269     exit(-1);
 270   }
 271 
 272   buffer = (char*) malloc(buflen);
 273   while ((blocklen = fread(block, 1, sizeof(block), atin)) > 0) {
 274     append(&buffer, &buflen, &used, block, blocklen);
 275   }
 276   buffer[used] = 0;
 277   if (debug_fixpath) {
 278     fprintf(stderr, "fixpath input from @-file %s: %s\n", &in[1], buffer);
 279   }
 280   fixed = replace_cygdrive(buffer);
 281   if (debug_fixpath) {
 282     fprintf(stderr, "fixpath converted to @-file %s is: %s\n", name, fixed);
 283   }
 284   fwrite(fixed, strlen(fixed), 1, atout);
 285   fclose(atin);
 286   fclose(atout);
 287   free(fixed);
 288   free(buffer);
 289   files_to_delete[num_files_to_delete] = (char*) malloc(strlen(name)+1);
 290   strcpy(files_to_delete[num_files_to_delete], name);
 291   num_files_to_delete++;
 292   atname = (char*) malloc(strlen(name)+2);
 293   atname[0] = '@';
 294   strcpy(atname+1, name);
 295   return atname;
 296 }
 297 
 298 // given an argument, convert it to the windows command line safe quoted version
 299 // using rules from:
 300 // http://blogs.msdn.com/b/twistylittlepassagesallalike/archive/2011/04/23/everyone-quotes-arguments-the-wrong-way.aspx
 301 // caller is responsible for freeing both input and output.


 370   *(current - 1) = '"';
 371   *current = '\0';
 372 
 373   return quoted;
 374 }
 375 
 376 int main(int argc, char const ** argv)
 377 {
 378     STARTUPINFO si;
 379     PROCESS_INFORMATION pi;
 380     unsigned short rc;
 381 
 382     char *line;
 383     char *current;
 384     int i, cmd;
 385     DWORD exitCode = 0;
 386     DWORD processFlags = 0;
 387     BOOL processInheritHandles = TRUE;
 388     BOOL waitForChild = TRUE;
 389 
 390         debug_fixpath = (getenv("DEBUG_FIXPATH") != NULL);
 391 
 392     if (argc<2 || argv[1][0] != '-' || (argv[1][1] != 'c' && argv[1][1] != 'm' && argv[1][1] != 'w')) {
 393         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");
 394         exit(0);
 395     }
 396 
 397     if (debug_fixpath) {
 398       char const * cmdline = GetCommandLine();
 399       fprintf(stderr, "fixpath input line >%s<\n", strstr(cmdline, argv[1]));
 400     }
 401 
 402     if (argv[1][1] == 'c' && argv[1][2] == '\0') {
 403       if (debug_fixpath) {
 404         fprintf(stderr, "fixpath using cygwin mode\n");
 405       }
 406       replace_cygdrive = replace_cygdrive_cygwin;
 407     } else if (argv[1][1] == 'm') {
 408       if (debug_fixpath) {
 409         fprintf(stderr, "fixpath using msys mode, with path list: %s\n", &argv[1][2]);
 410       }
 411       setup_msys_path_list(argv[1]);
 412       replace_cygdrive = replace_cygdrive_msys;
 413         } else if (argv[1][1] == 'w') {
 414       if (debug_fixpath) {
 415         fprintf(stderr, "fixpath using wsl mode, with path list: %s\n", &argv[1][2]);
 416       }
 417       replace_cygdrive = replace_cygdrive_wsl;
 418     } else {
 419       fprintf(stderr, "fixpath Unknown mode: %s\n", argv[1]);
 420       exit(-1);
 421     }
 422 
 423     if (argv[2][0] == '-') {
 424       if (strcmp(argv[2], "--detach") == 0) {
 425         if (debug_fixpath) {
 426           fprintf(stderr, "fixpath in detached mode\n");
 427         }
 428         processFlags |= DETACHED_PROCESS;
 429         processInheritHandles = FALSE;
 430         waitForChild = FALSE;
 431       } else {
 432         fprintf(stderr, "fixpath Unknown argument: %s\n", argv[2]);
 433         exit(-1);
 434       }
 435       i = 3;
 436     } else {
 437       i = 2;
 438     }
 439 
 440     // handle assignments
 441     while (i < argc) {
 442       char const * assignment = strchr(argv[i], '=');
 443       if (assignment != NULL && assignment != argv[i]) {
 444         size_t var_len = (size_t) (assignment - argv[i] + (ptrdiff_t) 1);
 445         char *var = (char *) calloc(var_len, sizeof(char));
 446         char *val = replace_cygdrive(assignment + 1);
 447         memmove(var, argv[i], var_len);
 448         var[var_len - 1] = '\0';
 449         strupr(var);
 450 
 451         if (debug_fixpath) {
 452           fprintf(stderr, "fixpath setting var >%s< to >%s<\n", var, val);
 453         }
 454 
 455         rc = SetEnvironmentVariable(var, val);
 456         if (!rc) {
 457           // Could not set var for some reason.  Try to report why.
 458           const int msg_len = 80 + var_len + strlen(val);
 459           char * msg = (char *) alloca(msg_len);
 460           _snprintf_s(msg, msg_len, _TRUNCATE, "Could not set environment variable [%s=%s]", var, val);
 461           report_error(msg);
 462           exit(1);
 463         }
 464         free(var);
 465         free(val);
 466       } else {
 467         // no more assignments;
 468         break;
 469       }
 470       i++;
 471     }


 494     for (i = cmd; i < argc; i++) {
 495       line += (ptrdiff_t) strlen(argv[i]);
 496     }
 497     // spaces and null
 498     line += (ptrdiff_t) (argc - cmd + 1);
 499     // allocate
 500     line = (char*) calloc(line - (char*) NULL, sizeof(char));
 501 
 502     // copy in args.
 503     current = line;
 504     for (i = cmd; i < argc; i++) {
 505       ptrdiff_t len = strlen(argv[i]);
 506       if (i != cmd) {
 507         *current++ = ' ';
 508       }
 509       memmove(current, argv[i], len);
 510       current += len;
 511     }
 512     *current = '\0';
 513 
 514     if (debug_fixpath) {
 515       fprintf(stderr, "fixpath converted line >%s<\n", line);
 516     }
 517 
 518     if (cmd == argc) {
 519        if (debug_fixpath) {
 520          fprintf(stderr, "fixpath no command provided!\n");
 521        }
 522        exit(0);
 523     }
 524 
 525     ZeroMemory(&si, sizeof(si));
 526     si.cb=sizeof(si);
 527     ZeroMemory(&pi, sizeof(pi));
 528 
 529     fflush(stderr);
 530     fflush(stdout);
 531 
 532     rc = CreateProcess(NULL,
 533                        line,
 534                        0,
 535                        0,
 536                        processInheritHandles,
 537                        processFlags,
 538                        NULL,
 539                        NULL,
 540                        &si,
 541                        &pi);
 542     if (!rc) {
 543       // Could not start process for some reason.  Try to report why:
 544       report_error("Could not start process!");
 545       exit(126);
 546     }
 547 
 548     if (waitForChild == TRUE) {
 549       WaitForSingleObject(pi.hProcess, INFINITE);
 550       GetExitCodeProcess(pi.hProcess, &exitCode);
 551 
 552       if (debug_fixpath) {
 553         for (i=0; i<num_files_to_delete; ++i) {
 554           fprintf(stderr, "fixpath Not deleting temporary file %s\n",
 555                   files_to_delete[i]);
 556         }
 557       } else {
 558         for (i=0; i<num_files_to_delete; ++i) {
 559           remove(files_to_delete[i]);
 560         }
 561       }
 562 
 563       if (exitCode != 0) {
 564         if (debug_fixpath) {
 565           fprintf(stderr, "fixpath exit code %d\n",
 566                   exitCode);
 567         }
 568       }
 569     } else {
 570       if (debug_fixpath) {
 571         fprintf(stderr, "fixpath Not waiting for child process");
 572       }
 573     }
 574 
 575     exit(exitCode);
 576 }
< prev index next >