| 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> |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 45 while (current != NULL) { | 45 while (current != NULL) { |
| 46 if (current->pid() == pid) { | 46 if (current->pid() == pid) { |
| 47 return current; | 47 return current; |
| 48 } | 48 } |
| 49 current = current->next(); | 49 current = current->next(); |
| 50 } | 50 } |
| 51 return NULL; | 51 return NULL; |
| 52 } | 52 } |
| 53 | 53 |
| 54 | 54 |
| 55 static ProcessInfo* RemoveProcess(pid_t pid) { | 55 static void RemoveProcess(pid_t pid) { |
| 56 ProcessInfo* prev = NULL; | 56 ProcessInfo* prev = NULL; |
| 57 ProcessInfo* current = active_processes; | 57 ProcessInfo* current = active_processes; |
| 58 while (current != NULL) { | 58 while (current != NULL) { |
| 59 if (current->pid() == pid) { | 59 if (current->pid() == pid) { |
| 60 if (prev == NULL) { | 60 if (prev == NULL) { |
| 61 active_processes = current->next(); | 61 active_processes = current->next(); |
| 62 } else { | 62 } else { |
| 63 prev->set_next(current->next()); | 63 prev->set_next(current->next()); |
| 64 } | 64 } |
| 65 return current; | 65 delete current; |
| 66 return; |
| 66 } | 67 } |
| 67 prev = current; | 68 prev = current; |
| 68 current = current->next(); | 69 current = current->next(); |
| 69 } | 70 } |
| 70 return NULL; | |
| 71 } | 71 } |
| 72 | 72 |
| 73 | 73 |
| 74 static char* SafeStrNCpy(char* dest, const char* src, size_t n) { | 74 static char* SafeStrNCpy(char* dest, const char* src, size_t n) { |
| 75 strncpy(dest, src, n); | 75 strncpy(dest, src, n); |
| 76 dest[n - 1] = '\0'; | 76 dest[n - 1] = '\0'; |
| 77 return dest; | 77 return dest; |
| 78 } | 78 } |
| 79 | 79 |
| 80 | 80 |
| (...skipping 27 matching lines...) Expand all Loading... |
| 108 FDUtils::WriteToBlocking(process->fd(), &message, sizeof(message)); | 108 FDUtils::WriteToBlocking(process->fd(), &message, sizeof(message)); |
| 109 if (result != sizeof(message) && errno != EPIPE) { | 109 if (result != sizeof(message) && errno != EPIPE) { |
| 110 perror("ExitHandler notification failed"); | 110 perror("ExitHandler notification failed"); |
| 111 } | 111 } |
| 112 close(process->fd()); | 112 close(process->fd()); |
| 113 } | 113 } |
| 114 } | 114 } |
| 115 } | 115 } |
| 116 | 116 |
| 117 | 117 |
| 118 static void ReportChildError(int exec_control_fd) { |
| 119 // In the case of failure in the child process write the errno and |
| 120 // the OS error message to the exec control pipe and exit. |
| 121 int child_errno = errno; |
| 122 char* os_error_message = strerror(errno); |
| 123 ASSERT(sizeof(child_errno) == sizeof(errno)); |
| 124 int bytes_written = |
| 125 FDUtils::WriteToBlocking( |
| 126 exec_control_fd, &child_errno, sizeof(child_errno)); |
| 127 if (bytes_written == sizeof(child_errno)) { |
| 128 FDUtils::WriteToBlocking( |
| 129 exec_control_fd, os_error_message, strlen(os_error_message) + 1); |
| 130 } |
| 131 close(exec_control_fd); |
| 132 exit(1); |
| 133 } |
| 134 |
| 135 |
| 118 int Process::Start(const char* path, | 136 int Process::Start(const char* path, |
| 119 char* arguments[], | 137 char* arguments[], |
| 120 intptr_t arguments_length, | 138 intptr_t arguments_length, |
| 121 intptr_t* in, | 139 intptr_t* in, |
| 122 intptr_t* out, | 140 intptr_t* out, |
| 123 intptr_t* err, | 141 intptr_t* err, |
| 124 intptr_t* id, | 142 intptr_t* id, |
| 125 intptr_t* exit_event, | 143 intptr_t* exit_event, |
| 126 char* os_error_message, | 144 char* os_error_message, |
| 127 int os_error_message_len) { | 145 int os_error_message_len) { |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 223 if (bytes_read != sizeof(msg)) { | 241 if (bytes_read != sizeof(msg)) { |
| 224 perror("Failed receiving notification message"); | 242 perror("Failed receiving notification message"); |
| 225 exit(1); | 243 exit(1); |
| 226 } | 244 } |
| 227 | 245 |
| 228 close(write_out[1]); | 246 close(write_out[1]); |
| 229 close(read_in[0]); | 247 close(read_in[0]); |
| 230 close(read_err[0]); | 248 close(read_err[0]); |
| 231 close(exec_control[0]); | 249 close(exec_control[0]); |
| 232 | 250 |
| 233 dup2(write_out[0], STDIN_FILENO); | 251 if (dup2(write_out[0], STDIN_FILENO) == -1) { |
| 252 ReportChildError(exec_control[1]); |
| 253 } |
| 234 close(write_out[0]); | 254 close(write_out[0]); |
| 235 | 255 |
| 236 dup2(read_in[1], STDOUT_FILENO); | 256 if (dup2(read_in[1], STDOUT_FILENO) == -1) { |
| 257 ReportChildError(exec_control[1]); |
| 258 } |
| 237 close(read_in[1]); | 259 close(read_in[1]); |
| 238 | 260 |
| 239 dup2(read_err[1], STDERR_FILENO); | 261 if (dup2(read_err[1], STDERR_FILENO) == -1) { |
| 262 ReportChildError(exec_control[1]); |
| 263 } |
| 240 close(read_err[1]); | 264 close(read_err[1]); |
| 241 | 265 |
| 242 execvp(path, const_cast<char* const*>(program_arguments)); | 266 execvp(path, const_cast<char* const*>(program_arguments)); |
| 243 // In the case of failure write the errno and the OS error message | 267 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 } | 268 } |
| 258 | 269 |
| 259 // The arguments for the spawned process are not needed any longer. | 270 // The arguments for the spawned process are not needed any longer. |
| 260 delete[] program_arguments; | 271 delete[] program_arguments; |
| 261 | 272 |
| 262 int event_fds[2]; | 273 int event_fds[2]; |
| 263 result = pipe(event_fds); | 274 result = pipe(event_fds); |
| 264 if (result < 0) { | 275 if (result < 0) { |
| 265 SetChildOsErrorMessage(os_error_message, os_error_message_len); | 276 SetChildOsErrorMessage(os_error_message, os_error_message_len); |
| 266 close(read_in[0]); | 277 close(read_in[0]); |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 338 if (result == -1) { | 349 if (result == -1) { |
| 339 return false; | 350 return false; |
| 340 } | 351 } |
| 341 return true; | 352 return true; |
| 342 } | 353 } |
| 343 | 354 |
| 344 | 355 |
| 345 void Process::Exit(intptr_t id) { | 356 void Process::Exit(intptr_t id) { |
| 346 RemoveProcess(id); | 357 RemoveProcess(id); |
| 347 } | 358 } |
| OLD | NEW |