| OLD | NEW |
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "bin/process.h" | 5 #include "bin/process.h" |
| 6 | 6 |
| 7 #include <errno.h> | 7 #include <errno.h> |
| 8 #include <fcntl.h> | 8 #include <fcntl.h> |
| 9 #include <signal.h> | 9 #include <signal.h> |
| 10 #include <stdio.h> | 10 #include <stdio.h> |
| 11 #include <stdlib.h> | 11 #include <stdlib.h> |
| 12 #include <string.h> | 12 #include <string.h> |
| 13 #include <sys/wait.h> | 13 #include <sys/wait.h> |
| 14 #include <unistd.h> | 14 #include <unistd.h> |
| 15 | 15 |
| 16 #include "bin/fdutils.h" | 16 #include "bin/fdutils.h" |
| 17 | 17 |
| 18 |
| 18 class ProcessInfo { | 19 class ProcessInfo { |
| 19 public: | 20 public: |
| 20 ProcessInfo(pid_t pid, intptr_t fd) : pid_(pid), fd_(fd) { } | 21 ProcessInfo(pid_t pid, intptr_t fd) : pid_(pid), fd_(fd) { } |
| 21 | 22 |
| 22 pid_t pid() { return pid_; } | 23 pid_t pid() { return pid_; } |
| 23 intptr_t fd() { return fd_; } | 24 intptr_t fd() { return fd_; } |
| 24 ProcessInfo* next() { return next_; } | 25 ProcessInfo* next() { return next_; } |
| 25 void set_next(ProcessInfo* next) { next_ = next; } | 26 void set_next(ProcessInfo* next) { next_ = next; } |
| 26 | 27 |
| 27 private: | 28 private: |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 108 FDUtils::WriteToBlocking(process->fd(), &message, sizeof(message)); | 109 FDUtils::WriteToBlocking(process->fd(), &message, sizeof(message)); |
| 109 if (result != sizeof(message) && errno != EPIPE) { | 110 if (result != sizeof(message) && errno != EPIPE) { |
| 110 perror("ExitHandler notification failed"); | 111 perror("ExitHandler notification failed"); |
| 111 } | 112 } |
| 112 close(process->fd()); | 113 close(process->fd()); |
| 113 } | 114 } |
| 114 } | 115 } |
| 115 } | 116 } |
| 116 | 117 |
| 117 | 118 |
| 119 static void ReportChildError(int exec_control_fd) { |
| 120 // In the case of failure in the child process write the errno and |
| 121 // the OS error message to the exec control pipe and exit. |
| 122 int child_errno = errno; |
| 123 char* os_error_message = strerror(errno); |
| 124 ASSERT(sizeof(child_errno) == sizeof(errno)); |
| 125 int bytes_written = |
| 126 FDUtils::WriteToBlocking( |
| 127 exec_control_fd, &child_errno, sizeof(child_errno)); |
| 128 if (bytes_written == sizeof(child_errno)) { |
| 129 FDUtils::WriteToBlocking( |
| 130 exec_control_fd, os_error_message, strlen(os_error_message) + 1); |
| 131 } |
| 132 close(exec_control_fd); |
| 133 exit(1); |
| 134 } |
| 135 |
| 136 |
| 118 int Process::Start(const char* path, | 137 int Process::Start(const char* path, |
| 119 char* arguments[], | 138 char* arguments[], |
| 120 intptr_t arguments_length, | 139 intptr_t arguments_length, |
| 121 intptr_t* in, | 140 intptr_t* in, |
| 122 intptr_t* out, | 141 intptr_t* out, |
| 123 intptr_t* err, | 142 intptr_t* err, |
| 124 intptr_t* id, | 143 intptr_t* id, |
| 125 intptr_t* exit_event, | 144 intptr_t* exit_event, |
| 126 char* os_error_message, | 145 char* os_error_message, |
| 127 int os_error_message_len) { | 146 int os_error_message_len) { |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 223 if (bytes_read != sizeof(msg)) { | 242 if (bytes_read != sizeof(msg)) { |
| 224 perror("Failed receiving notification message"); | 243 perror("Failed receiving notification message"); |
| 225 exit(1); | 244 exit(1); |
| 226 } | 245 } |
| 227 | 246 |
| 228 close(write_out[1]); | 247 close(write_out[1]); |
| 229 close(read_in[0]); | 248 close(read_in[0]); |
| 230 close(read_err[0]); | 249 close(read_err[0]); |
| 231 close(exec_control[0]); | 250 close(exec_control[0]); |
| 232 | 251 |
| 233 dup2(write_out[0], STDIN_FILENO); | 252 if (dup2(write_out[0], STDIN_FILENO) == -1) { |
| 253 ReportChildError(exec_control[1]); |
| 254 } |
| 234 close(write_out[0]); | 255 close(write_out[0]); |
| 235 | 256 |
| 236 dup2(read_in[1], STDOUT_FILENO); | 257 if (dup2(read_in[1], STDOUT_FILENO) == -1) { |
| 258 ReportChildError(exec_control[1]); |
| 259 } |
| 237 close(read_in[1]); | 260 close(read_in[1]); |
| 238 | 261 |
| 239 dup2(read_err[1], STDERR_FILENO); | 262 if (dup2(read_err[1], STDERR_FILENO) == -1) { |
| 263 ReportChildError(exec_control[1]); |
| 264 } |
| 240 close(read_err[1]); | 265 close(read_err[1]); |
| 241 | 266 |
| 242 execvp(path, const_cast<char* const*>(program_arguments)); | 267 execvp(path, const_cast<char* const*>(program_arguments)); |
| 243 // In the case of failure write the errno and the OS error message | 268 ReportChildError(exec_control[1]); |
| 244 // to the exec control pipe. | |
| 245 int child_errno = errno; | |
| 246 char* os_error_message = strerror(errno); | |
| 247 ASSERT(sizeof(child_errno) == sizeof(errno)); | |
| 248 int bytes_written = | |
| 249 FDUtils::WriteToBlocking( | |
| 250 exec_control[1], &child_errno, sizeof(child_errno)); | |
| 251 if (bytes_written == sizeof(child_errno)) { | |
| 252 FDUtils::WriteToBlocking( | |
| 253 exec_control[1], os_error_message, strlen(os_error_message) + 1); | |
| 254 } | |
| 255 close(exec_control[1]); | |
| 256 exit(1); | |
| 257 } | 269 } |
| 258 | 270 |
| 259 // The arguments for the spawned process are not needed any longer. | 271 // The arguments for the spawned process are not needed any longer. |
| 260 delete[] program_arguments; | 272 delete[] program_arguments; |
| 261 | 273 |
| 262 int event_fds[2]; | 274 int event_fds[2]; |
| 263 result = pipe(event_fds); | 275 result = pipe(event_fds); |
| 264 if (result < 0) { | 276 if (result < 0) { |
| 265 SetChildOsErrorMessage(os_error_message, os_error_message_len); | 277 SetChildOsErrorMessage(os_error_message, os_error_message_len); |
| 266 close(read_in[0]); | 278 close(read_in[0]); |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 338 if (result == -1) { | 350 if (result == -1) { |
| 339 return false; | 351 return false; |
| 340 } | 352 } |
| 341 return true; | 353 return true; |
| 342 } | 354 } |
| 343 | 355 |
| 344 | 356 |
| 345 void Process::Exit(intptr_t id) { | 357 void Process::Exit(intptr_t id) { |
| 346 RemoveProcess(id); | 358 RemoveProcess(id); |
| 347 } | 359 } |
| OLD | NEW |