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

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

Issue 2992803002: [Fuchsia] Fix Process exit code handler (Closed)
Patch Set: Format Created 3 years, 4 months 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
« no previous file with comments | « no previous file | no next file » | 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) 2016, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2016, 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 #if !defined(DART_IO_DISABLED) 5 #if !defined(DART_IO_DISABLED)
6 6
7 #include "platform/globals.h" 7 #include "platform/globals.h"
8 #if defined(HOST_OS_FUCHSIA) 8 #if defined(HOST_OS_FUCHSIA)
9 9
10 #include "bin/process.h" 10 #include "bin/process.h"
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
57 // the pipe used to communicate the exit code of the process to Dart. 57 // the pipe used to communicate the exit code of the process to Dart.
58 // ProcessInfo objects are kept in the static singly-linked 58 // ProcessInfo objects are kept in the static singly-linked
59 // ProcessInfoList. 59 // ProcessInfoList.
60 class ProcessInfo { 60 class ProcessInfo {
61 public: 61 public:
62 ProcessInfo(mx_handle_t process, intptr_t fd) 62 ProcessInfo(mx_handle_t process, intptr_t fd)
63 : process_(process), exit_pipe_fd_(fd) {} 63 : process_(process), exit_pipe_fd_(fd) {}
64 ~ProcessInfo() { 64 ~ProcessInfo() {
65 int closed = NO_RETRY_EXPECTED(close(exit_pipe_fd_)); 65 int closed = NO_RETRY_EXPECTED(close(exit_pipe_fd_));
66 if (closed != 0) { 66 if (closed != 0) {
67 FATAL("Failed to close process exit code pipe"); 67 LOG_ERR("Failed to close process exit code pipe");
68 } 68 }
69 mx_handle_close(process_); 69 mx_handle_close(process_);
70 } 70 }
71 mx_handle_t process() const { return process_; } 71 mx_handle_t process() const { return process_; }
72 intptr_t exit_pipe_fd() const { return exit_pipe_fd_; } 72 intptr_t exit_pipe_fd() const { return exit_pipe_fd_; }
73 ProcessInfo* next() const { return next_; } 73 ProcessInfo* next() const { return next_; }
74 void set_next(ProcessInfo* info) { next_ = info; } 74 void set_next(ProcessInfo* info) { next_ = info; }
75 75
76 private: 76 private:
77 mx_handle_t process_; 77 mx_handle_t process_;
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
149 class ExitCodeHandler { 149 class ExitCodeHandler {
150 public: 150 public:
151 // Notify the ExitCodeHandler that another process exists. 151 // Notify the ExitCodeHandler that another process exists.
152 static void Start() { 152 static void Start() {
153 // Multiple isolates could be starting processes at the same 153 // Multiple isolates could be starting processes at the same
154 // time. Make sure that only one ExitCodeHandler thread exists. 154 // time. Make sure that only one ExitCodeHandler thread exists.
155 MonitorLocker locker(monitor_); 155 MonitorLocker locker(monitor_);
156 if (running_) { 156 if (running_) {
157 return; 157 return;
158 } 158 }
159
160 LOG_INFO("ExitCodeHandler Starting\n"); 159 LOG_INFO("ExitCodeHandler Starting\n");
161 160
162 mx_status_t status = mx_socket_create(0, &interrupt_in_, &interrupt_out_); 161 mx_status_t status = mx_port_create(0, &port_);
163 if (status < 0) { 162 if (status != MX_OK) {
164 FATAL1("Failed to create exit code handler interrupt socket: %s\n", 163 FATAL1("ExitCodeHandler: mx_port_create failed: %s\n",
165 mx_status_get_string(status)); 164 mx_status_get_string(status));
165 return;
166 } 166 }
167 167
168 // Start thread that handles process exits when wait returns. 168 // Start thread that handles process exits when wait returns.
169 intptr_t result = 169 intptr_t result = Thread::Start(ExitCodeHandlerEntry, 0);
170 Thread::Start(ExitCodeHandlerEntry, static_cast<uword>(interrupt_out_));
171 if (result != 0) { 170 if (result != 0) {
172 FATAL1("Failed to start exit code handler worker thread %ld", result); 171 FATAL1("Failed to start exit code handler worker thread %ld", result);
173 } 172 }
174 173
175 running_ = true; 174 running_ = true;
176 } 175 }
177 176
178 static void Add(mx_handle_t process) { 177 static mx_status_t Add(mx_handle_t process) {
179 MonitorLocker locker(monitor_); 178 MonitorLocker locker(monitor_);
180 LOG_INFO("ExitCodeHandler Adding Process: %ld\n", process); 179 LOG_INFO("ExitCodeHandler Adding Process: %ld\n", process);
181 SendMessage(Message::kAdd, process); 180 return mx_object_wait_async(process, port_, static_cast<uint64_t>(process),
181 MX_TASK_TERMINATED, MX_WAIT_ASYNC_ONCE);
182 } 182 }
183 183
184 static void Terminate() { 184 static void Terminate() {
185 MonitorLocker locker(monitor_); 185 MonitorLocker locker(monitor_);
186 if (!running_) { 186 if (!running_) {
187 return; 187 return;
188 } 188 }
189 running_ = false; 189 running_ = false;
190 190
191 LOG_INFO("ExitCodeHandler Terminating\n"); 191 LOG_INFO("ExitCodeHandler Terminating\n");
192 SendMessage(Message::kShutdown, MX_HANDLE_INVALID); 192 SendShutdownMessage();
193 193
194 while (!terminate_done_) { 194 while (!terminate_done_) {
195 monitor_->Wait(Monitor::kNoTimeout); 195 monitor_->Wait(Monitor::kNoTimeout);
196 } 196 }
197 mx_handle_close(interrupt_in_); 197 mx_handle_close(port_);
198 LOG_INFO("ExitCodeHandler Terminated\n"); 198 LOG_INFO("ExitCodeHandler Terminated\n");
199 } 199 }
200 200
201 private: 201 private:
202 class Message { 202 static const uint64_t kShutdownPacketKey = 1;
203 public:
204 enum Command {
205 kAdd,
206 kShutdown,
207 };
208 Command command;
209 mx_handle_t handle;
210 };
211 203
212 static void SendMessage(Message::Command command, mx_handle_t handle) { 204 static void SendShutdownMessage() {
213 Message msg; 205 mx_port_packet_t pkt;
214 msg.command = command; 206 pkt.key = kShutdownPacketKey;
215 msg.handle = handle; 207 mx_status_t status = mx_port_queue(port_, reinterpret_cast<void*>(&pkt), 0);
216 size_t actual; 208 if (status != MX_OK) {
217 mx_status_t status = 209 Log::PrintErr("ExitCodeHandler: mx_port_queue failed: %s\n",
218 mx_socket_write(interrupt_in_, 0, &msg, sizeof(msg), &actual); 210 mx_status_get_string(status));
219 if (status < 0) {
220 FATAL1("Write to exit handler interrupt handle failed: %s\n",
221 mx_status_get_string(status));
222 } 211 }
223 ASSERT(actual == sizeof(msg));
224 } 212 }
225 213
226 // Entry point for the separate exit code handler thread started by 214 // Entry point for the separate exit code handler thread started by
227 // the ExitCodeHandler. 215 // the ExitCodeHandler.
228 static void ExitCodeHandlerEntry(uword param) { 216 static void ExitCodeHandlerEntry(uword param) {
229 LOG_INFO("ExitCodeHandler Entering ExitCodeHandler thread\n"); 217 LOG_INFO("ExitCodeHandler Entering ExitCodeHandler thread\n");
230 item_capacity_ = 16;
231 items_ = reinterpret_cast<mx_wait_item_t*>(
232 malloc(item_capacity_ * sizeof(*items_)));
233 items_to_remove_ = reinterpret_cast<intptr_t*>(
234 malloc(item_capacity_ * sizeof(*items_to_remove_)));
235 218
236 // The interrupt handle is fixed to the first entry. 219 mx_port_packet_t pkt;
237 items_[0].handle = interrupt_out_; 220 while (true) {
238 items_[0].waitfor = MX_SOCKET_READABLE | MX_SOCKET_PEER_CLOSED; 221 mx_status_t status = mx_port_wait(port_, MX_TIME_INFINITE,
239 items_[0].pending = MX_SIGNAL_NONE; 222 reinterpret_cast<void*>(&pkt), 0);
240 item_count_ = 1; 223 if (status != MX_OK) {
241 224 FATAL1("ExitCodeHandler: mx_port_wait failed: %s\n",
242 while (!do_shutdown_) {
243 LOG_INFO("ExitCodeHandler Calling mx_object_wait_many: %ld items\n",
244 item_count_);
245 mx_status_t status =
246 mx_object_wait_many(items_, item_count_, MX_TIME_INFINITE);
247 if (status < 0) {
248 FATAL1("Exit code handler handle wait failed: %s\n",
249 mx_status_get_string(status)); 225 mx_status_get_string(status));
250 } 226 }
251 LOG_INFO("ExitCodeHandler mx_object_wait_many returned\n"); 227 if (pkt.type == MX_PKT_TYPE_USER) {
252 228 ASSERT(pkt.key == kShutdownPacketKey);
253 bool have_interrupt = false; 229 break;
254 intptr_t remove_count = 0;
255 for (intptr_t i = 0; i < item_count_; i++) {
256 if (items_[i].pending == MX_SIGNAL_NONE) {
257 continue;
258 }
259 if (i == 0) {
260 LOG_INFO("ExitCodeHandler thread saw interrupt\n");
261 have_interrupt = true;
262 continue;
263 }
264 ASSERT(items_[i].waitfor == MX_TASK_TERMINATED);
265 ASSERT((items_[i].pending & MX_TASK_TERMINATED) != 0);
266 LOG_INFO("ExitCodeHandler signal for %ld\n", items_[i].handle);
267 SendProcessStatus(items_[i].handle);
268 items_to_remove_[remove_count++] = i;
269 } 230 }
270 for (intptr_t i = 0; i < remove_count; i++) { 231 mx_handle_t process = static_cast<mx_handle_t>(pkt.key);
271 RemoveItem(items_to_remove_[i]); 232 mx_signals_t observed = pkt.signal.observed;
233 if ((observed & MX_TASK_TERMINATED) == MX_SIGNAL_NONE) {
234 LOG_ERR("ExitCodeHandler: Unexpected signals, process %ld: %lx\n",
235 process, observed);
272 } 236 }
273 if (have_interrupt) { 237 SendProcessStatus(process);
274 HandleInterruptMsg();
275 }
276 } 238 }
277 239
278 LOG_INFO("ExitCodeHandler thread shutting down\n"); 240 LOG_INFO("ExitCodeHandler thread shutting down\n");
279 mx_handle_close(interrupt_out_);
280 free(items_);
281 items_ = NULL;
282 free(items_to_remove_);
283 items_to_remove_ = NULL;
284 item_count_ = 0;
285 item_capacity_ = 0;
286
287 terminate_done_ = true; 241 terminate_done_ = true;
288 monitor_->Notify(); 242 monitor_->Notify();
289 } 243 }
290 244
291 static void SendProcessStatus(mx_handle_t process) { 245 static void SendProcessStatus(mx_handle_t process) {
292 LOG_INFO("ExitCodeHandler thread getting process status: %ld\n", process); 246 LOG_INFO("ExitCodeHandler thread getting process status: %ld\n", process);
247 int return_code = -1;
293 mx_info_process_t proc_info; 248 mx_info_process_t proc_info;
294 mx_status_t status = mx_object_get_info( 249 mx_status_t status = mx_object_get_info(
295 process, MX_INFO_PROCESS, &proc_info, sizeof(proc_info), NULL, NULL); 250 process, MX_INFO_PROCESS, &proc_info, sizeof(proc_info), NULL, NULL);
296 if (status < 0) { 251 if (status != MX_OK) {
297 FATAL1("mx_object_get_info failed on process handle: %s\n", 252 Log::PrintErr("ExitCodeHandler: mx_object_get_info failed: %s\n",
298 mx_status_get_string(status)); 253 mx_status_get_string(status));
254 } else {
255 return_code = proc_info.return_code;
299 } 256 }
300 257 mx_handle_close(process);
301 const int return_code = proc_info.return_code;
302 status = mx_handle_close(process);
303 if (status < 0) {
304 FATAL1("Failed to close process handle: %s\n",
305 mx_status_get_string(status));
306 }
307 LOG_INFO("ExitCodeHandler thread process %ld exited with %d\n", process, 258 LOG_INFO("ExitCodeHandler thread process %ld exited with %d\n", process,
308 return_code); 259 return_code);
309 260
310 const intptr_t exit_code_fd = ProcessInfoList::LookupProcessExitFd(process); 261 const intptr_t exit_code_fd = ProcessInfoList::LookupProcessExitFd(process);
311 LOG_INFO("ExitCodeHandler thread sending %ld code %d on fd %ld\n", process, 262 LOG_INFO("ExitCodeHandler thread sending %ld code %d on fd %ld\n", process,
312 return_code, exit_code_fd); 263 return_code, exit_code_fd);
313 if (exit_code_fd != 0) { 264 if (exit_code_fd != 0) {
314 int exit_message[2]; 265 int exit_message[2];
315 exit_message[0] = abs(return_code); 266 exit_message[0] = abs(return_code);
316 exit_message[1] = return_code >= 0 ? 0 : 1; 267 exit_message[1] = return_code >= 0 ? 0 : 1;
317 intptr_t result = FDUtils::WriteToBlocking(exit_code_fd, &exit_message, 268 intptr_t result = FDUtils::WriteToBlocking(exit_code_fd, &exit_message,
318 sizeof(exit_message)); 269 sizeof(exit_message));
319 ASSERT((result == -1) || (result == sizeof(exit_code_fd))); 270 ASSERT((result == -1) || (result == sizeof(exit_code_fd)));
320 if ((result == -1) && (errno != EPIPE)) { 271 if ((result == -1) && (errno != EPIPE)) {
321 int err = errno; 272 int err = errno;
322 FATAL1("Failed to write exit code to pipe: %d\n", err); 273 Log::PrintErr("Failed to write exit code for process %ld: errno=%d\n",
274 process, err);
323 } 275 }
324 LOG_INFO("ExitCodeHandler thread wrote %ld bytes to fd %ld\n", result, 276 LOG_INFO("ExitCodeHandler thread wrote %ld bytes to fd %ld\n", result,
325 exit_code_fd); 277 exit_code_fd);
326 LOG_INFO("ExitCodeHandler thread removing process %ld from list\n", 278 LOG_INFO("ExitCodeHandler thread removing process %ld from list\n",
327 process); 279 process);
328 ProcessInfoList::RemoveProcess(process); 280 ProcessInfoList::RemoveProcess(process);
281 } else {
282 LOG_ERR("ExitCodeHandler: Process %ld not found\n", process);
329 } 283 }
330 } 284 }
331 285
332 static void HandleInterruptMsg() { 286 static mx_handle_t port_;
333 ASSERT(items_[0].handle == interrupt_out_);
334 ASSERT(items_[0].waitfor == MX_SOCKET_READABLE);
335 ASSERT((items_[0].pending & MX_SOCKET_READABLE) != 0);
336 while (true) {
337 Message msg;
338 size_t actual = 0;
339 LOG_INFO("ExitCodeHandler thread reading interrupt message\n");
340 mx_status_t status =
341 mx_socket_read(interrupt_out_, 0, &msg, sizeof(msg), &actual);
342 if (status == MX_ERR_SHOULD_WAIT) {
343 LOG_INFO("ExitCodeHandler thread done reading interrupt messages\n");
344 return;
345 }
346 if (status < 0) {
347 FATAL1("Failed to read exit handler interrupt handle: %s\n",
348 mx_status_get_string(status));
349 }
350 if (actual < sizeof(msg)) {
351 FATAL1("Short read from exit handler interrupt handle: %ld\n", actual);
352 }
353 switch (msg.command) {
354 case Message::kShutdown:
355 LOG_INFO("ExitCodeHandler thread got shutdown message\n");
356 do_shutdown_ = true;
357 break;
358 case Message::kAdd:
359 LOG_INFO("ExitCodeHandler thread got add message: %ld\n", msg.handle);
360 AddItem(msg.handle);
361 break;
362 }
363 }
364 }
365
366 static void AddItem(mx_handle_t h) {
367 if (item_count_ == item_capacity_) {
368 item_capacity_ = item_capacity_ + (item_capacity_ >> 1);
369 items_ =
370 reinterpret_cast<mx_wait_item_t*>(realloc(items_, item_capacity_));
371 items_to_remove_ = reinterpret_cast<intptr_t*>(
372 realloc(items_to_remove_, item_capacity_));
373 }
374 LOG_INFO("ExitCodeHandler thread adding item %ld at %ld\n", h, item_count_);
375 items_[item_count_].handle = h;
376 items_[item_count_].waitfor = MX_TASK_TERMINATED;
377 items_[item_count_].pending = MX_SIGNAL_NONE;
378 item_count_++;
379 }
380
381 static void RemoveItem(intptr_t idx) {
382 LOG_INFO("ExitCodeHandler thread removing item %ld at %ld\n",
383 items_[idx].handle, idx);
384 ASSERT(idx != 0);
385 const intptr_t last = item_count_ - 1;
386 items_[idx].handle = MX_HANDLE_INVALID;
387 items_[idx].waitfor = MX_SIGNAL_NONE;
388 items_[idx].pending = MX_SIGNAL_NONE;
389 if (idx != last) {
390 items_[idx] = items_[last];
391 }
392 item_count_--;
393 }
394
395 // Interrupt channel.
396 static mx_handle_t interrupt_in_;
397 static mx_handle_t interrupt_out_;
398
399 // Accessed only by the ExitCodeHandler thread.
400 static mx_wait_item_t* items_;
401 static intptr_t* items_to_remove_;
402 static intptr_t item_count_;
403 static intptr_t item_capacity_;
404 287
405 // Protected by monitor_. 288 // Protected by monitor_.
406 static bool do_shutdown_;
407 static bool terminate_done_; 289 static bool terminate_done_;
408 static bool running_; 290 static bool running_;
409 static Monitor* monitor_; 291 static Monitor* monitor_;
410 292
411 DISALLOW_ALLOCATION(); 293 DISALLOW_ALLOCATION();
412 DISALLOW_IMPLICIT_CONSTRUCTORS(ExitCodeHandler); 294 DISALLOW_IMPLICIT_CONSTRUCTORS(ExitCodeHandler);
413 }; 295 };
414 296
415 mx_handle_t ExitCodeHandler::interrupt_in_ = MX_HANDLE_INVALID; 297 mx_handle_t ExitCodeHandler::port_ = MX_HANDLE_INVALID;
416 mx_handle_t ExitCodeHandler::interrupt_out_ = MX_HANDLE_INVALID;
417 mx_wait_item_t* ExitCodeHandler::items_ = NULL;
418 intptr_t* ExitCodeHandler::items_to_remove_ = NULL;
419 intptr_t ExitCodeHandler::item_count_ = 0;
420 intptr_t ExitCodeHandler::item_capacity_ = 0;
421
422 bool ExitCodeHandler::do_shutdown_ = false;
423 bool ExitCodeHandler::running_ = false; 298 bool ExitCodeHandler::running_ = false;
424 bool ExitCodeHandler::terminate_done_ = false; 299 bool ExitCodeHandler::terminate_done_ = false;
425 Monitor* ExitCodeHandler::monitor_ = new Monitor(); 300 Monitor* ExitCodeHandler::monitor_ = new Monitor();
426 301
427 void Process::TerminateExitCodeHandler() { 302 void Process::TerminateExitCodeHandler() {
428 ExitCodeHandler::Terminate(); 303 ExitCodeHandler::Terminate();
429 } 304 }
430 305
431 intptr_t Process::CurrentProcessId() { 306 intptr_t Process::CurrentProcessId() {
432 return static_cast<intptr_t>(getpid()); 307 return static_cast<intptr_t>(getpid());
(...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after
718 return status; 593 return status;
719 } 594 }
720 ASSERT(lp != NULL); 595 ASSERT(lp != NULL);
721 596
722 // Launch it. 597 // Launch it.
723 LOG_INFO("ProcessStarter: Start() Calling launchpad_start\n"); 598 LOG_INFO("ProcessStarter: Start() Calling launchpad_start\n");
724 mx_handle_t process = MX_HANDLE_INVALID; 599 mx_handle_t process = MX_HANDLE_INVALID;
725 const char* errormsg = NULL; 600 const char* errormsg = NULL;
726 status = launchpad_go(lp, &process, &errormsg); 601 status = launchpad_go(lp, &process, &errormsg);
727 lp = NULL; // launchpad_go() calls launchpad_destroy() on the launchpad. 602 lp = NULL; // launchpad_go() calls launchpad_destroy() on the launchpad.
728 if (status < 0) { 603 if (status != MX_OK) {
729 LOG_INFO("ProcessStarter: Start() launchpad_start failed\n"); 604 LOG_ERR("ProcessStarter: Start() launchpad_start failed\n");
730 const intptr_t kMaxMessageSize = 256;
731 close(exit_pipe_fds[0]); 605 close(exit_pipe_fds[0]);
732 close(exit_pipe_fds[1]); 606 close(exit_pipe_fds[1]);
733 char* message = DartUtils::ScopedCString(kMaxMessageSize); 607 ReportStartError(errormsg);
734 snprintf(message, kMaxMessageSize, "%s:%d: launchpad_start failed: %s\n",
735 __FILE__, __LINE__, errormsg);
736 *os_error_message_ = message;
737 return status; 608 return status;
738 } 609 }
739 610
740 LOG_INFO("ProcessStarter: Start() adding %ld to list with exit_pipe %d\n", 611 LOG_INFO("ProcessStarter: Start() adding %ld to list with exit_pipe %d\n",
741 process, exit_pipe_fds[1]); 612 process, exit_pipe_fds[1]);
742 ProcessInfoList::AddProcess(process, exit_pipe_fds[1]); 613 ProcessInfoList::AddProcess(process, exit_pipe_fds[1]);
743 ExitCodeHandler::Start(); 614 ExitCodeHandler::Start();
744 ExitCodeHandler::Add(process); 615 status = ExitCodeHandler::Add(process);
616 if (status != MX_OK) {
617 LOG_ERR("ProcessStarter: ExitCodeHandler: Add failed: %s\n",
618 mx_status_get_string(status));
619 close(exit_pipe_fds[0]);
620 close(exit_pipe_fds[1]);
621 mx_task_kill(process);
622 ProcessInfoList::RemoveProcess(process);
623 ReportStartError(mx_status_get_string(status));
624 return status;
625 }
745 626
746 // The IOHandles allocated below are returned to Dart code. The Dart code 627 // The IOHandles allocated below are returned to Dart code. The Dart code
747 // calls into the runtime again to allocate a C++ Socket object, which 628 // calls into the runtime again to allocate a C++ Socket object, which
748 // becomes the native field of a Dart _NativeSocket object. The C++ Socket 629 // becomes the native field of a Dart _NativeSocket object. The C++ Socket
749 // object and the EventHandler manage the lifetime of these IOHandles. 630 // object and the EventHandler manage the lifetime of these IOHandles.
750 *id_ = process; 631 *id_ = process;
751 FDUtils::SetNonBlocking(read_in_); 632 FDUtils::SetNonBlocking(read_in_);
752 *in_ = reinterpret_cast<intptr_t>(new IOHandle(read_in_)); 633 *in_ = reinterpret_cast<intptr_t>(new IOHandle(read_in_));
753 read_in_ = -1; 634 read_in_ = -1;
754 FDUtils::SetNonBlocking(read_err_); 635 FDUtils::SetNonBlocking(read_err_);
755 *err_ = reinterpret_cast<intptr_t>(new IOHandle(read_err_)); 636 *err_ = reinterpret_cast<intptr_t>(new IOHandle(read_err_));
756 read_err_ = -1; 637 read_err_ = -1;
757 FDUtils::SetNonBlocking(write_out_); 638 FDUtils::SetNonBlocking(write_out_);
758 *out_ = reinterpret_cast<intptr_t>(new IOHandle(write_out_)); 639 *out_ = reinterpret_cast<intptr_t>(new IOHandle(write_out_));
759 write_out_ = -1; 640 write_out_ = -1;
760 FDUtils::SetNonBlocking(exit_pipe_fds[0]); 641 FDUtils::SetNonBlocking(exit_pipe_fds[0]);
761 *exit_event_ = reinterpret_cast<intptr_t>(new IOHandle(exit_pipe_fds[0])); 642 *exit_event_ = reinterpret_cast<intptr_t>(new IOHandle(exit_pipe_fds[0]));
762 return 0; 643 return 0;
763 } 644 }
764 645
765 private: 646 private:
647 void ReportStartError(const char* errormsg) {
648 const intptr_t kMaxMessageSize = 256;
649 char* message = DartUtils::ScopedCString(kMaxMessageSize);
650 snprintf(message, kMaxMessageSize, "Process start failed: %s\n", errormsg);
651 *os_error_message_ = message;
652 }
653
766 mx_status_t SetupLaunchpad(launchpad_t** launchpad) { 654 mx_status_t SetupLaunchpad(launchpad_t** launchpad) {
767 // TODO(zra): Use the supplied working directory when launchpad adds an 655 // TODO(zra): Use the supplied working directory when launchpad adds an
768 // API to set it. 656 // API to set it.
769 ASSERT(launchpad != NULL); 657 ASSERT(launchpad != NULL);
770 launchpad_t* lp = NULL; 658 launchpad_t* lp = NULL;
771 launchpad_create(MX_HANDLE_INVALID, program_arguments_[0], &lp); 659 launchpad_create(MX_HANDLE_INVALID, program_arguments_[0], &lp);
772 launchpad_set_args(lp, program_arguments_count_, program_arguments_); 660 launchpad_set_args(lp, program_arguments_count_, program_arguments_);
773 launchpad_set_environ(lp, program_environment_); 661 launchpad_set_environ(lp, program_environment_);
774 launchpad_clone(lp, LP_CLONE_MXIO_NAMESPACE); 662 launchpad_clone(lp, LP_CLONE_MXIO_NAMESPACE);
775 launchpad_clone(lp, LP_CLONE_MXIO_CWD); 663 launchpad_clone(lp, LP_CLONE_MXIO_CWD);
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
847 } 735 }
848 736
849 void Process::ClearSignalHandler(intptr_t signal, Dart_Port port) {} 737 void Process::ClearSignalHandler(intptr_t signal, Dart_Port port) {}
850 738
851 } // namespace bin 739 } // namespace bin
852 } // namespace dart 740 } // namespace dart
853 741
854 #endif // defined(HOST_OS_FUCHSIA) 742 #endif // defined(HOST_OS_FUCHSIA)
855 743
856 #endif // !defined(DART_IO_DISABLED) 744 #endif // !defined(DART_IO_DISABLED)
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698