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 |