Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(461)

Side by Side Diff: src/d8-posix.cc

Issue 83333002: Remove usage of deprecated APIs from d8 (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/d8-debug.cc ('k') | src/d8-windows.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2009 the V8 project authors. All rights reserved. 1 // Copyright 2009 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after
181 181
182 182
183 // A utility class that takes the array of command arguments and puts then in an 183 // A utility class that takes the array of command arguments and puts then in an
184 // array of new[]ed UTF-8 C strings. Deallocates them again when it goes out of 184 // array of new[]ed UTF-8 C strings. Deallocates them again when it goes out of
185 // scope. 185 // scope.
186 class ExecArgs { 186 class ExecArgs {
187 public: 187 public:
188 ExecArgs() { 188 ExecArgs() {
189 exec_args_[0] = NULL; 189 exec_args_[0] = NULL;
190 } 190 }
191 bool Init(Handle<Value> arg0, Handle<Array> command_args) { 191 bool Init(Isolate* isolate, Handle<Value> arg0, Handle<Array> command_args) {
192 String::Utf8Value prog(arg0); 192 String::Utf8Value prog(arg0);
193 if (*prog == NULL) { 193 if (*prog == NULL) {
194 const char* message = 194 const char* message =
195 "os.system(): String conversion of program name failed"; 195 "os.system(): String conversion of program name failed";
196 ThrowException(String::New(message)); 196 isolate->ThrowException(String::NewFromUtf8(isolate, message));
197 return false; 197 return false;
198 } 198 }
199 int len = prog.length() + 3; 199 int len = prog.length() + 3;
200 char* c_arg = new char[len]; 200 char* c_arg = new char[len];
201 snprintf(c_arg, len, "%s", *prog); 201 snprintf(c_arg, len, "%s", *prog);
202 exec_args_[0] = c_arg; 202 exec_args_[0] = c_arg;
203 int i = 1; 203 int i = 1;
204 for (unsigned j = 0; j < command_args->Length(); i++, j++) { 204 for (unsigned j = 0; j < command_args->Length(); i++, j++) {
205 Handle<Value> arg(command_args->Get(Integer::New(j))); 205 Handle<Value> arg(command_args->Get(Integer::New(j)));
206 String::Utf8Value utf8_arg(arg); 206 String::Utf8Value utf8_arg(arg);
207 if (*utf8_arg == NULL) { 207 if (*utf8_arg == NULL) {
208 exec_args_[i] = NULL; // Consistent state for destructor. 208 exec_args_[i] = NULL; // Consistent state for destructor.
209 const char* message = 209 const char* message =
210 "os.system(): String conversion of argument failed."; 210 "os.system(): String conversion of argument failed.";
211 ThrowException(String::New(message)); 211 isolate->ThrowException(String::NewFromUtf8(isolate, message));
212 return false; 212 return false;
213 } 213 }
214 int len = utf8_arg.length() + 1; 214 int len = utf8_arg.length() + 1;
215 char* c_arg = new char[len]; 215 char* c_arg = new char[len];
216 snprintf(c_arg, len, "%s", *utf8_arg); 216 snprintf(c_arg, len, "%s", *utf8_arg);
217 exec_args_[i] = c_arg; 217 exec_args_[i] = c_arg;
218 } 218 }
219 exec_args_[i] = NULL; 219 exec_args_[i] = NULL;
220 return true; 220 return true;
221 } 221 }
(...skipping 16 matching lines...) Expand all
238 238
239 239
240 // Gets the optional timeouts from the arguments to the system() call. 240 // Gets the optional timeouts from the arguments to the system() call.
241 static bool GetTimeouts(const v8::FunctionCallbackInfo<v8::Value>& args, 241 static bool GetTimeouts(const v8::FunctionCallbackInfo<v8::Value>& args,
242 int* read_timeout, 242 int* read_timeout,
243 int* total_timeout) { 243 int* total_timeout) {
244 if (args.Length() > 3) { 244 if (args.Length() > 3) {
245 if (args[3]->IsNumber()) { 245 if (args[3]->IsNumber()) {
246 *total_timeout = args[3]->Int32Value(); 246 *total_timeout = args[3]->Int32Value();
247 } else { 247 } else {
248 args.GetIsolate()->ThrowException( 248 args.GetIsolate()->ThrowException(String::NewFromUtf8(
249 String::New("system: Argument 4 must be a number")); 249 args.GetIsolate(), "system: Argument 4 must be a number"));
250 return false; 250 return false;
251 } 251 }
252 } 252 }
253 if (args.Length() > 2) { 253 if (args.Length() > 2) {
254 if (args[2]->IsNumber()) { 254 if (args[2]->IsNumber()) {
255 *read_timeout = args[2]->Int32Value(); 255 *read_timeout = args[2]->Int32Value();
256 } else { 256 } else {
257 args.GetIsolate()->ThrowException( 257 args.GetIsolate()->ThrowException(String::NewFromUtf8(
258 String::New("system: Argument 3 must be a number")); 258 args.GetIsolate(), "system: Argument 3 must be a number"));
259 return false; 259 return false;
260 } 260 }
261 } 261 }
262 return true; 262 return true;
263 } 263 }
264 264
265 265
266 static const int kReadFD = 0; 266 static const int kReadFD = 0;
267 static const int kWriteFD = 1; 267 static const int kWriteFD = 1;
268 268
(...skipping 17 matching lines...) Expand all
286 int bytes_written; 286 int bytes_written;
287 do { 287 do {
288 bytes_written = write(exec_error_fds[kWriteFD], &err, sizeof(err)); 288 bytes_written = write(exec_error_fds[kWriteFD], &err, sizeof(err));
289 } while (bytes_written == -1 && errno == EINTR); 289 } while (bytes_written == -1 && errno == EINTR);
290 // Return (and exit child process). 290 // Return (and exit child process).
291 } 291 }
292 292
293 293
294 // Runs in the parent process. Checks that the child was able to exec (closing 294 // Runs in the parent process. Checks that the child was able to exec (closing
295 // the file desriptor), or reports an error if it failed. 295 // the file desriptor), or reports an error if it failed.
296 static bool ChildLaunchedOK(int* exec_error_fds) { 296 static bool ChildLaunchedOK(Isolate* isolate, int* exec_error_fds) {
297 int bytes_read; 297 int bytes_read;
298 int err; 298 int err;
299 do { 299 do {
300 bytes_read = read(exec_error_fds[kReadFD], &err, sizeof(err)); 300 bytes_read = read(exec_error_fds[kReadFD], &err, sizeof(err));
301 } while (bytes_read == -1 && errno == EINTR); 301 } while (bytes_read == -1 && errno == EINTR);
302 if (bytes_read != 0) { 302 if (bytes_read != 0) {
303 ThrowException(String::New(strerror(err))); 303 isolate->ThrowException(String::NewFromUtf8(isolate, strerror(err)));
304 return false; 304 return false;
305 } 305 }
306 return true; 306 return true;
307 } 307 }
308 308
309 309
310 // Accumulates the output from the child in a string handle. Returns true if it 310 // Accumulates the output from the child in a string handle. Returns true if it
311 // succeeded or false if an exception was thrown. 311 // succeeded or false if an exception was thrown.
312 static Handle<Value> GetStdout(int child_fd, 312 static Handle<Value> GetStdout(Isolate* isolate,
313 int child_fd,
313 struct timeval& start_time, 314 struct timeval& start_time,
314 int read_timeout, 315 int read_timeout,
315 int total_timeout) { 316 int total_timeout) {
316 Handle<String> accumulator = String::Empty(); 317 Handle<String> accumulator = String::Empty();
317 318
318 int fullness = 0; 319 int fullness = 0;
319 static const int kStdoutReadBufferSize = 4096; 320 static const int kStdoutReadBufferSize = 4096;
320 char buffer[kStdoutReadBufferSize]; 321 char buffer[kStdoutReadBufferSize];
321 322
322 if (fcntl(child_fd, F_SETFL, O_NONBLOCK) != 0) { 323 if (fcntl(child_fd, F_SETFL, O_NONBLOCK) != 0) {
323 return ThrowException(String::New(strerror(errno))); 324 return isolate->ThrowException(
325 String::NewFromUtf8(isolate, strerror(errno)));
324 } 326 }
325 327
326 int bytes_read; 328 int bytes_read;
327 do { 329 do {
328 bytes_read = read(child_fd, 330 bytes_read = read(child_fd,
329 buffer + fullness, 331 buffer + fullness,
330 kStdoutReadBufferSize - fullness); 332 kStdoutReadBufferSize - fullness);
331 if (bytes_read == -1) { 333 if (bytes_read == -1) {
332 if (errno == EAGAIN) { 334 if (errno == EAGAIN) {
333 if (!WaitOnFD(child_fd, 335 if (!WaitOnFD(child_fd,
334 read_timeout, 336 read_timeout,
335 total_timeout, 337 total_timeout,
336 start_time) || 338 start_time) ||
337 (TimeIsOut(start_time, total_timeout))) { 339 (TimeIsOut(start_time, total_timeout))) {
338 return ThrowException(String::New("Timed out waiting for output")); 340 return isolate->ThrowException(
341 String::NewFromUtf8(isolate, "Timed out waiting for output"));
339 } 342 }
340 continue; 343 continue;
341 } else if (errno == EINTR) { 344 } else if (errno == EINTR) {
342 continue; 345 continue;
343 } else { 346 } else {
344 break; 347 break;
345 } 348 }
346 } 349 }
347 if (bytes_read + fullness > 0) { 350 if (bytes_read + fullness > 0) {
348 int length = bytes_read == 0 ? 351 int length = bytes_read == 0 ?
349 bytes_read + fullness : 352 bytes_read + fullness :
350 LengthWithoutIncompleteUtf8(buffer, bytes_read + fullness); 353 LengthWithoutIncompleteUtf8(buffer, bytes_read + fullness);
351 Handle<String> addition = String::New(buffer, length); 354 Handle<String> addition =
355 String::NewFromUtf8(isolate, buffer, String::kNormalString, length);
352 accumulator = String::Concat(accumulator, addition); 356 accumulator = String::Concat(accumulator, addition);
353 fullness = bytes_read + fullness - length; 357 fullness = bytes_read + fullness - length;
354 memcpy(buffer, buffer + length, fullness); 358 memcpy(buffer, buffer + length, fullness);
355 } 359 }
356 } while (bytes_read != 0); 360 } while (bytes_read != 0);
357 return accumulator; 361 return accumulator;
358 } 362 }
359 363
360 364
361 // Modern Linux has the waitid call, which is like waitpid, but more useful 365 // Modern Linux has the waitid call, which is like waitpid, but more useful
362 // if you want a timeout. If we don't have waitid we can't limit the time 366 // if you want a timeout. If we don't have waitid we can't limit the time
363 // waiting for the process to exit without losing the information about 367 // waiting for the process to exit without losing the information about
364 // whether it exited normally. In the common case this doesn't matter because 368 // whether it exited normally. In the common case this doesn't matter because
365 // we don't get here before the child has closed stdout and most programs don't 369 // we don't get here before the child has closed stdout and most programs don't
366 // do that before they exit. 370 // do that before they exit.
367 // 371 //
368 // We're disabling usage of waitid in Mac OS X because it doens't work for us: 372 // We're disabling usage of waitid in Mac OS X because it doens't work for us:
369 // a parent process hangs on waiting while a child process is already a zombie. 373 // a parent process hangs on waiting while a child process is already a zombie.
370 // See http://code.google.com/p/v8/issues/detail?id=401. 374 // See http://code.google.com/p/v8/issues/detail?id=401.
371 #if defined(WNOWAIT) && !defined(ANDROID) && !defined(__APPLE__) \ 375 #if defined(WNOWAIT) && !defined(ANDROID) && !defined(__APPLE__) \
372 && !defined(__NetBSD__) 376 && !defined(__NetBSD__)
373 #if !defined(__FreeBSD__) 377 #if !defined(__FreeBSD__)
374 #define HAS_WAITID 1 378 #define HAS_WAITID 1
375 #endif 379 #endif
376 #endif 380 #endif
377 381
378 382
379 // Get exit status of child. 383 // Get exit status of child.
380 static bool WaitForChild(int pid, 384 static bool WaitForChild(Isolate* isolate,
385 int pid,
381 ZombieProtector& child_waiter, 386 ZombieProtector& child_waiter,
382 struct timeval& start_time, 387 struct timeval& start_time,
383 int read_timeout, 388 int read_timeout,
384 int total_timeout) { 389 int total_timeout) {
385 #ifdef HAS_WAITID 390 #ifdef HAS_WAITID
386 391
387 siginfo_t child_info; 392 siginfo_t child_info;
388 child_info.si_pid = 0; 393 child_info.si_pid = 0;
389 int useconds = 1; 394 int useconds = 1;
390 // Wait for child to exit. 395 // Wait for child to exit.
391 while (child_info.si_pid == 0) { 396 while (child_info.si_pid == 0) {
392 waitid(P_PID, pid, &child_info, WEXITED | WNOHANG | WNOWAIT); 397 waitid(P_PID, pid, &child_info, WEXITED | WNOHANG | WNOWAIT);
393 usleep(useconds); 398 usleep(useconds);
394 if (useconds < 1000000) useconds <<= 1; 399 if (useconds < 1000000) useconds <<= 1;
395 if ((read_timeout != -1 && useconds / 1000 > read_timeout) || 400 if ((read_timeout != -1 && useconds / 1000 > read_timeout) ||
396 (TimeIsOut(start_time, total_timeout))) { 401 (TimeIsOut(start_time, total_timeout))) {
397 ThrowException(String::New("Timed out waiting for process to terminate")); 402 isolate->ThrowException(String::NewFromUtf8(
403 isolate, "Timed out waiting for process to terminate"));
398 kill(pid, SIGINT); 404 kill(pid, SIGINT);
399 return false; 405 return false;
400 } 406 }
401 } 407 }
402 if (child_info.si_code == CLD_KILLED) { 408 if (child_info.si_code == CLD_KILLED) {
403 char message[999]; 409 char message[999];
404 snprintf(message, 410 snprintf(message,
405 sizeof(message), 411 sizeof(message),
406 "Child killed by signal %d", 412 "Child killed by signal %d",
407 child_info.si_status); 413 child_info.si_status);
408 ThrowException(String::New(message)); 414 isolate->ThrowException(String::NewFromUtf8(isolate, message));
409 return false; 415 return false;
410 } 416 }
411 if (child_info.si_code == CLD_EXITED && child_info.si_status != 0) { 417 if (child_info.si_code == CLD_EXITED && child_info.si_status != 0) {
412 char message[999]; 418 char message[999];
413 snprintf(message, 419 snprintf(message,
414 sizeof(message), 420 sizeof(message),
415 "Child exited with status %d", 421 "Child exited with status %d",
416 child_info.si_status); 422 child_info.si_status);
417 ThrowException(String::New(message)); 423 isolate->ThrowException(String::NewFromUtf8(isolate, message));
418 return false; 424 return false;
419 } 425 }
420 426
421 #else // No waitid call. 427 #else // No waitid call.
422 428
423 int child_status; 429 int child_status;
424 waitpid(pid, &child_status, 0); // We hang here if the child doesn't exit. 430 waitpid(pid, &child_status, 0); // We hang here if the child doesn't exit.
425 child_waiter.ChildIsDeadNow(); 431 child_waiter.ChildIsDeadNow();
426 if (WIFSIGNALED(child_status)) { 432 if (WIFSIGNALED(child_status)) {
427 char message[999]; 433 char message[999];
428 snprintf(message, 434 snprintf(message,
429 sizeof(message), 435 sizeof(message),
430 "Child killed by signal %d", 436 "Child killed by signal %d",
431 WTERMSIG(child_status)); 437 WTERMSIG(child_status));
432 ThrowException(String::New(message)); 438 isolate->ThrowException(String::NewFromUtf8(isolate, message));
433 return false; 439 return false;
434 } 440 }
435 if (WEXITSTATUS(child_status) != 0) { 441 if (WEXITSTATUS(child_status) != 0) {
436 char message[999]; 442 char message[999];
437 int exit_status = WEXITSTATUS(child_status); 443 int exit_status = WEXITSTATUS(child_status);
438 snprintf(message, 444 snprintf(message,
439 sizeof(message), 445 sizeof(message),
440 "Child exited with status %d", 446 "Child exited with status %d",
441 exit_status); 447 exit_status);
442 ThrowException(String::New(message)); 448 isolate->ThrowException(String::NewFromUtf8(isolate, message));
443 return false; 449 return false;
444 } 450 }
445 451
446 #endif // No waitid call. 452 #endif // No waitid call.
447 453
448 return true; 454 return true;
449 } 455 }
450 456
451 457
452 // Implementation of the system() function (see d8.h for details). 458 // Implementation of the system() function (see d8.h for details).
453 void Shell::System(const v8::FunctionCallbackInfo<v8::Value>& args) { 459 void Shell::System(const v8::FunctionCallbackInfo<v8::Value>& args) {
454 HandleScope scope(args.GetIsolate()); 460 HandleScope scope(args.GetIsolate());
455 int read_timeout = -1; 461 int read_timeout = -1;
456 int total_timeout = -1; 462 int total_timeout = -1;
457 if (!GetTimeouts(args, &read_timeout, &total_timeout)) return; 463 if (!GetTimeouts(args, &read_timeout, &total_timeout)) return;
458 Handle<Array> command_args; 464 Handle<Array> command_args;
459 if (args.Length() > 1) { 465 if (args.Length() > 1) {
460 if (!args[1]->IsArray()) { 466 if (!args[1]->IsArray()) {
461 args.GetIsolate()->ThrowException( 467 args.GetIsolate()->ThrowException(String::NewFromUtf8(
462 String::New("system: Argument 2 must be an array")); 468 args.GetIsolate(), "system: Argument 2 must be an array"));
463 return; 469 return;
464 } 470 }
465 command_args = Handle<Array>::Cast(args[1]); 471 command_args = Handle<Array>::Cast(args[1]);
466 } else { 472 } else {
467 command_args = Array::New(0); 473 command_args = Array::New(0);
468 } 474 }
469 if (command_args->Length() > ExecArgs::kMaxArgs) { 475 if (command_args->Length() > ExecArgs::kMaxArgs) {
470 args.GetIsolate()->ThrowException( 476 args.GetIsolate()->ThrowException(String::NewFromUtf8(
471 String::New("Too many arguments to system()")); 477 args.GetIsolate(), "Too many arguments to system()"));
472 return; 478 return;
473 } 479 }
474 if (args.Length() < 1) { 480 if (args.Length() < 1) {
475 args.GetIsolate()->ThrowException( 481 args.GetIsolate()->ThrowException(String::NewFromUtf8(
476 String::New("Too few arguments to system()")); 482 args.GetIsolate(), "Too few arguments to system()"));
477 return; 483 return;
478 } 484 }
479 485
480 struct timeval start_time; 486 struct timeval start_time;
481 gettimeofday(&start_time, NULL); 487 gettimeofday(&start_time, NULL);
482 488
483 ExecArgs exec_args; 489 ExecArgs exec_args;
484 if (!exec_args.Init(args[0], command_args)) { 490 if (!exec_args.Init(args.GetIsolate(), args[0], command_args)) {
485 return; 491 return;
486 } 492 }
487 int exec_error_fds[2]; 493 int exec_error_fds[2];
488 int stdout_fds[2]; 494 int stdout_fds[2];
489 495
490 if (pipe(exec_error_fds) != 0) { 496 if (pipe(exec_error_fds) != 0) {
491 args.GetIsolate()->ThrowException( 497 args.GetIsolate()->ThrowException(
492 String::New("pipe syscall failed.")); 498 String::NewFromUtf8(args.GetIsolate(), "pipe syscall failed."));
493 return; 499 return;
494 } 500 }
495 if (pipe(stdout_fds) != 0) { 501 if (pipe(stdout_fds) != 0) {
496 args.GetIsolate()->ThrowException( 502 args.GetIsolate()->ThrowException(
497 String::New("pipe syscall failed.")); 503 String::NewFromUtf8(args.GetIsolate(), "pipe syscall failed."));
498 return; 504 return;
499 } 505 }
500 506
501 pid_t pid = fork(); 507 pid_t pid = fork();
502 if (pid == 0) { // Child process. 508 if (pid == 0) { // Child process.
503 ExecSubprocess(exec_error_fds, stdout_fds, exec_args); 509 ExecSubprocess(exec_error_fds, stdout_fds, exec_args);
504 exit(1); 510 exit(1);
505 } 511 }
506 512
507 // Parent process. Ensure that we clean up if we exit this function early. 513 // Parent process. Ensure that we clean up if we exit this function early.
508 ZombieProtector child_waiter(pid); 514 ZombieProtector child_waiter(pid);
509 close(exec_error_fds[kWriteFD]); 515 close(exec_error_fds[kWriteFD]);
510 close(stdout_fds[kWriteFD]); 516 close(stdout_fds[kWriteFD]);
511 OpenFDCloser error_read_closer(exec_error_fds[kReadFD]); 517 OpenFDCloser error_read_closer(exec_error_fds[kReadFD]);
512 OpenFDCloser stdout_read_closer(stdout_fds[kReadFD]); 518 OpenFDCloser stdout_read_closer(stdout_fds[kReadFD]);
513 519
514 if (!ChildLaunchedOK(exec_error_fds)) return; 520 if (!ChildLaunchedOK(args.GetIsolate(), exec_error_fds)) return;
515 521
516 Handle<Value> accumulator = GetStdout(stdout_fds[kReadFD], 522 Handle<Value> accumulator = GetStdout(args.GetIsolate(),
523 stdout_fds[kReadFD],
517 start_time, 524 start_time,
518 read_timeout, 525 read_timeout,
519 total_timeout); 526 total_timeout);
520 if (accumulator->IsUndefined()) { 527 if (accumulator->IsUndefined()) {
521 kill(pid, SIGINT); // On timeout, kill the subprocess. 528 kill(pid, SIGINT); // On timeout, kill the subprocess.
522 args.GetReturnValue().Set(accumulator); 529 args.GetReturnValue().Set(accumulator);
523 return; 530 return;
524 } 531 }
525 532
526 if (!WaitForChild(pid, 533 if (!WaitForChild(args.GetIsolate(),
534 pid,
527 child_waiter, 535 child_waiter,
528 start_time, 536 start_time,
529 read_timeout, 537 read_timeout,
530 total_timeout)) { 538 total_timeout)) {
531 return; 539 return;
532 } 540 }
533 541
534 args.GetReturnValue().Set(accumulator); 542 args.GetReturnValue().Set(accumulator);
535 } 543 }
536 544
537 545
538 void Shell::ChangeDirectory(const v8::FunctionCallbackInfo<v8::Value>& args) { 546 void Shell::ChangeDirectory(const v8::FunctionCallbackInfo<v8::Value>& args) {
539 if (args.Length() != 1) { 547 if (args.Length() != 1) {
540 const char* message = "chdir() takes one argument"; 548 const char* message = "chdir() takes one argument";
541 args.GetIsolate()->ThrowException(String::New(message)); 549 args.GetIsolate()->ThrowException(
550 String::NewFromUtf8(args.GetIsolate(), message));
542 return; 551 return;
543 } 552 }
544 String::Utf8Value directory(args[0]); 553 String::Utf8Value directory(args[0]);
545 if (*directory == NULL) { 554 if (*directory == NULL) {
546 const char* message = "os.chdir(): String conversion of argument failed."; 555 const char* message = "os.chdir(): String conversion of argument failed.";
547 args.GetIsolate()->ThrowException(String::New(message)); 556 args.GetIsolate()->ThrowException(
557 String::NewFromUtf8(args.GetIsolate(), message));
548 return; 558 return;
549 } 559 }
550 if (chdir(*directory) != 0) { 560 if (chdir(*directory) != 0) {
551 args.GetIsolate()->ThrowException(String::New(strerror(errno))); 561 args.GetIsolate()->ThrowException(
562 String::NewFromUtf8(args.GetIsolate(), strerror(errno)));
552 return; 563 return;
553 } 564 }
554 } 565 }
555 566
556 567
557 void Shell::SetUMask(const v8::FunctionCallbackInfo<v8::Value>& args) { 568 void Shell::SetUMask(const v8::FunctionCallbackInfo<v8::Value>& args) {
558 if (args.Length() != 1) { 569 if (args.Length() != 1) {
559 const char* message = "umask() takes one argument"; 570 const char* message = "umask() takes one argument";
560 args.GetIsolate()->ThrowException(String::New(message)); 571 args.GetIsolate()->ThrowException(
572 String::NewFromUtf8(args.GetIsolate(), message));
561 return; 573 return;
562 } 574 }
563 if (args[0]->IsNumber()) { 575 if (args[0]->IsNumber()) {
564 mode_t mask = args[0]->Int32Value(); 576 mode_t mask = args[0]->Int32Value();
565 int previous = umask(mask); 577 int previous = umask(mask);
566 args.GetReturnValue().Set(previous); 578 args.GetReturnValue().Set(previous);
567 return; 579 return;
568 } else { 580 } else {
569 const char* message = "umask() argument must be numeric"; 581 const char* message = "umask() argument must be numeric";
570 args.GetIsolate()->ThrowException(String::New(message)); 582 args.GetIsolate()->ThrowException(
583 String::NewFromUtf8(args.GetIsolate(), message));
571 return; 584 return;
572 } 585 }
573 } 586 }
574 587
575 588
576 static bool CheckItsADirectory(char* directory) { 589 static bool CheckItsADirectory(Isolate* isolate, char* directory) {
577 struct stat stat_buf; 590 struct stat stat_buf;
578 int stat_result = stat(directory, &stat_buf); 591 int stat_result = stat(directory, &stat_buf);
579 if (stat_result != 0) { 592 if (stat_result != 0) {
580 ThrowException(String::New(strerror(errno))); 593 isolate->ThrowException(String::NewFromUtf8(isolate, strerror(errno)));
581 return false; 594 return false;
582 } 595 }
583 if ((stat_buf.st_mode & S_IFDIR) != 0) return true; 596 if ((stat_buf.st_mode & S_IFDIR) != 0) return true;
584 ThrowException(String::New(strerror(EEXIST))); 597 isolate->ThrowException(String::NewFromUtf8(isolate, strerror(EEXIST)));
585 return false; 598 return false;
586 } 599 }
587 600
588 601
589 // Returns true for success. Creates intermediate directories as needed. No 602 // Returns true for success. Creates intermediate directories as needed. No
590 // error if the directory exists already. 603 // error if the directory exists already.
591 static bool mkdirp(char* directory, mode_t mask) { 604 static bool mkdirp(Isolate* isolate, char* directory, mode_t mask) {
592 int result = mkdir(directory, mask); 605 int result = mkdir(directory, mask);
593 if (result == 0) return true; 606 if (result == 0) return true;
594 if (errno == EEXIST) { 607 if (errno == EEXIST) {
595 return CheckItsADirectory(directory); 608 return CheckItsADirectory(isolate, directory);
596 } else if (errno == ENOENT) { // Intermediate path element is missing. 609 } else if (errno == ENOENT) { // Intermediate path element is missing.
597 char* last_slash = strrchr(directory, '/'); 610 char* last_slash = strrchr(directory, '/');
598 if (last_slash == NULL) { 611 if (last_slash == NULL) {
599 ThrowException(String::New(strerror(errno))); 612 isolate->ThrowException(String::NewFromUtf8(isolate, strerror(errno)));
600 return false; 613 return false;
601 } 614 }
602 *last_slash = 0; 615 *last_slash = 0;
603 if (!mkdirp(directory, mask)) return false; 616 if (!mkdirp(isolate, directory, mask)) return false;
604 *last_slash = '/'; 617 *last_slash = '/';
605 result = mkdir(directory, mask); 618 result = mkdir(directory, mask);
606 if (result == 0) return true; 619 if (result == 0) return true;
607 if (errno == EEXIST) { 620 if (errno == EEXIST) {
608 return CheckItsADirectory(directory); 621 return CheckItsADirectory(isolate, directory);
609 } 622 }
610 ThrowException(String::New(strerror(errno))); 623 isolate->ThrowException(String::NewFromUtf8(isolate, strerror(errno)));
611 return false; 624 return false;
612 } else { 625 } else {
613 ThrowException(String::New(strerror(errno))); 626 isolate->ThrowException(String::NewFromUtf8(isolate, strerror(errno)));
614 return false; 627 return false;
615 } 628 }
616 } 629 }
617 630
618 631
619 void Shell::MakeDirectory(const v8::FunctionCallbackInfo<v8::Value>& args) { 632 void Shell::MakeDirectory(const v8::FunctionCallbackInfo<v8::Value>& args) {
620 mode_t mask = 0777; 633 mode_t mask = 0777;
621 if (args.Length() == 2) { 634 if (args.Length() == 2) {
622 if (args[1]->IsNumber()) { 635 if (args[1]->IsNumber()) {
623 mask = args[1]->Int32Value(); 636 mask = args[1]->Int32Value();
624 } else { 637 } else {
625 const char* message = "mkdirp() second argument must be numeric"; 638 const char* message = "mkdirp() second argument must be numeric";
626 args.GetIsolate()->ThrowException(String::New(message)); 639 args.GetIsolate()->ThrowException(
640 String::NewFromUtf8(args.GetIsolate(), message));
627 return; 641 return;
628 } 642 }
629 } else if (args.Length() != 1) { 643 } else if (args.Length() != 1) {
630 const char* message = "mkdirp() takes one or two arguments"; 644 const char* message = "mkdirp() takes one or two arguments";
631 args.GetIsolate()->ThrowException(String::New(message)); 645 args.GetIsolate()->ThrowException(
646 String::NewFromUtf8(args.GetIsolate(), message));
632 return; 647 return;
633 } 648 }
634 String::Utf8Value directory(args[0]); 649 String::Utf8Value directory(args[0]);
635 if (*directory == NULL) { 650 if (*directory == NULL) {
636 const char* message = "os.mkdirp(): String conversion of argument failed."; 651 const char* message = "os.mkdirp(): String conversion of argument failed.";
637 args.GetIsolate()->ThrowException(String::New(message)); 652 args.GetIsolate()->ThrowException(
653 String::NewFromUtf8(args.GetIsolate(), message));
638 return; 654 return;
639 } 655 }
640 mkdirp(*directory, mask); 656 mkdirp(args.GetIsolate(), *directory, mask);
641 } 657 }
642 658
643 659
644 void Shell::RemoveDirectory(const v8::FunctionCallbackInfo<v8::Value>& args) { 660 void Shell::RemoveDirectory(const v8::FunctionCallbackInfo<v8::Value>& args) {
645 if (args.Length() != 1) { 661 if (args.Length() != 1) {
646 const char* message = "rmdir() takes one or two arguments"; 662 const char* message = "rmdir() takes one or two arguments";
647 args.GetIsolate()->ThrowException(String::New(message)); 663 args.GetIsolate()->ThrowException(
664 String::NewFromUtf8(args.GetIsolate(), message));
648 return; 665 return;
649 } 666 }
650 String::Utf8Value directory(args[0]); 667 String::Utf8Value directory(args[0]);
651 if (*directory == NULL) { 668 if (*directory == NULL) {
652 const char* message = "os.rmdir(): String conversion of argument failed."; 669 const char* message = "os.rmdir(): String conversion of argument failed.";
653 args.GetIsolate()->ThrowException(String::New(message)); 670 args.GetIsolate()->ThrowException(
671 String::NewFromUtf8(args.GetIsolate(), message));
654 return; 672 return;
655 } 673 }
656 rmdir(*directory); 674 rmdir(*directory);
657 } 675 }
658 676
659 677
660 void Shell::SetEnvironment(const v8::FunctionCallbackInfo<v8::Value>& args) { 678 void Shell::SetEnvironment(const v8::FunctionCallbackInfo<v8::Value>& args) {
661 if (args.Length() != 2) { 679 if (args.Length() != 2) {
662 const char* message = "setenv() takes two arguments"; 680 const char* message = "setenv() takes two arguments";
663 args.GetIsolate()->ThrowException(String::New(message)); 681 args.GetIsolate()->ThrowException(
682 String::NewFromUtf8(args.GetIsolate(), message));
664 return; 683 return;
665 } 684 }
666 String::Utf8Value var(args[0]); 685 String::Utf8Value var(args[0]);
667 String::Utf8Value value(args[1]); 686 String::Utf8Value value(args[1]);
668 if (*var == NULL) { 687 if (*var == NULL) {
669 const char* message = 688 const char* message =
670 "os.setenv(): String conversion of variable name failed."; 689 "os.setenv(): String conversion of variable name failed.";
671 args.GetIsolate()->ThrowException(String::New(message)); 690 args.GetIsolate()->ThrowException(
691 String::NewFromUtf8(args.GetIsolate(), message));
672 return; 692 return;
673 } 693 }
674 if (*value == NULL) { 694 if (*value == NULL) {
675 const char* message = 695 const char* message =
676 "os.setenv(): String conversion of variable contents failed."; 696 "os.setenv(): String conversion of variable contents failed.";
677 args.GetIsolate()->ThrowException(String::New(message)); 697 args.GetIsolate()->ThrowException(
698 String::NewFromUtf8(args.GetIsolate(), message));
678 return; 699 return;
679 } 700 }
680 setenv(*var, *value, 1); 701 setenv(*var, *value, 1);
681 } 702 }
682 703
683 704
684 void Shell::UnsetEnvironment(const v8::FunctionCallbackInfo<v8::Value>& args) { 705 void Shell::UnsetEnvironment(const v8::FunctionCallbackInfo<v8::Value>& args) {
685 if (args.Length() != 1) { 706 if (args.Length() != 1) {
686 const char* message = "unsetenv() takes one argument"; 707 const char* message = "unsetenv() takes one argument";
687 args.GetIsolate()->ThrowException(String::New(message)); 708 args.GetIsolate()->ThrowException(
709 String::NewFromUtf8(args.GetIsolate(), message));
688 return; 710 return;
689 } 711 }
690 String::Utf8Value var(args[0]); 712 String::Utf8Value var(args[0]);
691 if (*var == NULL) { 713 if (*var == NULL) {
692 const char* message = 714 const char* message =
693 "os.setenv(): String conversion of variable name failed."; 715 "os.setenv(): String conversion of variable name failed.";
694 args.GetIsolate()->ThrowException(String::New(message)); 716 args.GetIsolate()->ThrowException(
717 String::NewFromUtf8(args.GetIsolate(), message));
695 return; 718 return;
696 } 719 }
697 unsetenv(*var); 720 unsetenv(*var);
698 } 721 }
699 722
700 723
701 void Shell::AddOSMethods(Handle<ObjectTemplate> os_templ) { 724 void Shell::AddOSMethods(Isolate* isolate, Handle<ObjectTemplate> os_templ) {
702 os_templ->Set(String::New("system"), FunctionTemplate::New(System)); 725 os_templ->Set(String::NewFromUtf8(isolate, "system"),
703 os_templ->Set(String::New("chdir"), FunctionTemplate::New(ChangeDirectory)); 726 FunctionTemplate::New(System));
704 os_templ->Set(String::New("setenv"), FunctionTemplate::New(SetEnvironment)); 727 os_templ->Set(String::NewFromUtf8(isolate, "chdir"),
705 os_templ->Set(String::New("unsetenv"), 728 FunctionTemplate::New(ChangeDirectory));
729 os_templ->Set(String::NewFromUtf8(isolate, "setenv"),
730 FunctionTemplate::New(SetEnvironment));
731 os_templ->Set(String::NewFromUtf8(isolate, "unsetenv"),
706 FunctionTemplate::New(UnsetEnvironment)); 732 FunctionTemplate::New(UnsetEnvironment));
707 os_templ->Set(String::New("umask"), FunctionTemplate::New(SetUMask)); 733 os_templ->Set(String::NewFromUtf8(isolate, "umask"),
708 os_templ->Set(String::New("mkdirp"), FunctionTemplate::New(MakeDirectory)); 734 FunctionTemplate::New(SetUMask));
709 os_templ->Set(String::New("rmdir"), FunctionTemplate::New(RemoveDirectory)); 735 os_templ->Set(String::NewFromUtf8(isolate, "mkdirp"),
736 FunctionTemplate::New(MakeDirectory));
737 os_templ->Set(String::NewFromUtf8(isolate, "rmdir"),
738 FunctionTemplate::New(RemoveDirectory));
710 } 739 }
711 740
712 } // namespace v8 741 } // namespace v8
OLDNEW
« no previous file with comments | « src/d8-debug.cc ('k') | src/d8-windows.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698