| OLD | NEW |
| 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 | 5 |
| 6 #include <stdlib.h> | 6 #include <stdlib.h> |
| 7 #include <errno.h> | 7 #include <errno.h> |
| 8 #include <sys/types.h> | 8 #include <sys/types.h> |
| 9 #include <sys/stat.h> | 9 #include <sys/stat.h> |
| 10 #include <sys/time.h> | 10 #include <sys/time.h> |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 76 } | 76 } |
| 77 return 0; | 77 return 0; |
| 78 } | 78 } |
| 79 | 79 |
| 80 | 80 |
| 81 // Suspends the thread until there is data available from the child process. | 81 // Suspends the thread until there is data available from the child process. |
| 82 // Returns false on timeout, true on data ready. | 82 // Returns false on timeout, true on data ready. |
| 83 static bool WaitOnFD(int fd, | 83 static bool WaitOnFD(int fd, |
| 84 int read_timeout, | 84 int read_timeout, |
| 85 int total_timeout, | 85 int total_timeout, |
| 86 struct timeval& start_time) { | 86 const struct timeval& start_time) { |
| 87 fd_set readfds, writefds, exceptfds; | 87 fd_set readfds, writefds, exceptfds; |
| 88 struct timeval timeout; | 88 struct timeval timeout; |
| 89 int gone = 0; | 89 int gone = 0; |
| 90 if (total_timeout != -1) { | 90 if (total_timeout != -1) { |
| 91 struct timeval time_now; | 91 struct timeval time_now; |
| 92 gettimeofday(&time_now, NULL); | 92 gettimeofday(&time_now, NULL); |
| 93 int seconds = time_now.tv_sec - start_time.tv_sec; | 93 int seconds = time_now.tv_sec - start_time.tv_sec; |
| 94 gone = seconds * 1000 + (time_now.tv_usec - start_time.tv_usec) / 1000; | 94 gone = seconds * 1000 + (time_now.tv_usec - start_time.tv_usec) / 1000; |
| 95 if (gone >= total_timeout) return false; | 95 if (gone >= total_timeout) return false; |
| 96 } | 96 } |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 199 ~ExecArgs() { | 199 ~ExecArgs() { |
| 200 for (unsigned i = 0; i < kMaxArgs; i++) { | 200 for (unsigned i = 0; i < kMaxArgs; i++) { |
| 201 if (exec_args_[i] == NULL) { | 201 if (exec_args_[i] == NULL) { |
| 202 return; | 202 return; |
| 203 } | 203 } |
| 204 delete [] exec_args_[i]; | 204 delete [] exec_args_[i]; |
| 205 exec_args_[i] = 0; | 205 exec_args_[i] = 0; |
| 206 } | 206 } |
| 207 } | 207 } |
| 208 static const unsigned kMaxArgs = 1000; | 208 static const unsigned kMaxArgs = 1000; |
| 209 char** arg_array() { return exec_args_; } | 209 char* const* arg_array() const { return exec_args_; } |
| 210 char* arg0() { return exec_args_[0]; } | 210 const char* arg0() const { return exec_args_[0]; } |
| 211 | 211 |
| 212 private: | 212 private: |
| 213 char* exec_args_[kMaxArgs + 1]; | 213 char* exec_args_[kMaxArgs + 1]; |
| 214 }; | 214 }; |
| 215 | 215 |
| 216 | 216 |
| 217 // Gets the optional timeouts from the arguments to the system() call. | 217 // Gets the optional timeouts from the arguments to the system() call. |
| 218 static bool GetTimeouts(const v8::FunctionCallbackInfo<v8::Value>& args, | 218 static bool GetTimeouts(const v8::FunctionCallbackInfo<v8::Value>& args, |
| 219 int* read_timeout, | 219 int* read_timeout, |
| 220 int* total_timeout) { | 220 int* total_timeout) { |
| (...skipping 21 matching lines...) Expand all Loading... |
| 242 | 242 |
| 243 static const int kReadFD = 0; | 243 static const int kReadFD = 0; |
| 244 static const int kWriteFD = 1; | 244 static const int kWriteFD = 1; |
| 245 | 245 |
| 246 | 246 |
| 247 // This is run in the child process after fork() but before exec(). It normally | 247 // This is run in the child process after fork() but before exec(). It normally |
| 248 // ends with the child process being replaced with the desired child program. | 248 // ends with the child process being replaced with the desired child program. |
| 249 // It only returns if an error occurred. | 249 // It only returns if an error occurred. |
| 250 static void ExecSubprocess(int* exec_error_fds, | 250 static void ExecSubprocess(int* exec_error_fds, |
| 251 int* stdout_fds, | 251 int* stdout_fds, |
| 252 ExecArgs& exec_args) { | 252 const ExecArgs& exec_args) { |
| 253 close(exec_error_fds[kReadFD]); // Don't need this in the child. | 253 close(exec_error_fds[kReadFD]); // Don't need this in the child. |
| 254 close(stdout_fds[kReadFD]); // Don't need this in the child. | 254 close(stdout_fds[kReadFD]); // Don't need this in the child. |
| 255 close(1); // Close stdout. | 255 close(1); // Close stdout. |
| 256 dup2(stdout_fds[kWriteFD], 1); // Dup pipe fd to stdout. | 256 dup2(stdout_fds[kWriteFD], 1); // Dup pipe fd to stdout. |
| 257 close(stdout_fds[kWriteFD]); // Don't need the original fd now. | 257 close(stdout_fds[kWriteFD]); // Don't need the original fd now. |
| 258 fcntl(exec_error_fds[kWriteFD], F_SETFD, FD_CLOEXEC); | 258 fcntl(exec_error_fds[kWriteFD], F_SETFD, FD_CLOEXEC); |
| 259 execvp(exec_args.arg0(), exec_args.arg_array()); | 259 execvp(exec_args.arg0(), exec_args.arg_array()); |
| 260 // Only get here if the exec failed. Write errno to the parent to tell | 260 // Only get here if the exec failed. Write errno to the parent to tell |
| 261 // them it went wrong. If it went well the pipe is closed. | 261 // them it went wrong. If it went well the pipe is closed. |
| 262 int err = errno; | 262 int err = errno; |
| (...skipping 18 matching lines...) Expand all Loading... |
| 281 return false; | 281 return false; |
| 282 } | 282 } |
| 283 return true; | 283 return true; |
| 284 } | 284 } |
| 285 | 285 |
| 286 | 286 |
| 287 // Accumulates the output from the child in a string handle. Returns true if it | 287 // Accumulates the output from the child in a string handle. Returns true if it |
| 288 // succeeded or false if an exception was thrown. | 288 // succeeded or false if an exception was thrown. |
| 289 static Handle<Value> GetStdout(Isolate* isolate, | 289 static Handle<Value> GetStdout(Isolate* isolate, |
| 290 int child_fd, | 290 int child_fd, |
| 291 struct timeval& start_time, | 291 const struct timeval& start_time, |
| 292 int read_timeout, | 292 int read_timeout, |
| 293 int total_timeout) { | 293 int total_timeout) { |
| 294 Handle<String> accumulator = String::Empty(isolate); | 294 Handle<String> accumulator = String::Empty(isolate); |
| 295 | 295 |
| 296 int fullness = 0; | 296 int fullness = 0; |
| 297 static const int kStdoutReadBufferSize = 4096; | 297 static const int kStdoutReadBufferSize = 4096; |
| 298 char buffer[kStdoutReadBufferSize]; | 298 char buffer[kStdoutReadBufferSize]; |
| 299 | 299 |
| 300 if (fcntl(child_fd, F_SETFL, O_NONBLOCK) != 0) { | 300 if (fcntl(child_fd, F_SETFL, O_NONBLOCK) != 0) { |
| 301 return isolate->ThrowException( | 301 return isolate->ThrowException( |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 353 && !defined(__NetBSD__) | 353 && !defined(__NetBSD__) |
| 354 #if !defined(__FreeBSD__) | 354 #if !defined(__FreeBSD__) |
| 355 #define HAS_WAITID 1 | 355 #define HAS_WAITID 1 |
| 356 #endif | 356 #endif |
| 357 #endif | 357 #endif |
| 358 | 358 |
| 359 | 359 |
| 360 // Get exit status of child. | 360 // Get exit status of child. |
| 361 static bool WaitForChild(Isolate* isolate, | 361 static bool WaitForChild(Isolate* isolate, |
| 362 int pid, | 362 int pid, |
| 363 ZombieProtector& child_waiter, | 363 ZombieProtector& child_waiter, // NOLINT |
| 364 struct timeval& start_time, | 364 const struct timeval& start_time, |
| 365 int read_timeout, | 365 int read_timeout, |
| 366 int total_timeout) { | 366 int total_timeout) { |
| 367 #ifdef HAS_WAITID | 367 #ifdef HAS_WAITID |
| 368 | 368 |
| 369 siginfo_t child_info; | 369 siginfo_t child_info; |
| 370 child_info.si_pid = 0; | 370 child_info.si_pid = 0; |
| 371 int useconds = 1; | 371 int useconds = 1; |
| 372 // Wait for child to exit. | 372 // Wait for child to exit. |
| 373 while (child_info.si_pid == 0) { | 373 while (child_info.si_pid == 0) { |
| 374 waitid(P_PID, pid, &child_info, WEXITED | WNOHANG | WNOWAIT); | 374 waitid(P_PID, pid, &child_info, WEXITED | WNOHANG | WNOWAIT); |
| (...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 709 FunctionTemplate::New(isolate, UnsetEnvironment)); | 709 FunctionTemplate::New(isolate, UnsetEnvironment)); |
| 710 os_templ->Set(String::NewFromUtf8(isolate, "umask"), | 710 os_templ->Set(String::NewFromUtf8(isolate, "umask"), |
| 711 FunctionTemplate::New(isolate, SetUMask)); | 711 FunctionTemplate::New(isolate, SetUMask)); |
| 712 os_templ->Set(String::NewFromUtf8(isolate, "mkdirp"), | 712 os_templ->Set(String::NewFromUtf8(isolate, "mkdirp"), |
| 713 FunctionTemplate::New(isolate, MakeDirectory)); | 713 FunctionTemplate::New(isolate, MakeDirectory)); |
| 714 os_templ->Set(String::NewFromUtf8(isolate, "rmdir"), | 714 os_templ->Set(String::NewFromUtf8(isolate, "rmdir"), |
| 715 FunctionTemplate::New(isolate, RemoveDirectory)); | 715 FunctionTemplate::New(isolate, RemoveDirectory)); |
| 716 } | 716 } |
| 717 | 717 |
| 718 } // namespace v8 | 718 } // namespace v8 |
| OLD | NEW |