common/src/fixpath.c

Fri, 26 Oct 2012 14:29:57 -0700

author
ohair
date
Fri, 26 Oct 2012 14:29:57 -0700
changeset 494
e64f2cb57d05
child 564
befbad2e4d87
permissions
-rw-r--r--

8000992: Update new build-infra makefiles
Summary: Build-infra project integration. Multiple authors on this work: erikj and ihse primarily, also changes from ohair, tbell, and dholmes. Special credit to ohstrom for his smartjavac work.
Reviewed-by: erikj, ihse, dholmes, tbell

ohair@494 1 /*
ohair@494 2 * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
ohair@494 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
ohair@494 4 *
ohair@494 5 * This code is free software; you can redistribute it and/or modify it
ohair@494 6 * under the terms of the GNU General Public License version 2 only, as
ohair@494 7 * published by the Free Software Foundation. Oracle designates this
ohair@494 8 * particular file as subject to the "Classpath" exception as provided
ohair@494 9 * by Oracle in the LICENSE file that accompanied this code.
ohair@494 10 *
ohair@494 11 * This code is distributed in the hope that it will be useful, but WITHOUT
ohair@494 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
ohair@494 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
ohair@494 14 * version 2 for more details (a copy is included in the LICENSE file that
ohair@494 15 * accompanied this code).
ohair@494 16 *
ohair@494 17 * You should have received a copy of the GNU General Public License version
ohair@494 18 * 2 along with this work; if not, write to the Free Software Foundation,
ohair@494 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
ohair@494 20 *
ohair@494 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
ohair@494 22 * or visit www.oracle.com if you need additional information or have any
ohair@494 23 * questions.
ohair@494 24 */
ohair@494 25
ohair@494 26 #include <Windows.h>
ohair@494 27 #include <io.h>
ohair@494 28 #include <stdio.h>
ohair@494 29 #include <string.h>
ohair@494 30 #include <malloc.h>
ohair@494 31
ohair@494 32 /*
ohair@494 33 * Test if pos points to /cygdrive/_/ where _ can
ohair@494 34 * be any character.
ohair@494 35 */
ohair@494 36 int is_cygdrive_here(int pos, char *in, int len)
ohair@494 37 {
ohair@494 38 // Length of /cygdrive/c/ is 12
ohair@494 39 if (pos+12 > len) return 0;
ohair@494 40 if (in[pos+11]=='/' &&
ohair@494 41 in[pos+9]=='/' &&
ohair@494 42 in[pos+8]=='e' &&
ohair@494 43 in[pos+7]=='v' &&
ohair@494 44 in[pos+6]=='i' &&
ohair@494 45 in[pos+5]=='r' &&
ohair@494 46 in[pos+4]=='d' &&
ohair@494 47 in[pos+3]=='g' &&
ohair@494 48 in[pos+2]=='y' &&
ohair@494 49 in[pos+1]=='c' &&
ohair@494 50 in[pos+0]=='/') {
ohair@494 51 return 1;
ohair@494 52 }
ohair@494 53 return 0;
ohair@494 54 }
ohair@494 55
ohair@494 56 /*
ohair@494 57 * Replace /cygdrive/_/ with _:/
ohair@494 58 * Works in place since drive letter is always
ohair@494 59 * shorter than /cygdrive/
ohair@494 60 */
ohair@494 61 char *replace_cygdrive_cygwin(char *in)
ohair@494 62 {
ohair@494 63 int len = strlen(in);
ohair@494 64 char *out = malloc(len+1);
ohair@494 65 int i,j;
ohair@494 66
ohair@494 67 if (len < 12) {
ohair@494 68 strcpy(out, in);
ohair@494 69 return out;
ohair@494 70 }
ohair@494 71 for (i = 0, j = 0; i<len;) {
ohair@494 72 if (is_cygdrive_here(i, in, len)) {
ohair@494 73 out[j++] = in[i+10];
ohair@494 74 out[j++] = ':';
ohair@494 75 i+=11;
ohair@494 76 } else {
ohair@494 77 out[j] = in[i];
ohair@494 78 i++;
ohair@494 79 j++;
ohair@494 80 }
ohair@494 81 }
ohair@494 82 out[j] = 0;
ohair@494 83 return out;
ohair@494 84 }
ohair@494 85
ohair@494 86 void append(char **b, size_t *bl, size_t *u, char *add, size_t addlen)
ohair@494 87 {
ohair@494 88 while ( (addlen+*u+1) > *bl) {
ohair@494 89 *bl *= 2;
ohair@494 90 *b = realloc(*b, *bl);
ohair@494 91 }
ohair@494 92 memcpy(*b+*u, add, addlen);
ohair@494 93 *u += addlen;
ohair@494 94 }
ohair@494 95
ohair@494 96 /*
ohair@494 97 * Creates a new string from in where the first occurance of sub is
ohair@494 98 * replaced by rep.
ohair@494 99 */
ohair@494 100 char *replace_substring(char *in, char *sub, char *rep)
ohair@494 101 {
ohair@494 102 int in_len = strlen(in);
ohair@494 103 int sub_len = strlen(sub);
ohair@494 104 int rep_len = strlen(rep);
ohair@494 105 char *out = malloc(in_len - sub_len + rep_len + 1);
ohair@494 106 char *p;
ohair@494 107
ohair@494 108 if (!(p = strstr(in, sub))) {
ohair@494 109 // If sub isn't a substring of in, just return in.
ohair@494 110 return in;
ohair@494 111 }
ohair@494 112
ohair@494 113 // Copy characters from beginning of in to start of sub.
ohair@494 114 strncpy(out, in, p - in);
ohair@494 115 out[p - in] = '\0';
ohair@494 116
ohair@494 117 sprintf(out + (p - in), "%s%s", rep, p + sub_len);
ohair@494 118
ohair@494 119 return out;
ohair@494 120 }
ohair@494 121
ohair@494 122 char* msys_path_list; // @-separated list of paths prefix to look for
ohair@494 123 char* msys_path_list_end; // Points to last \0 in msys_path_list.
ohair@494 124
ohair@494 125 void setup_msys_path_list(char* argument)
ohair@494 126 {
ohair@494 127 char* p;
ohair@494 128 char* drive_letter_pos;
ohair@494 129
ohair@494 130 msys_path_list = strdup(&argument[2]);
ohair@494 131 msys_path_list_end = &msys_path_list[strlen(msys_path_list)];
ohair@494 132
ohair@494 133 // Convert all at-sign (@) in path list to \0.
ohair@494 134 // @ was chosen as separator to minimize risk of other tools messing around with it
ohair@494 135 p = msys_path_list;
ohair@494 136 do {
ohair@494 137 if (p[1] == ':') {
ohair@494 138 // msys has mangled our path list, restore it from c:/... to /c/...
ohair@494 139 drive_letter_pos = p+1;
ohair@494 140 *drive_letter_pos = *p;
ohair@494 141 *p = '/';
ohair@494 142 }
ohair@494 143
ohair@494 144 // Look for an @ in the list
ohair@494 145 p = strchr(p, '@');
ohair@494 146 if (p != NULL) {
ohair@494 147 *p = '\0';
ohair@494 148 p++;
ohair@494 149 }
ohair@494 150 } while (p != NULL);
ohair@494 151 }
ohair@494 152
ohair@494 153 char *replace_cygdrive_msys(char *in)
ohair@494 154 {
ohair@494 155 char* str;
ohair@494 156 char* prefix;
ohair@494 157 char* p;
ohair@494 158
ohair@494 159 str = strdup(in);
ohair@494 160
ohair@494 161 // For each prefix in the path list, search for it and replace /c/... with c:/...
ohair@494 162 for (prefix = msys_path_list; prefix < msys_path_list_end && prefix != NULL; prefix += strlen(prefix)+1) {
ohair@494 163 p=str;
ohair@494 164 while ((p = strstr(p, prefix))) {
ohair@494 165 char* drive_letter = p+1;
ohair@494 166 *p = *drive_letter;
ohair@494 167 *drive_letter = ':';
ohair@494 168 p++;
ohair@494 169 }
ohair@494 170 }
ohair@494 171
ohair@494 172 return str;
ohair@494 173 }
ohair@494 174
ohair@494 175 char*(*replace_cygdrive)(char *in) = NULL;
ohair@494 176
ohair@494 177 char *files_to_delete[1024];
ohair@494 178 int num_files_to_delete = 0;
ohair@494 179
ohair@494 180 char *fix_at_file(char *in)
ohair@494 181 {
ohair@494 182 char *tmpdir;
ohair@494 183 char name[2048];
ohair@494 184 char *atname;
ohair@494 185 char *buffer;
ohair@494 186 size_t buflen=65536;
ohair@494 187 size_t used=0;
ohair@494 188 size_t len;
ohair@494 189 int rc;
ohair@494 190 FILE *atout;
ohair@494 191 FILE *atin;
ohair@494 192 char block[2048];
ohair@494 193 size_t blocklen;
ohair@494 194 char *fixed;
ohair@494 195
ohair@494 196 atin = fopen(in+1, "r");
ohair@494 197 if (atin == NULL) {
ohair@494 198 fprintf(stderr, "Could not read at file %s\n", in+1);
ohair@494 199 exit(-1);
ohair@494 200 }
ohair@494 201
ohair@494 202 tmpdir = getenv("TMP");
ohair@494 203 if (tmpdir == NULL) {
ohair@494 204 tmpdir = "c:/cygwin/tmp";
ohair@494 205 }
ohair@494 206 _snprintf(name, sizeof(name), "%s\\atfile_XXXXXX", tmpdir);
ohair@494 207
ohair@494 208 rc = _mktemp_s(name, strlen(name)+1);
ohair@494 209 if (rc) {
ohair@494 210 fprintf(stderr, "Could not create temporary file name for at file!\n");
ohair@494 211 exit(-1);
ohair@494 212 }
ohair@494 213
ohair@494 214 atout = fopen(name, "w");
ohair@494 215 if (atout == NULL) {
ohair@494 216 fprintf(stderr, "Could not open temporary file for writing! %s\n", name);
ohair@494 217 exit(-1);
ohair@494 218 }
ohair@494 219
ohair@494 220 buffer = malloc(buflen);
ohair@494 221 while((blocklen = fread(block,1,sizeof(block),atin)) > 0) {
ohair@494 222 append(&buffer, &buflen, &used, block, blocklen);
ohair@494 223 }
ohair@494 224 buffer[used] = 0;
ohair@494 225 if (getenv("DEBUG_FIXPATH") != NULL) {
ohair@494 226 fprintf(stderr, "fixpath input from @-file %s: %s\n", &in[1], buffer);
ohair@494 227 }
ohair@494 228 fixed = replace_cygdrive(buffer);
ohair@494 229 if (getenv("DEBUG_FIXPATH") != NULL) {
ohair@494 230 fprintf(stderr, "fixpath converted to @-file %s is: %s\n", name, fixed);
ohair@494 231 }
ohair@494 232 fwrite(fixed, strlen(fixed), 1, atout);
ohair@494 233 fclose(atin);
ohair@494 234 fclose(atout);
ohair@494 235 free(fixed);
ohair@494 236 free(buffer);
ohair@494 237 files_to_delete[num_files_to_delete] = malloc(strlen(name)+1);
ohair@494 238 strcpy(files_to_delete[num_files_to_delete], name);
ohair@494 239 num_files_to_delete++;
ohair@494 240 atname = malloc(strlen(name)+2);
ohair@494 241 atname[0] = '@';
ohair@494 242 strcpy(atname+1, name);
ohair@494 243 return atname;
ohair@494 244 }
ohair@494 245
ohair@494 246 int main(int argc, char **argv)
ohair@494 247 {
ohair@494 248 STARTUPINFO si;
ohair@494 249 PROCESS_INFORMATION pi;
ohair@494 250 unsigned short rc;
ohair@494 251
ohair@494 252 char *new_at_file;
ohair@494 253 char *old_at_file;
ohair@494 254 char *line;
ohair@494 255 int i;
ohair@494 256 DWORD exitCode;
ohair@494 257
ohair@494 258 if (argc<3 || argv[1][0] != '-' || (argv[1][1] != 'c' && argv[1][1] != 'm')) {
ohair@494 259 fprintf(stderr, "Usage: fixpath -c|m<path@path@...> /cygdrive/c/WINDOWS/notepad.exe /cygdrive/c/x/test.txt");
ohair@494 260 exit(0);
ohair@494 261 }
ohair@494 262
ohair@494 263 if (getenv("DEBUG_FIXPATH") != NULL) {
ohair@494 264 fprintf(stderr, "fixpath input line >%s<\n", strstr(GetCommandLine(), argv[1]));
ohair@494 265 }
ohair@494 266
ohair@494 267 if (argv[1][1] == 'c' && argv[1][2] == '\0') {
ohair@494 268 if (getenv("DEBUG_FIXPATH") != NULL) {
ohair@494 269 fprintf(stderr, "using cygwin mode\n");
ohair@494 270 }
ohair@494 271 replace_cygdrive = replace_cygdrive_cygwin;
ohair@494 272 } else if (argv[1][1] == 'm') {
ohair@494 273 if (getenv("DEBUG_FIXPATH") != NULL) {
ohair@494 274 fprintf(stderr, "using msys mode, with path list: %s\n", &argv[1][2]);
ohair@494 275 }
ohair@494 276 setup_msys_path_list(argv[1]);
ohair@494 277 replace_cygdrive = replace_cygdrive_msys;
ohair@494 278 } else {
ohair@494 279 fprintf(stderr, "Unknown mode: %s\n", argv[1]);
ohair@494 280 exit(-1);
ohair@494 281 }
ohair@494 282 line = replace_cygdrive(strstr(GetCommandLine(), argv[2]));
ohair@494 283
ohair@494 284 for (i=1; i<argc; ++i) {
ohair@494 285 if (argv[i][0] == '@') {
ohair@494 286 // Found at-file! Fix it!
ohair@494 287 old_at_file = replace_cygdrive(argv[i]);
ohair@494 288 new_at_file = fix_at_file(old_at_file);
ohair@494 289 line = replace_substring(line, old_at_file, new_at_file);
ohair@494 290 }
ohair@494 291 }
ohair@494 292
ohair@494 293 if (getenv("DEBUG_FIXPATH") != NULL) {
ohair@494 294 fprintf(stderr, "fixpath converted line >%s<\n", line);
ohair@494 295 }
ohair@494 296
ohair@494 297 ZeroMemory(&si,sizeof(si));
ohair@494 298 si.cb=sizeof(si);
ohair@494 299 ZeroMemory(&pi,sizeof(pi));
ohair@494 300
ohair@494 301 rc = CreateProcess(NULL,
ohair@494 302 line,
ohair@494 303 0,
ohair@494 304 0,
ohair@494 305 TRUE,
ohair@494 306 0,
ohair@494 307 0,
ohair@494 308 0,
ohair@494 309 &si,
ohair@494 310 &pi);
ohair@494 311 if(!rc)
ohair@494 312 {
ohair@494 313 //Could not start process;
ohair@494 314 fprintf(stderr, "Could not start process!\n");
ohair@494 315 exit(-1);
ohair@494 316 }
ohair@494 317
ohair@494 318 WaitForSingleObject(pi.hProcess,INFINITE);
ohair@494 319 GetExitCodeProcess(pi.hProcess,&exitCode);
ohair@494 320
ohair@494 321 if (getenv("DEBUG_FIXPATH") != NULL) {
ohair@494 322 for (i=0; i<num_files_to_delete; ++i) {
ohair@494 323 fprintf(stderr, "Not deleting temporary fixpath file %s\n",
ohair@494 324 files_to_delete[i]);
ohair@494 325 }
ohair@494 326 }
ohair@494 327 else {
ohair@494 328 for (i=0; i<num_files_to_delete; ++i) {
ohair@494 329 remove(files_to_delete[i]);
ohair@494 330 }
ohair@494 331 }
ohair@494 332
ohair@494 333 exit(exitCode);
ohair@494 334 }

mercurial