Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(95)

Side by Side Diff: runtime/bin/process_macos.cc

Issue 8659032: Fix memory leak in MacOS process handling. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Address review comments. Created 9 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/bin/process_linux.cc ('k') | runtime/bin/socket.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « runtime/bin/process_linux.cc ('k') | runtime/bin/socket.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698