v8  3.11.10(node0.8.26)
V8 is Google's open source JavaScript engine
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
d8-posix.cc
Go to the documentation of this file.
1 // Copyright 2009 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
4 // met:
5 //
6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided
11 // with the distribution.
12 // * Neither the name of Google Inc. nor the names of its
13 // contributors may be used to endorse or promote products derived
14 // from this software without specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 
28 
29 #include <stdlib.h>
30 #include <errno.h>
31 #include <sys/types.h>
32 #include <sys/stat.h>
33 #include <sys/time.h>
34 #include <time.h>
35 #include <unistd.h>
36 #include <fcntl.h>
37 #include <sys/wait.h>
38 #include <signal.h>
39 
40 
41 #include "d8.h"
42 #include "d8-debug.h"
43 #include "debug.h"
44 
45 
46 namespace v8 {
47 
48 
49 // If the buffer ends in the middle of a UTF-8 sequence then we return
50 // the length of the string up to but not including the incomplete UTF-8
51 // sequence. If the buffer ends with a valid UTF-8 sequence then we
52 // return the whole buffer.
53 static int LengthWithoutIncompleteUtf8(char* buffer, int len) {
54  int answer = len;
55  // 1-byte encoding.
56  static const int kUtf8SingleByteMask = 0x80;
57  static const int kUtf8SingleByteValue = 0x00;
58  // 2-byte encoding.
59  static const int kUtf8TwoByteMask = 0xe0;
60  static const int kUtf8TwoByteValue = 0xc0;
61  // 3-byte encoding.
62  static const int kUtf8ThreeByteMask = 0xf0;
63  static const int kUtf8ThreeByteValue = 0xe0;
64  // 4-byte encoding.
65  static const int kUtf8FourByteMask = 0xf8;
66  static const int kUtf8FourByteValue = 0xf0;
67  // Subsequent bytes of a multi-byte encoding.
68  static const int kMultiByteMask = 0xc0;
69  static const int kMultiByteValue = 0x80;
70  int multi_byte_bytes_seen = 0;
71  while (answer > 0) {
72  int c = buffer[answer - 1];
73  // Ends in valid single-byte sequence?
74  if ((c & kUtf8SingleByteMask) == kUtf8SingleByteValue) return answer;
75  // Ends in one or more subsequent bytes of a multi-byte value?
76  if ((c & kMultiByteMask) == kMultiByteValue) {
77  multi_byte_bytes_seen++;
78  answer--;
79  } else {
80  if ((c & kUtf8TwoByteMask) == kUtf8TwoByteValue) {
81  if (multi_byte_bytes_seen >= 1) {
82  return answer + 2;
83  }
84  return answer - 1;
85  } else if ((c & kUtf8ThreeByteMask) == kUtf8ThreeByteValue) {
86  if (multi_byte_bytes_seen >= 2) {
87  return answer + 3;
88  }
89  return answer - 1;
90  } else if ((c & kUtf8FourByteMask) == kUtf8FourByteValue) {
91  if (multi_byte_bytes_seen >= 3) {
92  return answer + 4;
93  }
94  return answer - 1;
95  } else {
96  return answer; // Malformed UTF-8.
97  }
98  }
99  }
100  return 0;
101 }
102 
103 
104 // Suspends the thread until there is data available from the child process.
105 // Returns false on timeout, true on data ready.
106 static bool WaitOnFD(int fd,
107  int read_timeout,
108  int total_timeout,
109  struct timeval& start_time) {
110  fd_set readfds, writefds, exceptfds;
111  struct timeval timeout;
112  int gone = 0;
113  if (total_timeout != -1) {
114  struct timeval time_now;
115  gettimeofday(&time_now, NULL);
116  int seconds = time_now.tv_sec - start_time.tv_sec;
117  gone = seconds * 1000 + (time_now.tv_usec - start_time.tv_usec) / 1000;
118  if (gone >= total_timeout) return false;
119  }
120  FD_ZERO(&readfds);
121  FD_ZERO(&writefds);
122  FD_ZERO(&exceptfds);
123  FD_SET(fd, &readfds);
124  FD_SET(fd, &exceptfds);
125  if (read_timeout == -1 ||
126  (total_timeout != -1 && total_timeout - gone < read_timeout)) {
127  read_timeout = total_timeout - gone;
128  }
129  timeout.tv_usec = (read_timeout % 1000) * 1000;
130  timeout.tv_sec = read_timeout / 1000;
131  int number_of_fds_ready = select(fd + 1,
132  &readfds,
133  &writefds,
134  &exceptfds,
135  read_timeout != -1 ? &timeout : NULL);
136  return number_of_fds_ready == 1;
137 }
138 
139 
140 // Checks whether we ran out of time on the timeout. Returns true if we ran out
141 // of time, false if we still have time.
142 static bool TimeIsOut(const struct timeval& start_time, const int& total_time) {
143  if (total_time == -1) return false;
144  struct timeval time_now;
145  gettimeofday(&time_now, NULL);
146  // Careful about overflow.
147  int seconds = time_now.tv_sec - start_time.tv_sec;
148  if (seconds > 100) {
149  if (seconds * 1000 > total_time) return true;
150  return false;
151  }
152  int useconds = time_now.tv_usec - start_time.tv_usec;
153  if (seconds * 1000000 + useconds > total_time * 1000) {
154  return true;
155  }
156  return false;
157 }
158 
159 
160 // A utility class that does a non-hanging waitpid on the child process if we
161 // bail out of the System() function early. If you don't ever do a waitpid on
162 // a subprocess then it turns into one of those annoying 'zombie processes'.
164  public:
165  explicit ZombieProtector(int pid): pid_(pid) { }
166  ~ZombieProtector() { if (pid_ != 0) waitpid(pid_, NULL, 0); }
167  void ChildIsDeadNow() { pid_ = 0; }
168  private:
169  int pid_;
170 };
171 
172 
173 // A utility class that closes a file descriptor when it goes out of scope.
175  public:
176  explicit OpenFDCloser(int fd): fd_(fd) { }
177  ~OpenFDCloser() { close(fd_); }
178  private:
179  int fd_;
180 };
181 
182 
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
185 // scope.
186 class ExecArgs {
187  public:
189  exec_args_[0] = NULL;
190  }
191  bool Init(Handle<Value> arg0, Handle<Array> command_args) {
192  String::Utf8Value prog(arg0);
193  if (*prog == NULL) {
194  const char* message =
195  "os.system(): String conversion of program name failed";
196  ThrowException(String::New(message));
197  return false;
198  }
199  int len = prog.length() + 3;
200  char* c_arg = new char[len];
201  snprintf(c_arg, len, "%s", *prog);
202  exec_args_[0] = c_arg;
203  int i = 1;
204  for (unsigned j = 0; j < command_args->Length(); i++, j++) {
205  Handle<Value> arg(command_args->Get(Integer::New(j)));
206  String::Utf8Value utf8_arg(arg);
207  if (*utf8_arg == NULL) {
208  exec_args_[i] = NULL; // Consistent state for destructor.
209  const char* message =
210  "os.system(): String conversion of argument failed.";
211  ThrowException(String::New(message));
212  return false;
213  }
214  int len = utf8_arg.length() + 1;
215  char* c_arg = new char[len];
216  snprintf(c_arg, len, "%s", *utf8_arg);
217  exec_args_[i] = c_arg;
218  }
219  exec_args_[i] = NULL;
220  return true;
221  }
223  for (unsigned i = 0; i < kMaxArgs; i++) {
224  if (exec_args_[i] == NULL) {
225  return;
226  }
227  delete [] exec_args_[i];
228  exec_args_[i] = 0;
229  }
230  }
231  static const unsigned kMaxArgs = 1000;
232  char** arg_array() { return exec_args_; }
233  char* arg0() { return exec_args_[0]; }
234 
235  private:
236  char* exec_args_[kMaxArgs + 1];
237 };
238 
239 
240 // Gets the optional timeouts from the arguments to the system() call.
241 static bool GetTimeouts(const Arguments& args,
242  int* read_timeout,
243  int* total_timeout) {
244  if (args.Length() > 3) {
245  if (args[3]->IsNumber()) {
246  *total_timeout = args[3]->Int32Value();
247  } else {
248  ThrowException(String::New("system: Argument 4 must be a number"));
249  return false;
250  }
251  }
252  if (args.Length() > 2) {
253  if (args[2]->IsNumber()) {
254  *read_timeout = args[2]->Int32Value();
255  } else {
256  ThrowException(String::New("system: Argument 3 must be a number"));
257  return false;
258  }
259  }
260  return true;
261 }
262 
263 
264 static const int kReadFD = 0;
265 static const int kWriteFD = 1;
266 
267 
268 // This is run in the child process after fork() but before exec(). It normally
269 // ends with the child process being replaced with the desired child program.
270 // It only returns if an error occurred.
271 static void ExecSubprocess(int* exec_error_fds,
272  int* stdout_fds,
273  ExecArgs& exec_args) {
274  close(exec_error_fds[kReadFD]); // Don't need this in the child.
275  close(stdout_fds[kReadFD]); // Don't need this in the child.
276  close(1); // Close stdout.
277  dup2(stdout_fds[kWriteFD], 1); // Dup pipe fd to stdout.
278  close(stdout_fds[kWriteFD]); // Don't need the original fd now.
279  fcntl(exec_error_fds[kWriteFD], F_SETFD, FD_CLOEXEC);
280  execvp(exec_args.arg0(), exec_args.arg_array());
281  // Only get here if the exec failed. Write errno to the parent to tell
282  // them it went wrong. If it went well the pipe is closed.
283  int err = errno;
284  int bytes_written;
285  do {
286  bytes_written = write(exec_error_fds[kWriteFD], &err, sizeof(err));
287  } while (bytes_written == -1 && errno == EINTR);
288  // Return (and exit child process).
289 }
290 
291 
292 // Runs in the parent process. Checks that the child was able to exec (closing
293 // the file desriptor), or reports an error if it failed.
294 static bool ChildLaunchedOK(int* exec_error_fds) {
295  int bytes_read;
296  int err;
297  do {
298  bytes_read = read(exec_error_fds[kReadFD], &err, sizeof(err));
299  } while (bytes_read == -1 && errno == EINTR);
300  if (bytes_read != 0) {
301  ThrowException(String::New(strerror(err)));
302  return false;
303  }
304  return true;
305 }
306 
307 
308 // Accumulates the output from the child in a string handle. Returns true if it
309 // succeeded or false if an exception was thrown.
310 static Handle<Value> GetStdout(int child_fd,
311  struct timeval& start_time,
312  int read_timeout,
313  int total_timeout) {
314  Handle<String> accumulator = String::Empty();
315 
316  int fullness = 0;
317  static const int kStdoutReadBufferSize = 4096;
318  char buffer[kStdoutReadBufferSize];
319 
320  if (fcntl(child_fd, F_SETFL, O_NONBLOCK) != 0) {
321  return ThrowException(String::New(strerror(errno)));
322  }
323 
324  int bytes_read;
325  do {
326  bytes_read = read(child_fd,
327  buffer + fullness,
328  kStdoutReadBufferSize - fullness);
329  if (bytes_read == -1) {
330  if (errno == EAGAIN) {
331  if (!WaitOnFD(child_fd,
332  read_timeout,
333  total_timeout,
334  start_time) ||
335  (TimeIsOut(start_time, total_timeout))) {
336  return ThrowException(String::New("Timed out waiting for output"));
337  }
338  continue;
339  } else if (errno == EINTR) {
340  continue;
341  } else {
342  break;
343  }
344  }
345  if (bytes_read + fullness > 0) {
346  int length = bytes_read == 0 ?
347  bytes_read + fullness :
348  LengthWithoutIncompleteUtf8(buffer, bytes_read + fullness);
349  Handle<String> addition = String::New(buffer, length);
350  accumulator = String::Concat(accumulator, addition);
351  fullness = bytes_read + fullness - length;
352  memcpy(buffer, buffer + length, fullness);
353  }
354  } while (bytes_read != 0);
355  return accumulator;
356 }
357 
358 
359 // Modern Linux has the waitid call, which is like waitpid, but more useful
360 // if you want a timeout. If we don't have waitid we can't limit the time
361 // waiting for the process to exit without losing the information about
362 // whether it exited normally. In the common case this doesn't matter because
363 // we don't get here before the child has closed stdout and most programs don't
364 // do that before they exit.
365 //
366 // We're disabling usage of waitid in Mac OS X because it doens't work for us:
367 // a parent process hangs on waiting while a child process is already a zombie.
368 // See http://code.google.com/p/v8/issues/detail?id=401.
369 #if defined(WNOWAIT) && !defined(ANDROID) && !defined(__APPLE__) \
370  && !defined(__NetBSD__)
371 #if !defined(__FreeBSD__)
372 #define HAS_WAITID 1
373 #endif
374 #endif
375 
376 
377 // Get exit status of child.
378 static bool WaitForChild(int pid,
379  ZombieProtector& child_waiter,
380  struct timeval& start_time,
381  int read_timeout,
382  int total_timeout) {
383 #ifdef HAS_WAITID
384 
385  siginfo_t child_info;
386  child_info.si_pid = 0;
387  int useconds = 1;
388  // Wait for child to exit.
389  while (child_info.si_pid == 0) {
390  waitid(P_PID, pid, &child_info, WEXITED | WNOHANG | WNOWAIT);
391  usleep(useconds);
392  if (useconds < 1000000) useconds <<= 1;
393  if ((read_timeout != -1 && useconds / 1000 > read_timeout) ||
394  (TimeIsOut(start_time, total_timeout))) {
395  ThrowException(String::New("Timed out waiting for process to terminate"));
396  kill(pid, SIGINT);
397  return false;
398  }
399  }
400  if (child_info.si_code == CLD_KILLED) {
401  char message[999];
402  snprintf(message,
403  sizeof(message),
404  "Child killed by signal %d",
405  child_info.si_status);
406  ThrowException(String::New(message));
407  return false;
408  }
409  if (child_info.si_code == CLD_EXITED && child_info.si_status != 0) {
410  char message[999];
411  snprintf(message,
412  sizeof(message),
413  "Child exited with status %d",
414  child_info.si_status);
415  ThrowException(String::New(message));
416  return false;
417  }
418 
419 #else // No waitid call.
420 
421  int child_status;
422  waitpid(pid, &child_status, 0); // We hang here if the child doesn't exit.
423  child_waiter.ChildIsDeadNow();
424  if (WIFSIGNALED(child_status)) {
425  char message[999];
426  snprintf(message,
427  sizeof(message),
428  "Child killed by signal %d",
429  WTERMSIG(child_status));
430  ThrowException(String::New(message));
431  return false;
432  }
433  if (WEXITSTATUS(child_status) != 0) {
434  char message[999];
435  int exit_status = WEXITSTATUS(child_status);
436  snprintf(message,
437  sizeof(message),
438  "Child exited with status %d",
439  exit_status);
440  ThrowException(String::New(message));
441  return false;
442  }
443 
444 #endif // No waitid call.
445 
446  return true;
447 }
448 
449 
450 // Implementation of the system() function (see d8.h for details).
452  HandleScope scope;
453  int read_timeout = -1;
454  int total_timeout = -1;
455  if (!GetTimeouts(args, &read_timeout, &total_timeout)) return v8::Undefined();
456  Handle<Array> command_args;
457  if (args.Length() > 1) {
458  if (!args[1]->IsArray()) {
459  return ThrowException(String::New("system: Argument 2 must be an array"));
460  }
461  command_args = Handle<Array>::Cast(args[1]);
462  } else {
463  command_args = Array::New(0);
464  }
465  if (command_args->Length() > ExecArgs::kMaxArgs) {
466  return ThrowException(String::New("Too many arguments to system()"));
467  }
468  if (args.Length() < 1) {
469  return ThrowException(String::New("Too few arguments to system()"));
470  }
471 
472  struct timeval start_time;
473  gettimeofday(&start_time, NULL);
474 
475  ExecArgs exec_args;
476  if (!exec_args.Init(args[0], command_args)) {
477  return v8::Undefined();
478  }
479  int exec_error_fds[2];
480  int stdout_fds[2];
481 
482  if (pipe(exec_error_fds) != 0) {
483  return ThrowException(String::New("pipe syscall failed."));
484  }
485  if (pipe(stdout_fds) != 0) {
486  return ThrowException(String::New("pipe syscall failed."));
487  }
488 
489  pid_t pid = fork();
490  if (pid == 0) { // Child process.
491  ExecSubprocess(exec_error_fds, stdout_fds, exec_args);
492  exit(1);
493  }
494 
495  // Parent process. Ensure that we clean up if we exit this function early.
496  ZombieProtector child_waiter(pid);
497  close(exec_error_fds[kWriteFD]);
498  close(stdout_fds[kWriteFD]);
499  OpenFDCloser error_read_closer(exec_error_fds[kReadFD]);
500  OpenFDCloser stdout_read_closer(stdout_fds[kReadFD]);
501 
502  if (!ChildLaunchedOK(exec_error_fds)) return v8::Undefined();
503 
504  Handle<Value> accumulator = GetStdout(stdout_fds[kReadFD],
505  start_time,
506  read_timeout,
507  total_timeout);
508  if (accumulator->IsUndefined()) {
509  kill(pid, SIGINT); // On timeout, kill the subprocess.
510  return accumulator;
511  }
512 
513  if (!WaitForChild(pid,
514  child_waiter,
515  start_time,
516  read_timeout,
517  total_timeout)) {
518  return v8::Undefined();
519  }
520 
521  return scope.Close(accumulator);
522 }
523 
524 
526  if (args.Length() != 1) {
527  const char* message = "chdir() takes one argument";
528  return ThrowException(String::New(message));
529  }
530  String::Utf8Value directory(args[0]);
531  if (*directory == NULL) {
532  const char* message = "os.chdir(): String conversion of argument failed.";
533  return ThrowException(String::New(message));
534  }
535  if (chdir(*directory) != 0) {
536  return ThrowException(String::New(strerror(errno)));
537  }
538  return v8::Undefined();
539 }
540 
541 
543  if (args.Length() != 1) {
544  const char* message = "umask() takes one argument";
545  return ThrowException(String::New(message));
546  }
547  if (args[0]->IsNumber()) {
548  mode_t mask = args[0]->Int32Value();
549  int previous = umask(mask);
550  return Number::New(previous);
551  } else {
552  const char* message = "umask() argument must be numeric";
553  return ThrowException(String::New(message));
554  }
555 }
556 
557 
558 static bool CheckItsADirectory(char* directory) {
559  struct stat stat_buf;
560  int stat_result = stat(directory, &stat_buf);
561  if (stat_result != 0) {
562  ThrowException(String::New(strerror(errno)));
563  return false;
564  }
565  if ((stat_buf.st_mode & S_IFDIR) != 0) return true;
566  ThrowException(String::New(strerror(EEXIST)));
567  return false;
568 }
569 
570 
571 // Returns true for success. Creates intermediate directories as needed. No
572 // error if the directory exists already.
573 static bool mkdirp(char* directory, mode_t mask) {
574  int result = mkdir(directory, mask);
575  if (result == 0) return true;
576  if (errno == EEXIST) {
577  return CheckItsADirectory(directory);
578  } else if (errno == ENOENT) { // Intermediate path element is missing.
579  char* last_slash = strrchr(directory, '/');
580  if (last_slash == NULL) {
581  ThrowException(String::New(strerror(errno)));
582  return false;
583  }
584  *last_slash = 0;
585  if (!mkdirp(directory, mask)) return false;
586  *last_slash = '/';
587  result = mkdir(directory, mask);
588  if (result == 0) return true;
589  if (errno == EEXIST) {
590  return CheckItsADirectory(directory);
591  }
592  ThrowException(String::New(strerror(errno)));
593  return false;
594  } else {
595  ThrowException(String::New(strerror(errno)));
596  return false;
597  }
598 }
599 
600 
602  mode_t mask = 0777;
603  if (args.Length() == 2) {
604  if (args[1]->IsNumber()) {
605  mask = args[1]->Int32Value();
606  } else {
607  const char* message = "mkdirp() second argument must be numeric";
608  return ThrowException(String::New(message));
609  }
610  } else if (args.Length() != 1) {
611  const char* message = "mkdirp() takes one or two arguments";
612  return ThrowException(String::New(message));
613  }
614  String::Utf8Value directory(args[0]);
615  if (*directory == NULL) {
616  const char* message = "os.mkdirp(): String conversion of argument failed.";
617  return ThrowException(String::New(message));
618  }
619  mkdirp(*directory, mask);
620  return v8::Undefined();
621 }
622 
623 
625  if (args.Length() != 1) {
626  const char* message = "rmdir() takes one or two arguments";
627  return ThrowException(String::New(message));
628  }
629  String::Utf8Value directory(args[0]);
630  if (*directory == NULL) {
631  const char* message = "os.rmdir(): String conversion of argument failed.";
632  return ThrowException(String::New(message));
633  }
634  rmdir(*directory);
635  return v8::Undefined();
636 }
637 
638 
640  if (args.Length() != 2) {
641  const char* message = "setenv() takes two arguments";
642  return ThrowException(String::New(message));
643  }
644  String::Utf8Value var(args[0]);
645  String::Utf8Value value(args[1]);
646  if (*var == NULL) {
647  const char* message =
648  "os.setenv(): String conversion of variable name failed.";
649  return ThrowException(String::New(message));
650  }
651  if (*value == NULL) {
652  const char* message =
653  "os.setenv(): String conversion of variable contents failed.";
654  return ThrowException(String::New(message));
655  }
656  setenv(*var, *value, 1);
657  return v8::Undefined();
658 }
659 
660 
662  if (args.Length() != 1) {
663  const char* message = "unsetenv() takes one argument";
664  return ThrowException(String::New(message));
665  }
666  String::Utf8Value var(args[0]);
667  if (*var == NULL) {
668  const char* message =
669  "os.setenv(): String conversion of variable name failed.";
670  return ThrowException(String::New(message));
671  }
672  unsetenv(*var);
673  return v8::Undefined();
674 }
675 
676 
678  os_templ->Set(String::New("system"), FunctionTemplate::New(System));
680  os_templ->Set(String::New("setenv"), FunctionTemplate::New(SetEnvironment));
681  os_templ->Set(String::New("unsetenv"),
683  os_templ->Set(String::New("umask"), FunctionTemplate::New(SetUMask));
684  os_templ->Set(String::New("mkdirp"), FunctionTemplate::New(MakeDirectory));
686 }
687 
688 } // namespace v8
static Local< FunctionTemplate > New(InvocationCallback callback=0, Handle< Value > data=Handle< Value >(), Handle< Signature > signature=Handle< Signature >())
Definition: api.cc:943
bool Init(Handle< Value > arg0, Handle< Array > command_args)
Definition: d8-posix.cc:191
ZombieProtector(int pid)
Definition: d8-posix.cc:165
static V8EXPORT Local< String > New(const char *data, int length=-1)
Definition: api.cc:4655
static Handle< Value > SetUMask(const Arguments &args)
Definition: d8-posix.cc:542
static void AddOSMethods(Handle< ObjectTemplate > os_template)
Definition: d8-posix.cc:677
static Handle< T > Cast(Handle< S > that)
Definition: v8.h:243
char * arg0()
Definition: d8-posix.cc:233
void Set(Handle< String > name, Handle< Data > value, PropertyAttribute attributes=None)
Definition: api.cc:894
static Handle< Value > SetEnvironment(const Arguments &args)
Definition: d8-posix.cc:639
activate correct semantics for inheriting readonliness enable harmony semantics for typeof enable harmony enable harmony proxies enable all harmony harmony_scoping harmony_proxies harmony_scoping tracks arrays with only smi values automatically unbox arrays of doubles use crankshaft use hydrogen range analysis use hydrogen global value numbering use function inlining maximum number of AST nodes considered for a single inlining loop invariant code motion print statistics for hydrogen trace generated IR for specified phases trace register allocator trace range analysis trace representation types environment for every instruction put a break point before deoptimizing polymorphic inlining perform array bounds checks elimination trace on stack replacement optimize closures functions with arguments object optimize functions containing for in loops profiler considers IC stability primitive functions trigger their own optimization re try self optimization if it failed insert an interrupt check at function exit execution budget before interrupt is triggered call count before self optimization self_optimization count_based_interrupts weighted_back_edges trace_opt emit comments in code disassembly enable use of SSE3 instructions if available enable use of CMOV instruction if available enable use of SAHF instruction if enable use of VFP3 instructions if available this implies enabling ARMv7 enable use of ARMv7 instructions if enable use of MIPS FPU instructions if NULL
int Length() const
Definition: v8.h:4143
bool IsUndefined() const
Definition: v8.h:4277
static Handle< Value > RemoveDirectory(const Arguments &args)
Definition: d8-posix.cc:624
static V8EXPORT v8::Local< v8::String > Empty()
Definition: api.cc:4645
static Handle< Value > UnsetEnvironment(const Arguments &args)
Definition: d8-posix.cc:661
int length() const
Definition: v8.h:1288
static V8EXPORT Local< Integer > New(int32_t value)
Definition: api.cc:5100
Local< T > Close(Handle< T > value)
Definition: v8.h:4149
Handle< Primitive > V8EXPORT Undefined()
Definition: api.cc:546
static V8EXPORT Local< Number > New(double value)
Definition: api.cc:5087
static V8EXPORT Local< String > Concat(Handle< String > left, Handle< String > right)
Definition: api.cc:4669
OpenFDCloser(int fd)
Definition: d8-posix.cc:176
static Handle< Value > MakeDirectory(const Arguments &args)
Definition: d8-posix.cc:601
char ** arg_array()
Definition: d8-posix.cc:232
Handle< Value > V8EXPORT ThrowException(Handle< Value > exception)
Definition: api.cc:485
static Handle< Value > System(const Arguments &args)
Definition: d8-posix.cc:451
static Handle< Value > ChangeDirectory(const Arguments &args)
Definition: d8-posix.cc:525
static V8EXPORT Local< Object > New()
Definition: api.cc:4829
static const unsigned kMaxArgs
Definition: d8-posix.cc:231