228 effectivePath(void) 229 { 230 const char *s = getenv("PATH"); 231 return (s != NULL) ? s : defaultPath(); 232 } 233 234 static int 235 countOccurrences(const char *s, char c) 236 { 237 int count; 238 for (count = 0; *s != '\0'; s++) 239 count += (*s == c); 240 return count; 241 } 242 243 static const char * const * 244 splitPath(JNIEnv *env, const char *path) 245 { 246 const char *p, *q; 247 char **pathv; 248 int i; 249 int count = countOccurrences(path, ':') + 1; 250 251 pathv = NEW(char*, count+1); 252 pathv[count] = NULL; 253 for (p = path, i = 0; i < count; i++, p = q + 1) { 254 for (q = p; (*q != ':') && (*q != '\0'); q++) 255 ; 256 if (q == p) /* empty PATH component => "." */ 257 pathv[i] = "./"; 258 else { 259 int addSlash = ((*(q - 1)) != '/'); 260 pathv[i] = NEW(char, q - p + addSlash + 1); 261 memcpy(pathv[i], p, q - p); 262 if (addSlash) 263 pathv[i][q - p] = '/'; 264 pathv[i][q - p + addSlash] = '\0'; 265 } 266 } 267 return (const char * const *) pathv; 268 } 269 270 /** 271 * Cached value of JVM's effective PATH. 272 * (We don't support putenv("PATH=...") in native code) 273 */ 274 static const char *parentPath; 275 276 /** 277 * Split, canonicalized version of parentPath 278 */ 279 static const char * const *parentPathv; 280 469 while (*(p++)); 470 } 471 vector[count] = NULL; 472 } 473 474 static void 475 throwIOException(JNIEnv *env, int errnum, const char *defaultDetail) 476 { 477 static const char * const format = "error=%d, %s"; 478 const char *detail = defaultDetail; 479 char *errmsg; 480 jstring s; 481 482 if (errnum != 0) { 483 const char *s = strerror(errnum); 484 if (strcmp(s, "Unknown error") != 0) 485 detail = s; 486 } 487 /* ASCII Decimal representation uses 2.4 times as many bits as binary. */ 488 errmsg = NEW(char, strlen(format) + strlen(detail) + 3 * sizeof(errnum)); 489 sprintf(errmsg, format, errnum, detail); 490 s = JNU_NewStringPlatform(env, errmsg); 491 if (s != NULL) { 492 jobject x = JNU_NewObjectByName(env, "java/io/IOException", 493 "(Ljava/lang/String;)V", s); 494 if (x != NULL) 495 (*env)->Throw(env, x); 496 } 497 free(errmsg); 498 } 499 500 #ifdef DEBUG_PROCESS 501 /* Debugging process code is difficult; where to write debug output? */ 502 static void 503 debugPrint(char *format, ...) 504 { 505 FILE *tty = fopen("/dev/tty", "w"); 506 va_list ap; 507 va_start(ap, format); 508 vfprintf(tty, format, ap); | 228 effectivePath(void) 229 { 230 const char *s = getenv("PATH"); 231 return (s != NULL) ? s : defaultPath(); 232 } 233 234 static int 235 countOccurrences(const char *s, char c) 236 { 237 int count; 238 for (count = 0; *s != '\0'; s++) 239 count += (*s == c); 240 return count; 241 } 242 243 static const char * const * 244 splitPath(JNIEnv *env, const char *path) 245 { 246 const char *p, *q; 247 char **pathv; 248 const char *cwd = "./"; 249 size_t i; 250 size_t count = countOccurrences(path, ':') + 1; 251 252 pathv = NEW(char*, count+1); 253 if (pathv == NULL) 254 return NULL; 255 256 pathv[count] = NULL; 257 for (p = path, i = 0; i < count; i++, p = q + 1) { 258 for (q = p; (*q != ':') && (*q != '\0'); q++) 259 ; 260 261 if (q == p) { /* empty PATH component => "." */ 262 pathv[i] = NEW(char,sizeof(cwd)); 263 264 if (pathv[i] == NULL) { 265 266 while(i) 267 free(pathv[--i]); 268 269 free(pathv); 270 return NULL; 271 } 272 273 memcpy(pathv[i],cwd,sizeof(cwd)); 274 } 275 else { 276 int addSlash = ((*(q - 1)) != '/'); 277 pathv[i] = NEW(char, q - p + addSlash + 1); 278 279 if (pathv[i] == NULL) { 280 281 while(i) 282 free(pathv[--i]); 283 284 free(pathv); 285 return NULL; 286 } 287 288 memcpy(pathv[i], p, q - p); 289 if (addSlash) 290 pathv[i][q - p] = '/'; 291 pathv[i][q - p + addSlash] = '\0'; 292 } 293 } 294 return (const char * const *) pathv; 295 } 296 297 /** 298 * Cached value of JVM's effective PATH. 299 * (We don't support putenv("PATH=...") in native code) 300 */ 301 static const char *parentPath; 302 303 /** 304 * Split, canonicalized version of parentPath 305 */ 306 static const char * const *parentPathv; 307 496 while (*(p++)); 497 } 498 vector[count] = NULL; 499 } 500 501 static void 502 throwIOException(JNIEnv *env, int errnum, const char *defaultDetail) 503 { 504 static const char * const format = "error=%d, %s"; 505 const char *detail = defaultDetail; 506 char *errmsg; 507 jstring s; 508 509 if (errnum != 0) { 510 const char *s = strerror(errnum); 511 if (strcmp(s, "Unknown error") != 0) 512 detail = s; 513 } 514 /* ASCII Decimal representation uses 2.4 times as many bits as binary. */ 515 errmsg = NEW(char, strlen(format) + strlen(detail) + 3 * sizeof(errnum)); 516 if (errmsg == NULL) 517 return; 518 519 sprintf(errmsg, format, errnum, detail); 520 s = JNU_NewStringPlatform(env, errmsg); 521 if (s != NULL) { 522 jobject x = JNU_NewObjectByName(env, "java/io/IOException", 523 "(Ljava/lang/String;)V", s); 524 if (x != NULL) 525 (*env)->Throw(env, x); 526 } 527 free(errmsg); 528 } 529 530 #ifdef DEBUG_PROCESS 531 /* Debugging process code is difficult; where to write debug output? */ 532 static void 533 debugPrint(char *format, ...) 534 { 535 FILE *tty = fopen("/dev/tty", "w"); 536 va_list ap; 537 va_start(ap, format); 538 vfprintf(tty, format, ap); |