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

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

Issue 1235603004: Reland of "Make d8 stop using to-be-deprecated APIs" (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: fix Created 5 years, 5 months 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
« no previous file with comments | « src/d8-debug.cc ('k') | src/d8-readline.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 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <errno.h> 5 #include <errno.h>
6 #include <fcntl.h> 6 #include <fcntl.h>
7 #include <signal.h> 7 #include <signal.h>
8 #include <stdlib.h> 8 #include <stdlib.h>
9 #include <string.h> 9 #include <string.h>
10 #include <sys/stat.h> 10 #include <sys/stat.h>
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
163 163
164 164
165 // A utility class that takes the array of command arguments and puts then in an 165 // A utility class that takes the array of command arguments and puts then in an
166 // array of new[]ed UTF-8 C strings. Deallocates them again when it goes out of 166 // array of new[]ed UTF-8 C strings. Deallocates them again when it goes out of
167 // scope. 167 // scope.
168 class ExecArgs { 168 class ExecArgs {
169 public: 169 public:
170 ExecArgs() { 170 ExecArgs() {
171 exec_args_[0] = NULL; 171 exec_args_[0] = NULL;
172 } 172 }
173 bool Init(Isolate* isolate, Handle<Value> arg0, Handle<Array> command_args) { 173 bool Init(Isolate* isolate, Local<Value> arg0, Local<Array> command_args) {
174 String::Utf8Value prog(arg0); 174 String::Utf8Value prog(arg0);
175 if (*prog == NULL) { 175 if (*prog == NULL) {
176 const char* message = 176 const char* message =
177 "os.system(): String conversion of program name failed"; 177 "os.system(): String conversion of program name failed";
178 isolate->ThrowException(String::NewFromUtf8(isolate, message)); 178 isolate->ThrowException(
179 String::NewFromUtf8(isolate, message, NewStringType::kNormal)
180 .ToLocalChecked());
179 return false; 181 return false;
180 } 182 }
181 int len = prog.length() + 3; 183 int len = prog.length() + 3;
182 char* c_arg = new char[len]; 184 char* c_arg = new char[len];
183 snprintf(c_arg, len, "%s", *prog); 185 snprintf(c_arg, len, "%s", *prog);
184 exec_args_[0] = c_arg; 186 exec_args_[0] = c_arg;
185 int i = 1; 187 int i = 1;
186 for (unsigned j = 0; j < command_args->Length(); i++, j++) { 188 for (unsigned j = 0; j < command_args->Length(); i++, j++) {
187 Handle<Value> arg(command_args->Get(Integer::New(isolate, j))); 189 Local<Value> arg(
190 command_args->Get(isolate->GetCurrentContext(),
191 Integer::New(isolate, j)).ToLocalChecked());
188 String::Utf8Value utf8_arg(arg); 192 String::Utf8Value utf8_arg(arg);
189 if (*utf8_arg == NULL) { 193 if (*utf8_arg == NULL) {
190 exec_args_[i] = NULL; // Consistent state for destructor. 194 exec_args_[i] = NULL; // Consistent state for destructor.
191 const char* message = 195 const char* message =
192 "os.system(): String conversion of argument failed."; 196 "os.system(): String conversion of argument failed.";
193 isolate->ThrowException(String::NewFromUtf8(isolate, message)); 197 isolate->ThrowException(
198 String::NewFromUtf8(isolate, message, NewStringType::kNormal)
199 .ToLocalChecked());
194 return false; 200 return false;
195 } 201 }
196 int len = utf8_arg.length() + 1; 202 int len = utf8_arg.length() + 1;
197 char* c_arg = new char[len]; 203 char* c_arg = new char[len];
198 snprintf(c_arg, len, "%s", *utf8_arg); 204 snprintf(c_arg, len, "%s", *utf8_arg);
199 exec_args_[i] = c_arg; 205 exec_args_[i] = c_arg;
200 } 206 }
201 exec_args_[i] = NULL; 207 exec_args_[i] = NULL;
202 return true; 208 return true;
203 } 209 }
(...skipping 14 matching lines...) Expand all
218 char* exec_args_[kMaxArgs + 1]; 224 char* exec_args_[kMaxArgs + 1];
219 }; 225 };
220 226
221 227
222 // Gets the optional timeouts from the arguments to the system() call. 228 // Gets the optional timeouts from the arguments to the system() call.
223 static bool GetTimeouts(const v8::FunctionCallbackInfo<v8::Value>& args, 229 static bool GetTimeouts(const v8::FunctionCallbackInfo<v8::Value>& args,
224 int* read_timeout, 230 int* read_timeout,
225 int* total_timeout) { 231 int* total_timeout) {
226 if (args.Length() > 3) { 232 if (args.Length() > 3) {
227 if (args[3]->IsNumber()) { 233 if (args[3]->IsNumber()) {
228 *total_timeout = args[3]->Int32Value(); 234 *total_timeout = args[3]
235 ->Int32Value(args.GetIsolate()->GetCurrentContext())
236 .FromJust();
229 } else { 237 } else {
230 args.GetIsolate()->ThrowException(String::NewFromUtf8( 238 args.GetIsolate()->ThrowException(
231 args.GetIsolate(), "system: Argument 4 must be a number")); 239 String::NewFromUtf8(args.GetIsolate(),
240 "system: Argument 4 must be a number",
241 NewStringType::kNormal).ToLocalChecked());
232 return false; 242 return false;
233 } 243 }
234 } 244 }
235 if (args.Length() > 2) { 245 if (args.Length() > 2) {
236 if (args[2]->IsNumber()) { 246 if (args[2]->IsNumber()) {
237 *read_timeout = args[2]->Int32Value(); 247 *read_timeout = args[2]
248 ->Int32Value(args.GetIsolate()->GetCurrentContext())
249 .FromJust();
238 } else { 250 } else {
239 args.GetIsolate()->ThrowException(String::NewFromUtf8( 251 args.GetIsolate()->ThrowException(
240 args.GetIsolate(), "system: Argument 3 must be a number")); 252 String::NewFromUtf8(args.GetIsolate(),
253 "system: Argument 3 must be a number",
254 NewStringType::kNormal).ToLocalChecked());
241 return false; 255 return false;
242 } 256 }
243 } 257 }
244 return true; 258 return true;
245 } 259 }
246 260
247 261
248 static const int kReadFD = 0; 262 static const int kReadFD = 0;
249 static const int kWriteFD = 1; 263 static const int kWriteFD = 1;
250 264
(...skipping 24 matching lines...) Expand all
275 289
276 // Runs in the parent process. Checks that the child was able to exec (closing 290 // Runs in the parent process. Checks that the child was able to exec (closing
277 // the file desriptor), or reports an error if it failed. 291 // the file desriptor), or reports an error if it failed.
278 static bool ChildLaunchedOK(Isolate* isolate, int* exec_error_fds) { 292 static bool ChildLaunchedOK(Isolate* isolate, int* exec_error_fds) {
279 ssize_t bytes_read; 293 ssize_t bytes_read;
280 int err; 294 int err;
281 do { 295 do {
282 bytes_read = read(exec_error_fds[kReadFD], &err, sizeof(err)); 296 bytes_read = read(exec_error_fds[kReadFD], &err, sizeof(err));
283 } while (bytes_read == -1 && errno == EINTR); 297 } while (bytes_read == -1 && errno == EINTR);
284 if (bytes_read != 0) { 298 if (bytes_read != 0) {
285 isolate->ThrowException(String::NewFromUtf8(isolate, strerror(err))); 299 isolate->ThrowException(
300 String::NewFromUtf8(isolate, strerror(err), NewStringType::kNormal)
301 .ToLocalChecked());
286 return false; 302 return false;
287 } 303 }
288 return true; 304 return true;
289 } 305 }
290 306
291 307
292 // Accumulates the output from the child in a string handle. Returns true if it 308 // Accumulates the output from the child in a string handle. Returns true if it
293 // succeeded or false if an exception was thrown. 309 // succeeded or false if an exception was thrown.
294 static Handle<Value> GetStdout(Isolate* isolate, 310 static Local<Value> GetStdout(Isolate* isolate, int child_fd,
295 int child_fd, 311 const struct timeval& start_time,
296 const struct timeval& start_time, 312 int read_timeout, int total_timeout) {
297 int read_timeout, 313 Local<String> accumulator = String::Empty(isolate);
298 int total_timeout) {
299 Handle<String> accumulator = String::Empty(isolate);
300 314
301 int fullness = 0; 315 int fullness = 0;
302 static const int kStdoutReadBufferSize = 4096; 316 static const int kStdoutReadBufferSize = 4096;
303 char buffer[kStdoutReadBufferSize]; 317 char buffer[kStdoutReadBufferSize];
304 318
305 if (fcntl(child_fd, F_SETFL, O_NONBLOCK) != 0) { 319 if (fcntl(child_fd, F_SETFL, O_NONBLOCK) != 0) {
306 return isolate->ThrowException( 320 return isolate->ThrowException(
307 String::NewFromUtf8(isolate, strerror(errno))); 321 String::NewFromUtf8(isolate, strerror(errno), NewStringType::kNormal)
322 .ToLocalChecked());
308 } 323 }
309 324
310 int bytes_read; 325 int bytes_read;
311 do { 326 do {
312 bytes_read = static_cast<int>( 327 bytes_read = static_cast<int>(
313 read(child_fd, buffer + fullness, kStdoutReadBufferSize - fullness)); 328 read(child_fd, buffer + fullness, kStdoutReadBufferSize - fullness));
314 if (bytes_read == -1) { 329 if (bytes_read == -1) {
315 if (errno == EAGAIN) { 330 if (errno == EAGAIN) {
316 if (!WaitOnFD(child_fd, 331 if (!WaitOnFD(child_fd,
317 read_timeout, 332 read_timeout,
318 total_timeout, 333 total_timeout,
319 start_time) || 334 start_time) ||
320 (TimeIsOut(start_time, total_timeout))) { 335 (TimeIsOut(start_time, total_timeout))) {
321 return isolate->ThrowException( 336 return isolate->ThrowException(
322 String::NewFromUtf8(isolate, "Timed out waiting for output")); 337 String::NewFromUtf8(isolate, "Timed out waiting for output",
338 NewStringType::kNormal).ToLocalChecked());
323 } 339 }
324 continue; 340 continue;
325 } else if (errno == EINTR) { 341 } else if (errno == EINTR) {
326 continue; 342 continue;
327 } else { 343 } else {
328 break; 344 break;
329 } 345 }
330 } 346 }
331 if (bytes_read + fullness > 0) { 347 if (bytes_read + fullness > 0) {
332 int length = bytes_read == 0 ? 348 int length = bytes_read == 0 ?
333 bytes_read + fullness : 349 bytes_read + fullness :
334 LengthWithoutIncompleteUtf8(buffer, bytes_read + fullness); 350 LengthWithoutIncompleteUtf8(buffer, bytes_read + fullness);
335 Handle<String> addition = 351 Local<String> addition =
336 String::NewFromUtf8(isolate, buffer, String::kNormalString, length); 352 String::NewFromUtf8(isolate, buffer, NewStringType::kNormal, length)
353 .ToLocalChecked();
337 accumulator = String::Concat(accumulator, addition); 354 accumulator = String::Concat(accumulator, addition);
338 fullness = bytes_read + fullness - length; 355 fullness = bytes_read + fullness - length;
339 memcpy(buffer, buffer + length, fullness); 356 memcpy(buffer, buffer + length, fullness);
340 } 357 }
341 } while (bytes_read != 0); 358 } while (bytes_read != 0);
342 return accumulator; 359 return accumulator;
343 } 360 }
344 361
345 362
346 // Modern Linux has the waitid call, which is like waitpid, but more useful 363 // Modern Linux has the waitid call, which is like waitpid, but more useful
(...skipping 26 matching lines...) Expand all
373 siginfo_t child_info; 390 siginfo_t child_info;
374 child_info.si_pid = 0; 391 child_info.si_pid = 0;
375 int useconds = 1; 392 int useconds = 1;
376 // Wait for child to exit. 393 // Wait for child to exit.
377 while (child_info.si_pid == 0) { 394 while (child_info.si_pid == 0) {
378 waitid(P_PID, pid, &child_info, WEXITED | WNOHANG | WNOWAIT); 395 waitid(P_PID, pid, &child_info, WEXITED | WNOHANG | WNOWAIT);
379 usleep(useconds); 396 usleep(useconds);
380 if (useconds < 1000000) useconds <<= 1; 397 if (useconds < 1000000) useconds <<= 1;
381 if ((read_timeout != -1 && useconds / 1000 > read_timeout) || 398 if ((read_timeout != -1 && useconds / 1000 > read_timeout) ||
382 (TimeIsOut(start_time, total_timeout))) { 399 (TimeIsOut(start_time, total_timeout))) {
383 isolate->ThrowException(String::NewFromUtf8( 400 isolate->ThrowException(
384 isolate, "Timed out waiting for process to terminate")); 401 String::NewFromUtf8(isolate,
402 "Timed out waiting for process to terminate",
403 NewStringType::kNormal).ToLocalChecked());
385 kill(pid, SIGINT); 404 kill(pid, SIGINT);
386 return false; 405 return false;
387 } 406 }
388 } 407 }
389 if (child_info.si_code == CLD_KILLED) { 408 if (child_info.si_code == CLD_KILLED) {
390 char message[999]; 409 char message[999];
391 snprintf(message, 410 snprintf(message,
392 sizeof(message), 411 sizeof(message),
393 "Child killed by signal %d", 412 "Child killed by signal %d",
394 child_info.si_status); 413 child_info.si_status);
395 isolate->ThrowException(String::NewFromUtf8(isolate, message)); 414 isolate->ThrowException(
415 String::NewFromUtf8(isolate, message, NewStringType::kNormal)
416 .ToLocalChecked());
396 return false; 417 return false;
397 } 418 }
398 if (child_info.si_code == CLD_EXITED && child_info.si_status != 0) { 419 if (child_info.si_code == CLD_EXITED && child_info.si_status != 0) {
399 char message[999]; 420 char message[999];
400 snprintf(message, 421 snprintf(message,
401 sizeof(message), 422 sizeof(message),
402 "Child exited with status %d", 423 "Child exited with status %d",
403 child_info.si_status); 424 child_info.si_status);
404 isolate->ThrowException(String::NewFromUtf8(isolate, message)); 425 isolate->ThrowException(
426 String::NewFromUtf8(isolate, message, NewStringType::kNormal)
427 .ToLocalChecked());
405 return false; 428 return false;
406 } 429 }
407 430
408 #else // No waitid call. 431 #else // No waitid call.
409 432
410 int child_status; 433 int child_status;
411 waitpid(pid, &child_status, 0); // We hang here if the child doesn't exit. 434 waitpid(pid, &child_status, 0); // We hang here if the child doesn't exit.
412 child_waiter.ChildIsDeadNow(); 435 child_waiter.ChildIsDeadNow();
413 if (WIFSIGNALED(child_status)) { 436 if (WIFSIGNALED(child_status)) {
414 char message[999]; 437 char message[999];
415 snprintf(message, 438 snprintf(message,
416 sizeof(message), 439 sizeof(message),
417 "Child killed by signal %d", 440 "Child killed by signal %d",
418 WTERMSIG(child_status)); 441 WTERMSIG(child_status));
419 isolate->ThrowException(String::NewFromUtf8(isolate, message)); 442 isolate->ThrowException(
443 String::NewFromUtf8(isolate, message, NewStringType::kNormal)
444 .ToLocalChecked());
420 return false; 445 return false;
421 } 446 }
422 if (WEXITSTATUS(child_status) != 0) { 447 if (WEXITSTATUS(child_status) != 0) {
423 char message[999]; 448 char message[999];
424 int exit_status = WEXITSTATUS(child_status); 449 int exit_status = WEXITSTATUS(child_status);
425 snprintf(message, 450 snprintf(message,
426 sizeof(message), 451 sizeof(message),
427 "Child exited with status %d", 452 "Child exited with status %d",
428 exit_status); 453 exit_status);
429 isolate->ThrowException(String::NewFromUtf8(isolate, message)); 454 isolate->ThrowException(
455 String::NewFromUtf8(isolate, message, NewStringType::kNormal)
456 .ToLocalChecked());
430 return false; 457 return false;
431 } 458 }
432 459
433 #endif // No waitid call. 460 #endif // No waitid call.
434 461
435 return true; 462 return true;
436 } 463 }
437 464
438 465
439 // Implementation of the system() function (see d8.h for details). 466 // Implementation of the system() function (see d8.h for details).
440 void Shell::System(const v8::FunctionCallbackInfo<v8::Value>& args) { 467 void Shell::System(const v8::FunctionCallbackInfo<v8::Value>& args) {
441 HandleScope scope(args.GetIsolate()); 468 HandleScope scope(args.GetIsolate());
442 int read_timeout = -1; 469 int read_timeout = -1;
443 int total_timeout = -1; 470 int total_timeout = -1;
444 if (!GetTimeouts(args, &read_timeout, &total_timeout)) return; 471 if (!GetTimeouts(args, &read_timeout, &total_timeout)) return;
445 Handle<Array> command_args; 472 Local<Array> command_args;
446 if (args.Length() > 1) { 473 if (args.Length() > 1) {
447 if (!args[1]->IsArray()) { 474 if (!args[1]->IsArray()) {
448 args.GetIsolate()->ThrowException(String::NewFromUtf8( 475 args.GetIsolate()->ThrowException(
449 args.GetIsolate(), "system: Argument 2 must be an array")); 476 String::NewFromUtf8(args.GetIsolate(),
477 "system: Argument 2 must be an array",
478 NewStringType::kNormal).ToLocalChecked());
450 return; 479 return;
451 } 480 }
452 command_args = Handle<Array>::Cast(args[1]); 481 command_args = Local<Array>::Cast(args[1]);
453 } else { 482 } else {
454 command_args = Array::New(args.GetIsolate(), 0); 483 command_args = Array::New(args.GetIsolate(), 0);
455 } 484 }
456 if (command_args->Length() > ExecArgs::kMaxArgs) { 485 if (command_args->Length() > ExecArgs::kMaxArgs) {
457 args.GetIsolate()->ThrowException(String::NewFromUtf8( 486 args.GetIsolate()->ThrowException(
458 args.GetIsolate(), "Too many arguments to system()")); 487 String::NewFromUtf8(args.GetIsolate(), "Too many arguments to system()",
488 NewStringType::kNormal).ToLocalChecked());
459 return; 489 return;
460 } 490 }
461 if (args.Length() < 1) { 491 if (args.Length() < 1) {
462 args.GetIsolate()->ThrowException(String::NewFromUtf8( 492 args.GetIsolate()->ThrowException(
463 args.GetIsolate(), "Too few arguments to system()")); 493 String::NewFromUtf8(args.GetIsolate(), "Too few arguments to system()",
494 NewStringType::kNormal).ToLocalChecked());
464 return; 495 return;
465 } 496 }
466 497
467 struct timeval start_time; 498 struct timeval start_time;
468 gettimeofday(&start_time, NULL); 499 gettimeofday(&start_time, NULL);
469 500
470 ExecArgs exec_args; 501 ExecArgs exec_args;
471 if (!exec_args.Init(args.GetIsolate(), args[0], command_args)) { 502 if (!exec_args.Init(args.GetIsolate(), args[0], command_args)) {
472 return; 503 return;
473 } 504 }
474 int exec_error_fds[2]; 505 int exec_error_fds[2];
475 int stdout_fds[2]; 506 int stdout_fds[2];
476 507
477 if (pipe(exec_error_fds) != 0) { 508 if (pipe(exec_error_fds) != 0) {
478 args.GetIsolate()->ThrowException( 509 args.GetIsolate()->ThrowException(
479 String::NewFromUtf8(args.GetIsolate(), "pipe syscall failed.")); 510 String::NewFromUtf8(args.GetIsolate(), "pipe syscall failed.",
511 NewStringType::kNormal).ToLocalChecked());
480 return; 512 return;
481 } 513 }
482 if (pipe(stdout_fds) != 0) { 514 if (pipe(stdout_fds) != 0) {
483 args.GetIsolate()->ThrowException( 515 args.GetIsolate()->ThrowException(
484 String::NewFromUtf8(args.GetIsolate(), "pipe syscall failed.")); 516 String::NewFromUtf8(args.GetIsolate(), "pipe syscall failed.",
517 NewStringType::kNormal).ToLocalChecked());
485 return; 518 return;
486 } 519 }
487 520
488 pid_t pid = fork(); 521 pid_t pid = fork();
489 if (pid == 0) { // Child process. 522 if (pid == 0) { // Child process.
490 ExecSubprocess(exec_error_fds, stdout_fds, exec_args); 523 ExecSubprocess(exec_error_fds, stdout_fds, exec_args);
491 exit(1); 524 exit(1);
492 } 525 }
493 526
494 // Parent process. Ensure that we clean up if we exit this function early. 527 // Parent process. Ensure that we clean up if we exit this function early.
495 ZombieProtector child_waiter(pid); 528 ZombieProtector child_waiter(pid);
496 close(exec_error_fds[kWriteFD]); 529 close(exec_error_fds[kWriteFD]);
497 close(stdout_fds[kWriteFD]); 530 close(stdout_fds[kWriteFD]);
498 OpenFDCloser error_read_closer(exec_error_fds[kReadFD]); 531 OpenFDCloser error_read_closer(exec_error_fds[kReadFD]);
499 OpenFDCloser stdout_read_closer(stdout_fds[kReadFD]); 532 OpenFDCloser stdout_read_closer(stdout_fds[kReadFD]);
500 533
501 if (!ChildLaunchedOK(args.GetIsolate(), exec_error_fds)) return; 534 if (!ChildLaunchedOK(args.GetIsolate(), exec_error_fds)) return;
502 535
503 Handle<Value> accumulator = GetStdout(args.GetIsolate(), 536 Local<Value> accumulator = GetStdout(args.GetIsolate(), stdout_fds[kReadFD],
504 stdout_fds[kReadFD], 537 start_time, read_timeout, total_timeout);
505 start_time,
506 read_timeout,
507 total_timeout);
508 if (accumulator->IsUndefined()) { 538 if (accumulator->IsUndefined()) {
509 kill(pid, SIGINT); // On timeout, kill the subprocess. 539 kill(pid, SIGINT); // On timeout, kill the subprocess.
510 args.GetReturnValue().Set(accumulator); 540 args.GetReturnValue().Set(accumulator);
511 return; 541 return;
512 } 542 }
513 543
514 if (!WaitForChild(args.GetIsolate(), 544 if (!WaitForChild(args.GetIsolate(),
515 pid, 545 pid,
516 child_waiter, 546 child_waiter,
517 start_time, 547 start_time,
518 read_timeout, 548 read_timeout,
519 total_timeout)) { 549 total_timeout)) {
520 return; 550 return;
521 } 551 }
522 552
523 args.GetReturnValue().Set(accumulator); 553 args.GetReturnValue().Set(accumulator);
524 } 554 }
525 555
526 556
527 void Shell::ChangeDirectory(const v8::FunctionCallbackInfo<v8::Value>& args) { 557 void Shell::ChangeDirectory(const v8::FunctionCallbackInfo<v8::Value>& args) {
528 if (args.Length() != 1) { 558 if (args.Length() != 1) {
529 const char* message = "chdir() takes one argument"; 559 const char* message = "chdir() takes one argument";
530 args.GetIsolate()->ThrowException( 560 args.GetIsolate()->ThrowException(
531 String::NewFromUtf8(args.GetIsolate(), message)); 561 String::NewFromUtf8(args.GetIsolate(), message, NewStringType::kNormal)
562 .ToLocalChecked());
532 return; 563 return;
533 } 564 }
534 String::Utf8Value directory(args[0]); 565 String::Utf8Value directory(args[0]);
535 if (*directory == NULL) { 566 if (*directory == NULL) {
536 const char* message = "os.chdir(): String conversion of argument failed."; 567 const char* message = "os.chdir(): String conversion of argument failed.";
537 args.GetIsolate()->ThrowException( 568 args.GetIsolate()->ThrowException(
538 String::NewFromUtf8(args.GetIsolate(), message)); 569 String::NewFromUtf8(args.GetIsolate(), message, NewStringType::kNormal)
570 .ToLocalChecked());
539 return; 571 return;
540 } 572 }
541 if (chdir(*directory) != 0) { 573 if (chdir(*directory) != 0) {
542 args.GetIsolate()->ThrowException( 574 args.GetIsolate()->ThrowException(
543 String::NewFromUtf8(args.GetIsolate(), strerror(errno))); 575 String::NewFromUtf8(args.GetIsolate(), strerror(errno),
576 NewStringType::kNormal).ToLocalChecked());
544 return; 577 return;
545 } 578 }
546 } 579 }
547 580
548 581
549 void Shell::SetUMask(const v8::FunctionCallbackInfo<v8::Value>& args) { 582 void Shell::SetUMask(const v8::FunctionCallbackInfo<v8::Value>& args) {
550 if (args.Length() != 1) { 583 if (args.Length() != 1) {
551 const char* message = "umask() takes one argument"; 584 const char* message = "umask() takes one argument";
552 args.GetIsolate()->ThrowException( 585 args.GetIsolate()->ThrowException(
553 String::NewFromUtf8(args.GetIsolate(), message)); 586 String::NewFromUtf8(args.GetIsolate(), message, NewStringType::kNormal)
587 .ToLocalChecked());
554 return; 588 return;
555 } 589 }
556 if (args[0]->IsNumber()) { 590 if (args[0]->IsNumber()) {
557 #if V8_OS_NACL 591 #if V8_OS_NACL
558 // PNaCL has no support for umask. 592 // PNaCL has no support for umask.
559 int previous = 0; 593 int previous = 0;
560 #else 594 #else
561 int previous = umask(args[0]->Int32Value()); 595 int previous = umask(
596 args[0]->Int32Value(args.GetIsolate()->GetCurrentContext()).FromJust());
562 #endif 597 #endif
563 args.GetReturnValue().Set(previous); 598 args.GetReturnValue().Set(previous);
564 return; 599 return;
565 } else { 600 } else {
566 const char* message = "umask() argument must be numeric"; 601 const char* message = "umask() argument must be numeric";
567 args.GetIsolate()->ThrowException( 602 args.GetIsolate()->ThrowException(
568 String::NewFromUtf8(args.GetIsolate(), message)); 603 String::NewFromUtf8(args.GetIsolate(), message, NewStringType::kNormal)
604 .ToLocalChecked());
569 return; 605 return;
570 } 606 }
571 } 607 }
572 608
573 609
574 static bool CheckItsADirectory(Isolate* isolate, char* directory) { 610 static bool CheckItsADirectory(Isolate* isolate, char* directory) {
575 struct stat stat_buf; 611 struct stat stat_buf;
576 int stat_result = stat(directory, &stat_buf); 612 int stat_result = stat(directory, &stat_buf);
577 if (stat_result != 0) { 613 if (stat_result != 0) {
578 isolate->ThrowException(String::NewFromUtf8(isolate, strerror(errno))); 614 isolate->ThrowException(
615 String::NewFromUtf8(isolate, strerror(errno), NewStringType::kNormal)
616 .ToLocalChecked());
579 return false; 617 return false;
580 } 618 }
581 if ((stat_buf.st_mode & S_IFDIR) != 0) return true; 619 if ((stat_buf.st_mode & S_IFDIR) != 0) return true;
582 isolate->ThrowException(String::NewFromUtf8(isolate, strerror(EEXIST))); 620 isolate->ThrowException(
621 String::NewFromUtf8(isolate, strerror(EEXIST), NewStringType::kNormal)
622 .ToLocalChecked());
583 return false; 623 return false;
584 } 624 }
585 625
586 626
587 // Returns true for success. Creates intermediate directories as needed. No 627 // Returns true for success. Creates intermediate directories as needed. No
588 // error if the directory exists already. 628 // error if the directory exists already.
589 static bool mkdirp(Isolate* isolate, char* directory, mode_t mask) { 629 static bool mkdirp(Isolate* isolate, char* directory, mode_t mask) {
590 int result = mkdir(directory, mask); 630 int result = mkdir(directory, mask);
591 if (result == 0) return true; 631 if (result == 0) return true;
592 if (errno == EEXIST) { 632 if (errno == EEXIST) {
593 return CheckItsADirectory(isolate, directory); 633 return CheckItsADirectory(isolate, directory);
594 } else if (errno == ENOENT) { // Intermediate path element is missing. 634 } else if (errno == ENOENT) { // Intermediate path element is missing.
595 char* last_slash = strrchr(directory, '/'); 635 char* last_slash = strrchr(directory, '/');
596 if (last_slash == NULL) { 636 if (last_slash == NULL) {
597 isolate->ThrowException(String::NewFromUtf8(isolate, strerror(errno))); 637 isolate->ThrowException(
638 String::NewFromUtf8(isolate, strerror(errno), NewStringType::kNormal)
639 .ToLocalChecked());
598 return false; 640 return false;
599 } 641 }
600 *last_slash = 0; 642 *last_slash = 0;
601 if (!mkdirp(isolate, directory, mask)) return false; 643 if (!mkdirp(isolate, directory, mask)) return false;
602 *last_slash = '/'; 644 *last_slash = '/';
603 result = mkdir(directory, mask); 645 result = mkdir(directory, mask);
604 if (result == 0) return true; 646 if (result == 0) return true;
605 if (errno == EEXIST) { 647 if (errno == EEXIST) {
606 return CheckItsADirectory(isolate, directory); 648 return CheckItsADirectory(isolate, directory);
607 } 649 }
608 isolate->ThrowException(String::NewFromUtf8(isolate, strerror(errno))); 650 isolate->ThrowException(
651 String::NewFromUtf8(isolate, strerror(errno), NewStringType::kNormal)
652 .ToLocalChecked());
609 return false; 653 return false;
610 } else { 654 } else {
611 isolate->ThrowException(String::NewFromUtf8(isolate, strerror(errno))); 655 isolate->ThrowException(
656 String::NewFromUtf8(isolate, strerror(errno), NewStringType::kNormal)
657 .ToLocalChecked());
612 return false; 658 return false;
613 } 659 }
614 } 660 }
615 661
616 662
617 void Shell::MakeDirectory(const v8::FunctionCallbackInfo<v8::Value>& args) { 663 void Shell::MakeDirectory(const v8::FunctionCallbackInfo<v8::Value>& args) {
618 mode_t mask = 0777; 664 mode_t mask = 0777;
619 if (args.Length() == 2) { 665 if (args.Length() == 2) {
620 if (args[1]->IsNumber()) { 666 if (args[1]->IsNumber()) {
621 mask = args[1]->Int32Value(); 667 mask = args[1]
668 ->Int32Value(args.GetIsolate()->GetCurrentContext())
669 .FromJust();
622 } else { 670 } else {
623 const char* message = "mkdirp() second argument must be numeric"; 671 const char* message = "mkdirp() second argument must be numeric";
624 args.GetIsolate()->ThrowException( 672 args.GetIsolate()->ThrowException(
625 String::NewFromUtf8(args.GetIsolate(), message)); 673 String::NewFromUtf8(args.GetIsolate(), message,
674 NewStringType::kNormal).ToLocalChecked());
626 return; 675 return;
627 } 676 }
628 } else if (args.Length() != 1) { 677 } else if (args.Length() != 1) {
629 const char* message = "mkdirp() takes one or two arguments"; 678 const char* message = "mkdirp() takes one or two arguments";
630 args.GetIsolate()->ThrowException( 679 args.GetIsolate()->ThrowException(
631 String::NewFromUtf8(args.GetIsolate(), message)); 680 String::NewFromUtf8(args.GetIsolate(), message, NewStringType::kNormal)
681 .ToLocalChecked());
632 return; 682 return;
633 } 683 }
634 String::Utf8Value directory(args[0]); 684 String::Utf8Value directory(args[0]);
635 if (*directory == NULL) { 685 if (*directory == NULL) {
636 const char* message = "os.mkdirp(): String conversion of argument failed."; 686 const char* message = "os.mkdirp(): String conversion of argument failed.";
637 args.GetIsolate()->ThrowException( 687 args.GetIsolate()->ThrowException(
638 String::NewFromUtf8(args.GetIsolate(), message)); 688 String::NewFromUtf8(args.GetIsolate(), message, NewStringType::kNormal)
689 .ToLocalChecked());
639 return; 690 return;
640 } 691 }
641 mkdirp(args.GetIsolate(), *directory, mask); 692 mkdirp(args.GetIsolate(), *directory, mask);
642 } 693 }
643 694
644 695
645 void Shell::RemoveDirectory(const v8::FunctionCallbackInfo<v8::Value>& args) { 696 void Shell::RemoveDirectory(const v8::FunctionCallbackInfo<v8::Value>& args) {
646 if (args.Length() != 1) { 697 if (args.Length() != 1) {
647 const char* message = "rmdir() takes one or two arguments"; 698 const char* message = "rmdir() takes one or two arguments";
648 args.GetIsolate()->ThrowException( 699 args.GetIsolate()->ThrowException(
649 String::NewFromUtf8(args.GetIsolate(), message)); 700 String::NewFromUtf8(args.GetIsolate(), message, NewStringType::kNormal)
701 .ToLocalChecked());
650 return; 702 return;
651 } 703 }
652 String::Utf8Value directory(args[0]); 704 String::Utf8Value directory(args[0]);
653 if (*directory == NULL) { 705 if (*directory == NULL) {
654 const char* message = "os.rmdir(): String conversion of argument failed."; 706 const char* message = "os.rmdir(): String conversion of argument failed.";
655 args.GetIsolate()->ThrowException( 707 args.GetIsolate()->ThrowException(
656 String::NewFromUtf8(args.GetIsolate(), message)); 708 String::NewFromUtf8(args.GetIsolate(), message, NewStringType::kNormal)
709 .ToLocalChecked());
657 return; 710 return;
658 } 711 }
659 rmdir(*directory); 712 rmdir(*directory);
660 } 713 }
661 714
662 715
663 void Shell::SetEnvironment(const v8::FunctionCallbackInfo<v8::Value>& args) { 716 void Shell::SetEnvironment(const v8::FunctionCallbackInfo<v8::Value>& args) {
664 if (args.Length() != 2) { 717 if (args.Length() != 2) {
665 const char* message = "setenv() takes two arguments"; 718 const char* message = "setenv() takes two arguments";
666 args.GetIsolate()->ThrowException( 719 args.GetIsolate()->ThrowException(
667 String::NewFromUtf8(args.GetIsolate(), message)); 720 String::NewFromUtf8(args.GetIsolate(), message, NewStringType::kNormal)
721 .ToLocalChecked());
668 return; 722 return;
669 } 723 }
670 String::Utf8Value var(args[0]); 724 String::Utf8Value var(args[0]);
671 String::Utf8Value value(args[1]); 725 String::Utf8Value value(args[1]);
672 if (*var == NULL) { 726 if (*var == NULL) {
673 const char* message = 727 const char* message =
674 "os.setenv(): String conversion of variable name failed."; 728 "os.setenv(): String conversion of variable name failed.";
675 args.GetIsolate()->ThrowException( 729 args.GetIsolate()->ThrowException(
676 String::NewFromUtf8(args.GetIsolate(), message)); 730 String::NewFromUtf8(args.GetIsolate(), message, NewStringType::kNormal)
731 .ToLocalChecked());
677 return; 732 return;
678 } 733 }
679 if (*value == NULL) { 734 if (*value == NULL) {
680 const char* message = 735 const char* message =
681 "os.setenv(): String conversion of variable contents failed."; 736 "os.setenv(): String conversion of variable contents failed.";
682 args.GetIsolate()->ThrowException( 737 args.GetIsolate()->ThrowException(
683 String::NewFromUtf8(args.GetIsolate(), message)); 738 String::NewFromUtf8(args.GetIsolate(), message, NewStringType::kNormal)
739 .ToLocalChecked());
684 return; 740 return;
685 } 741 }
686 setenv(*var, *value, 1); 742 setenv(*var, *value, 1);
687 } 743 }
688 744
689 745
690 void Shell::UnsetEnvironment(const v8::FunctionCallbackInfo<v8::Value>& args) { 746 void Shell::UnsetEnvironment(const v8::FunctionCallbackInfo<v8::Value>& args) {
691 if (args.Length() != 1) { 747 if (args.Length() != 1) {
692 const char* message = "unsetenv() takes one argument"; 748 const char* message = "unsetenv() takes one argument";
693 args.GetIsolate()->ThrowException( 749 args.GetIsolate()->ThrowException(
694 String::NewFromUtf8(args.GetIsolate(), message)); 750 String::NewFromUtf8(args.GetIsolate(), message, NewStringType::kNormal)
751 .ToLocalChecked());
695 return; 752 return;
696 } 753 }
697 String::Utf8Value var(args[0]); 754 String::Utf8Value var(args[0]);
698 if (*var == NULL) { 755 if (*var == NULL) {
699 const char* message = 756 const char* message =
700 "os.setenv(): String conversion of variable name failed."; 757 "os.setenv(): String conversion of variable name failed.";
701 args.GetIsolate()->ThrowException( 758 args.GetIsolate()->ThrowException(
702 String::NewFromUtf8(args.GetIsolate(), message)); 759 String::NewFromUtf8(args.GetIsolate(), message, NewStringType::kNormal)
760 .ToLocalChecked());
703 return; 761 return;
704 } 762 }
705 unsetenv(*var); 763 unsetenv(*var);
706 } 764 }
707 765
708 766
709 void Shell::AddOSMethods(Isolate* isolate, Handle<ObjectTemplate> os_templ) { 767 void Shell::AddOSMethods(Isolate* isolate, Local<ObjectTemplate> os_templ) {
710 os_templ->Set(String::NewFromUtf8(isolate, "system"), 768 os_templ->Set(String::NewFromUtf8(isolate, "system", NewStringType::kNormal)
769 .ToLocalChecked(),
711 FunctionTemplate::New(isolate, System)); 770 FunctionTemplate::New(isolate, System));
712 os_templ->Set(String::NewFromUtf8(isolate, "chdir"), 771 os_templ->Set(String::NewFromUtf8(isolate, "chdir", NewStringType::kNormal)
772 .ToLocalChecked(),
713 FunctionTemplate::New(isolate, ChangeDirectory)); 773 FunctionTemplate::New(isolate, ChangeDirectory));
714 os_templ->Set(String::NewFromUtf8(isolate, "setenv"), 774 os_templ->Set(String::NewFromUtf8(isolate, "setenv", NewStringType::kNormal)
775 .ToLocalChecked(),
715 FunctionTemplate::New(isolate, SetEnvironment)); 776 FunctionTemplate::New(isolate, SetEnvironment));
716 os_templ->Set(String::NewFromUtf8(isolate, "unsetenv"), 777 os_templ->Set(String::NewFromUtf8(isolate, "unsetenv", NewStringType::kNormal)
778 .ToLocalChecked(),
717 FunctionTemplate::New(isolate, UnsetEnvironment)); 779 FunctionTemplate::New(isolate, UnsetEnvironment));
718 os_templ->Set(String::NewFromUtf8(isolate, "umask"), 780 os_templ->Set(String::NewFromUtf8(isolate, "umask", NewStringType::kNormal)
781 .ToLocalChecked(),
719 FunctionTemplate::New(isolate, SetUMask)); 782 FunctionTemplate::New(isolate, SetUMask));
720 os_templ->Set(String::NewFromUtf8(isolate, "mkdirp"), 783 os_templ->Set(String::NewFromUtf8(isolate, "mkdirp", NewStringType::kNormal)
784 .ToLocalChecked(),
721 FunctionTemplate::New(isolate, MakeDirectory)); 785 FunctionTemplate::New(isolate, MakeDirectory));
722 os_templ->Set(String::NewFromUtf8(isolate, "rmdir"), 786 os_templ->Set(String::NewFromUtf8(isolate, "rmdir", NewStringType::kNormal)
787 .ToLocalChecked(),
723 FunctionTemplate::New(isolate, RemoveDirectory)); 788 FunctionTemplate::New(isolate, RemoveDirectory));
724 } 789 }
725 790
726 } // namespace v8 791 } // namespace v8
OLDNEW
« no previous file with comments | « src/d8-debug.cc ('k') | src/d8-readline.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698