OLD | NEW |
1 // Copyright (c) 2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2008 The Chromium 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 #include "chrome/common/ipc_channel_posix.h" | 5 #include "chrome/common/ipc_channel_posix.h" |
6 | 6 |
7 #include <errno.h> | 7 #include <errno.h> |
8 #include <fcntl.h> | 8 #include <fcntl.h> |
9 #include <stddef.h> | 9 #include <stddef.h> |
10 #include <sys/types.h> | 10 #include <sys/types.h> |
11 #include <sys/socket.h> | 11 #include <sys/socket.h> |
12 #include <sys/stat.h> | 12 #include <sys/stat.h> |
13 #include <sys/un.h> | 13 #include <sys/un.h> |
14 | 14 |
15 #include <string> | 15 #include <string> |
16 #include <map> | 16 #include <map> |
17 | 17 |
18 #include "base/command_line.h" | 18 #include "base/command_line.h" |
| 19 #include "base/eintr_wrappers.h" |
19 #include "base/lock.h" | 20 #include "base/lock.h" |
20 #include "base/logging.h" | 21 #include "base/logging.h" |
21 #include "base/process_util.h" | 22 #include "base/process_util.h" |
22 #include "base/scoped_ptr.h" | 23 #include "base/scoped_ptr.h" |
23 #include "base/string_util.h" | 24 #include "base/string_util.h" |
24 #include "base/singleton.h" | 25 #include "base/singleton.h" |
25 #include "base/stats_counters.h" | 26 #include "base/stats_counters.h" |
26 #include "chrome/common/chrome_counters.h" | 27 #include "chrome/common/chrome_counters.h" |
27 #include "chrome/common/chrome_switches.h" | 28 #include "chrome/common/chrome_switches.h" |
28 #include "chrome/common/file_descriptor_set_posix.h" | 29 #include "chrome/common/file_descriptor_set_posix.h" |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
132 } | 133 } |
133 | 134 |
134 // Create socket. | 135 // Create socket. |
135 int fd = socket(AF_UNIX, SOCK_STREAM, 0); | 136 int fd = socket(AF_UNIX, SOCK_STREAM, 0); |
136 if (fd < 0) { | 137 if (fd < 0) { |
137 return false; | 138 return false; |
138 } | 139 } |
139 | 140 |
140 // Make socket non-blocking | 141 // Make socket non-blocking |
141 if (fcntl(fd, F_SETFL, O_NONBLOCK) == -1) { | 142 if (fcntl(fd, F_SETFL, O_NONBLOCK) == -1) { |
142 close(fd); | 143 HANDLE_EINTR(close(fd)); |
143 return false; | 144 return false; |
144 } | 145 } |
145 | 146 |
146 // Delete any old FS instances. | 147 // Delete any old FS instances. |
147 unlink(pipe_name.c_str()); | 148 unlink(pipe_name.c_str()); |
148 | 149 |
149 // Create unix_addr structure | 150 // Create unix_addr structure |
150 struct sockaddr_un unix_addr; | 151 struct sockaddr_un unix_addr; |
151 memset(&unix_addr, 0, sizeof(unix_addr)); | 152 memset(&unix_addr, 0, sizeof(unix_addr)); |
152 unix_addr.sun_family = AF_UNIX; | 153 unix_addr.sun_family = AF_UNIX; |
153 snprintf(unix_addr.sun_path, kMaxPipeNameLength, "%s", pipe_name.c_str()); | 154 snprintf(unix_addr.sun_path, kMaxPipeNameLength, "%s", pipe_name.c_str()); |
154 size_t unix_addr_len = offsetof(struct sockaddr_un, sun_path) + | 155 size_t unix_addr_len = offsetof(struct sockaddr_un, sun_path) + |
155 strlen(unix_addr.sun_path) + 1; | 156 strlen(unix_addr.sun_path) + 1; |
156 | 157 |
157 // Bind the socket. | 158 // Bind the socket. |
158 if (bind(fd, reinterpret_cast<const sockaddr*>(&unix_addr), | 159 if (bind(fd, reinterpret_cast<const sockaddr*>(&unix_addr), |
159 unix_addr_len) != 0) { | 160 unix_addr_len) != 0) { |
160 close(fd); | 161 HANDLE_EINTR(close(fd)); |
161 return false; | 162 return false; |
162 } | 163 } |
163 | 164 |
164 // Start listening on the socket. | 165 // Start listening on the socket. |
165 const int listen_queue_length = 1; | 166 const int listen_queue_length = 1; |
166 if (listen(fd, listen_queue_length) != 0) { | 167 if (listen(fd, listen_queue_length) != 0) { |
167 close(fd); | 168 HANDLE_EINTR(close(fd)); |
168 return false; | 169 return false; |
169 } | 170 } |
170 | 171 |
171 *server_listen_fd = fd; | 172 *server_listen_fd = fd; |
172 return true; | 173 return true; |
173 } | 174 } |
174 | 175 |
175 // Accept a connection on a fifo. | 176 // Accept a connection on a fifo. |
176 bool ServerAcceptFifoConnection(int server_listen_fd, int* server_socket) { | 177 bool ServerAcceptFifoConnection(int server_listen_fd, int* server_socket) { |
177 DCHECK(server_socket); | 178 DCHECK(server_socket); |
178 | 179 |
179 int accept_fd = accept(server_listen_fd, NULL, 0); | 180 int accept_fd = HANDLE_EINTR(accept(server_listen_fd, NULL, 0)); |
180 if (accept_fd < 0) | 181 if (accept_fd < 0) |
181 return false; | 182 return false; |
182 if (fcntl(accept_fd, F_SETFL, O_NONBLOCK) == -1) { | 183 if (fcntl(accept_fd, F_SETFL, O_NONBLOCK) == -1) { |
183 close(accept_fd); | 184 HANDLE_EINTR(close(accept_fd)); |
184 return false; | 185 return false; |
185 } | 186 } |
186 | 187 |
187 *server_socket = accept_fd; | 188 *server_socket = accept_fd; |
188 return true; | 189 return true; |
189 } | 190 } |
190 | 191 |
191 bool ClientConnectToFifo(const std::string &pipe_name, int* client_socket) { | 192 bool ClientConnectToFifo(const std::string &pipe_name, int* client_socket) { |
192 DCHECK(client_socket); | 193 DCHECK(client_socket); |
193 DCHECK_LT(pipe_name.length(), kMaxPipeNameLength); | 194 DCHECK_LT(pipe_name.length(), kMaxPipeNameLength); |
194 | 195 |
195 // Create socket. | 196 // Create socket. |
196 int fd = socket(AF_UNIX, SOCK_STREAM, 0); | 197 int fd = socket(AF_UNIX, SOCK_STREAM, 0); |
197 if (fd < 0) { | 198 if (fd < 0) { |
198 LOG(ERROR) << "fd is invalid"; | 199 LOG(ERROR) << "fd is invalid"; |
199 return false; | 200 return false; |
200 } | 201 } |
201 | 202 |
202 // Make socket non-blocking | 203 // Make socket non-blocking |
203 if (fcntl(fd, F_SETFL, O_NONBLOCK) == -1) { | 204 if (fcntl(fd, F_SETFL, O_NONBLOCK) == -1) { |
204 LOG(ERROR) << "fcntl failed"; | 205 LOG(ERROR) << "fcntl failed"; |
205 close(fd); | 206 HANDLE_EINTR(close(fd)); |
206 return false; | 207 return false; |
207 } | 208 } |
208 | 209 |
209 // Create server side of socket. | 210 // Create server side of socket. |
210 struct sockaddr_un server_unix_addr; | 211 struct sockaddr_un server_unix_addr; |
211 memset(&server_unix_addr, 0, sizeof(server_unix_addr)); | 212 memset(&server_unix_addr, 0, sizeof(server_unix_addr)); |
212 server_unix_addr.sun_family = AF_UNIX; | 213 server_unix_addr.sun_family = AF_UNIX; |
213 snprintf(server_unix_addr.sun_path, kMaxPipeNameLength, "%s", | 214 snprintf(server_unix_addr.sun_path, kMaxPipeNameLength, "%s", |
214 pipe_name.c_str()); | 215 pipe_name.c_str()); |
215 size_t server_unix_addr_len = offsetof(struct sockaddr_un, sun_path) + | 216 size_t server_unix_addr_len = offsetof(struct sockaddr_un, sun_path) + |
216 strlen(server_unix_addr.sun_path) + 1; | 217 strlen(server_unix_addr.sun_path) + 1; |
217 | 218 |
218 int ret_val = -1; | 219 if (HANDLE_EINTR(connect(fd, reinterpret_cast<sockaddr*>(&server_unix_addr), |
219 do { | 220 server_unix_addr_len)) != 0) { |
220 ret_val = connect(fd, reinterpret_cast<sockaddr*>(&server_unix_addr), | 221 HANDLE_EINTR(close(fd)); |
221 server_unix_addr_len); | |
222 } while (ret_val == -1 && errno == EINTR); | |
223 if (ret_val != 0) { | |
224 close(fd); | |
225 return false; | 222 return false; |
226 } | 223 } |
227 | 224 |
228 *client_socket = fd; | 225 *client_socket = fd; |
229 return true; | 226 return true; |
230 } | 227 } |
231 | 228 |
232 } // namespace | 229 } // namespace |
233 //------------------------------------------------------------------------------ | 230 //------------------------------------------------------------------------------ |
234 | 231 |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
283 } else { | 280 } else { |
284 // socketpair() | 281 // socketpair() |
285 if (mode == MODE_SERVER) { | 282 if (mode == MODE_SERVER) { |
286 int pipe_fds[2]; | 283 int pipe_fds[2]; |
287 if (socketpair(AF_UNIX, SOCK_STREAM, 0, pipe_fds) != 0) { | 284 if (socketpair(AF_UNIX, SOCK_STREAM, 0, pipe_fds) != 0) { |
288 return false; | 285 return false; |
289 } | 286 } |
290 // Set both ends to be non-blocking. | 287 // Set both ends to be non-blocking. |
291 if (fcntl(pipe_fds[0], F_SETFL, O_NONBLOCK) == -1 || | 288 if (fcntl(pipe_fds[0], F_SETFL, O_NONBLOCK) == -1 || |
292 fcntl(pipe_fds[1], F_SETFL, O_NONBLOCK) == -1) { | 289 fcntl(pipe_fds[1], F_SETFL, O_NONBLOCK) == -1) { |
293 close(pipe_fds[0]); | 290 HANDLE_EINTR(close(pipe_fds[0])); |
294 close(pipe_fds[1]); | 291 HANDLE_EINTR(close(pipe_fds[1])); |
295 return false; | 292 return false; |
296 } | 293 } |
297 pipe_ = pipe_fds[0]; | 294 pipe_ = pipe_fds[0]; |
298 client_pipe_ = pipe_fds[1]; | 295 client_pipe_ = pipe_fds[1]; |
299 | 296 |
300 Singleton<PipeMap>()->Insert(pipe_name_, client_pipe_); | 297 Singleton<PipeMap>()->Insert(pipe_name_, client_pipe_); |
301 } else { | 298 } else { |
302 pipe_ = ChannelNameToClientFD(pipe_name_); | 299 pipe_ = ChannelNameToClientFD(pipe_name_); |
303 DCHECK(pipe_ > 0); | 300 DCHECK(pipe_ > 0); |
304 waiting_connect_ = false; | 301 waiting_connect_ = false; |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
360 for (;;) { | 357 for (;;) { |
361 msg.msg_controllen = sizeof(input_cmsg_buf_); | 358 msg.msg_controllen = sizeof(input_cmsg_buf_); |
362 | 359 |
363 if (bytes_read == 0) { | 360 if (bytes_read == 0) { |
364 if (pipe_ == -1) | 361 if (pipe_ == -1) |
365 return false; | 362 return false; |
366 | 363 |
367 // Read from pipe. | 364 // Read from pipe. |
368 // recvmsg() returns 0 if the connection has closed or EAGAIN if no data | 365 // recvmsg() returns 0 if the connection has closed or EAGAIN if no data |
369 // is waiting on the pipe. | 366 // is waiting on the pipe. |
370 do { | 367 bytes_read = HANDLE_EINTR(recvmsg(pipe_, &msg, MSG_DONTWAIT)); |
371 bytes_read = recvmsg(pipe_, &msg, MSG_DONTWAIT); | |
372 } while (bytes_read == -1 && errno == EINTR); | |
373 | 368 |
374 if (bytes_read < 0) { | 369 if (bytes_read < 0) { |
375 if (errno == EAGAIN) { | 370 if (errno == EAGAIN) { |
376 return true; | 371 return true; |
377 } else { | 372 } else { |
378 LOG(ERROR) << "pipe error (" << pipe_ << "): " << strerror(errno); | 373 LOG(ERROR) << "pipe error (" << pipe_ << "): " << strerror(errno); |
379 return false; | 374 return false; |
380 } | 375 } |
381 } else if (bytes_read == 0) { | 376 } else if (bytes_read == 0) { |
382 // The pipe has closed... | 377 // The pipe has closed... |
383 Close(); | 378 Close(); |
384 return false; | 379 return false; |
385 } | 380 } |
386 } | 381 } |
387 DCHECK(bytes_read); | 382 DCHECK(bytes_read); |
388 | 383 |
389 if (client_pipe_ != -1) { | 384 if (client_pipe_ != -1) { |
390 Singleton<PipeMap>()->Remove(pipe_name_); | 385 Singleton<PipeMap>()->Remove(pipe_name_); |
391 close(client_pipe_); | 386 HANDLE_EINTR(close(client_pipe_)); |
392 client_pipe_ = -1; | 387 client_pipe_ = -1; |
393 } | 388 } |
394 | 389 |
395 // a pointer to an array of |num_wire_fds| file descriptors from the read | 390 // a pointer to an array of |num_wire_fds| file descriptors from the read |
396 const int* wire_fds = NULL; | 391 const int* wire_fds = NULL; |
397 unsigned num_wire_fds = 0; | 392 unsigned num_wire_fds = 0; |
398 | 393 |
399 // walk the list of control messages and, if we find an array of file | 394 // walk the list of control messages and, if we find an array of file |
400 // descriptors, save a pointer to the array | 395 // descriptors, save a pointer to the array |
401 | 396 |
(...skipping 18 matching lines...) Expand all Loading... |
420 const unsigned payload_len = cmsg->cmsg_len - CMSG_LEN(0); | 415 const unsigned payload_len = cmsg->cmsg_len - CMSG_LEN(0); |
421 DCHECK(payload_len % sizeof(int) == 0); | 416 DCHECK(payload_len % sizeof(int) == 0); |
422 wire_fds = reinterpret_cast<int*>(CMSG_DATA(cmsg)); | 417 wire_fds = reinterpret_cast<int*>(CMSG_DATA(cmsg)); |
423 num_wire_fds = payload_len / 4; | 418 num_wire_fds = payload_len / 4; |
424 | 419 |
425 if (msg.msg_flags & MSG_CTRUNC) { | 420 if (msg.msg_flags & MSG_CTRUNC) { |
426 LOG(ERROR) << "SCM_RIGHTS message was truncated" | 421 LOG(ERROR) << "SCM_RIGHTS message was truncated" |
427 << " cmsg_len:" << cmsg->cmsg_len | 422 << " cmsg_len:" << cmsg->cmsg_len |
428 << " fd:" << pipe_; | 423 << " fd:" << pipe_; |
429 for (unsigned i = 0; i < num_wire_fds; ++i) | 424 for (unsigned i = 0; i < num_wire_fds; ++i) |
430 close(wire_fds[i]); | 425 HANDLE_EINTR(close(wire_fds[i])); |
431 return false; | 426 return false; |
432 } | 427 } |
433 break; | 428 break; |
434 } | 429 } |
435 } | 430 } |
436 } | 431 } |
437 | 432 |
438 // Process messages from input buffer. | 433 // Process messages from input buffer. |
439 const char *p; | 434 const char *p; |
440 const char *end; | 435 const char *end; |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
493 | 488 |
494 if (error) { | 489 if (error) { |
495 LOG(WARNING) << error | 490 LOG(WARNING) << error |
496 << " channel:" << this | 491 << " channel:" << this |
497 << " message-type:" << m.type() | 492 << " message-type:" << m.type() |
498 << " header()->num_fds:" << m.header()->num_fds | 493 << " header()->num_fds:" << m.header()->num_fds |
499 << " num_fds:" << num_fds | 494 << " num_fds:" << num_fds |
500 << " fds_i:" << fds_i; | 495 << " fds_i:" << fds_i; |
501 // close the existing file descriptors so that we don't leak them | 496 // close the existing file descriptors so that we don't leak them |
502 for (unsigned i = fds_i; i < num_fds; ++i) | 497 for (unsigned i = fds_i; i < num_fds; ++i) |
503 close(fds[i]); | 498 HANDLE_EINTR(close(fds[i])); |
504 input_overflow_fds_.clear(); | 499 input_overflow_fds_.clear(); |
505 // abort the connection | 500 // abort the connection |
506 return false; | 501 return false; |
507 } | 502 } |
508 | 503 |
509 m.file_descriptor_set()->SetDescriptors( | 504 m.file_descriptor_set()->SetDescriptors( |
510 &fds[fds_i], m.header()->num_fds); | 505 &fds[fds_i], m.header()->num_fds); |
511 fds_i += m.header()->num_fds; | 506 fds_i += m.header()->num_fds; |
512 } | 507 } |
513 #ifdef IPC_MESSAGE_DEBUG_EXTRA | 508 #ifdef IPC_MESSAGE_DEBUG_EXTRA |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
557 | 552 |
558 // Write out all the messages we can till the write blocks or there are no | 553 // Write out all the messages we can till the write blocks or there are no |
559 // more outgoing messages. | 554 // more outgoing messages. |
560 while (!output_queue_.empty()) { | 555 while (!output_queue_.empty()) { |
561 Message* msg = output_queue_.front(); | 556 Message* msg = output_queue_.front(); |
562 | 557 |
563 size_t amt_to_write = msg->size() - message_send_bytes_written_; | 558 size_t amt_to_write = msg->size() - message_send_bytes_written_; |
564 DCHECK(amt_to_write != 0); | 559 DCHECK(amt_to_write != 0); |
565 const char *out_bytes = reinterpret_cast<const char*>(msg->data()) + | 560 const char *out_bytes = reinterpret_cast<const char*>(msg->data()) + |
566 message_send_bytes_written_; | 561 message_send_bytes_written_; |
567 ssize_t bytes_written = -1; | |
568 do { | |
569 struct msghdr msgh = {0}; | |
570 struct iovec iov = {const_cast<char*>(out_bytes), amt_to_write}; | |
571 msgh.msg_iov = &iov; | |
572 msgh.msg_iovlen = 1; | |
573 char buf[CMSG_SPACE( | |
574 sizeof(int[FileDescriptorSet::MAX_DESCRIPTORS_PER_MESSAGE]))]; | |
575 | 562 |
576 if (message_send_bytes_written_ == 0 && | 563 struct msghdr msgh = {0}; |
577 !msg->file_descriptor_set()->empty()) { | 564 struct iovec iov = {const_cast<char*>(out_bytes), amt_to_write}; |
578 // This is the first chunk of a message which has descriptors to send | 565 msgh.msg_iov = &iov; |
579 struct cmsghdr *cmsg; | 566 msgh.msg_iovlen = 1; |
580 const unsigned num_fds = msg->file_descriptor_set()->size(); | 567 char buf[CMSG_SPACE( |
| 568 sizeof(int[FileDescriptorSet::MAX_DESCRIPTORS_PER_MESSAGE]))]; |
581 | 569 |
582 DCHECK_LE(num_fds, FileDescriptorSet::MAX_DESCRIPTORS_PER_MESSAGE); | 570 if (message_send_bytes_written_ == 0 && |
| 571 !msg->file_descriptor_set()->empty()) { |
| 572 // This is the first chunk of a message which has descriptors to send |
| 573 struct cmsghdr *cmsg; |
| 574 const unsigned num_fds = msg->file_descriptor_set()->size(); |
583 | 575 |
584 msgh.msg_control = buf; | 576 DCHECK_LE(num_fds, FileDescriptorSet::MAX_DESCRIPTORS_PER_MESSAGE); |
585 msgh.msg_controllen = CMSG_SPACE(sizeof(int) * num_fds); | |
586 cmsg = CMSG_FIRSTHDR(&msgh); | |
587 cmsg->cmsg_level = SOL_SOCKET; | |
588 cmsg->cmsg_type = SCM_RIGHTS; | |
589 cmsg->cmsg_len = CMSG_LEN(sizeof(int) * num_fds); | |
590 msg->file_descriptor_set()->GetDescriptors( | |
591 reinterpret_cast<int*>(CMSG_DATA(cmsg))); | |
592 msgh.msg_controllen = cmsg->cmsg_len; | |
593 | 577 |
594 msg->header()->num_fds = num_fds; | 578 msgh.msg_control = buf; |
595 } | 579 msgh.msg_controllen = CMSG_SPACE(sizeof(int) * num_fds); |
| 580 cmsg = CMSG_FIRSTHDR(&msgh); |
| 581 cmsg->cmsg_level = SOL_SOCKET; |
| 582 cmsg->cmsg_type = SCM_RIGHTS; |
| 583 cmsg->cmsg_len = CMSG_LEN(sizeof(int) * num_fds); |
| 584 msg->file_descriptor_set()->GetDescriptors( |
| 585 reinterpret_cast<int*>(CMSG_DATA(cmsg))); |
| 586 msgh.msg_controllen = cmsg->cmsg_len; |
596 | 587 |
597 bytes_written = sendmsg(pipe_, &msgh, MSG_DONTWAIT); | 588 msg->header()->num_fds = num_fds; |
598 if (bytes_written > 0) | 589 } |
599 msg->file_descriptor_set()->CommitAll(); | 590 |
600 } while (bytes_written == -1 && errno == EINTR); | 591 ssize_t bytes_written = HANDLE_EINTR(sendmsg(pipe_, &msgh, MSG_DONTWAIT)); |
| 592 if (bytes_written > 0) |
| 593 msg->file_descriptor_set()->CommitAll(); |
601 | 594 |
602 if (bytes_written < 0 && errno != EAGAIN) { | 595 if (bytes_written < 0 && errno != EAGAIN) { |
603 LOG(ERROR) << "pipe error: " << strerror(errno); | 596 LOG(ERROR) << "pipe error: " << strerror(errno); |
604 return false; | 597 return false; |
605 } | 598 } |
606 | 599 |
607 if (static_cast<size_t>(bytes_written) != amt_to_write) { | 600 if (static_cast<size_t>(bytes_written) != amt_to_write) { |
608 if (bytes_written > 0) { | 601 if (bytes_written > 0) { |
609 // If write() fails with EAGAIN then bytes_written will be -1. | 602 // If write() fails with EAGAIN then bytes_written will be -1. |
610 message_send_bytes_written_ += bytes_written; | 603 message_send_bytes_written_ += bytes_written; |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
724 } | 717 } |
725 | 718 |
726 void Channel::ChannelImpl::Close() { | 719 void Channel::ChannelImpl::Close() { |
727 // Close can be called multiple time, so we need to make sure we're | 720 // Close can be called multiple time, so we need to make sure we're |
728 // idempotent. | 721 // idempotent. |
729 | 722 |
730 // Unregister libevent for the listening socket and close it. | 723 // Unregister libevent for the listening socket and close it. |
731 server_listen_connection_watcher_.StopWatchingFileDescriptor(); | 724 server_listen_connection_watcher_.StopWatchingFileDescriptor(); |
732 | 725 |
733 if (server_listen_pipe_ != -1) { | 726 if (server_listen_pipe_ != -1) { |
734 close(server_listen_pipe_); | 727 HANDLE_EINTR(close(server_listen_pipe_)); |
735 server_listen_pipe_ = -1; | 728 server_listen_pipe_ = -1; |
736 } | 729 } |
737 | 730 |
738 // Unregister libevent for the FIFO and close it. | 731 // Unregister libevent for the FIFO and close it. |
739 read_watcher_.StopWatchingFileDescriptor(); | 732 read_watcher_.StopWatchingFileDescriptor(); |
740 write_watcher_.StopWatchingFileDescriptor(); | 733 write_watcher_.StopWatchingFileDescriptor(); |
741 if (pipe_ != -1) { | 734 if (pipe_ != -1) { |
742 close(pipe_); | 735 HANDLE_EINTR(close(pipe_)); |
743 pipe_ = -1; | 736 pipe_ = -1; |
744 } | 737 } |
745 if (client_pipe_ != -1) { | 738 if (client_pipe_ != -1) { |
746 Singleton<PipeMap>()->Remove(pipe_name_); | 739 Singleton<PipeMap>()->Remove(pipe_name_); |
747 close(client_pipe_); | 740 HANDLE_EINTR(close(client_pipe_)); |
748 client_pipe_ = -1; | 741 client_pipe_ = -1; |
749 } | 742 } |
750 | 743 |
751 // Unlink the FIFO | 744 // Unlink the FIFO |
752 unlink(pipe_name_.c_str()); | 745 unlink(pipe_name_.c_str()); |
753 | 746 |
754 while (!output_queue_.empty()) { | 747 while (!output_queue_.empty()) { |
755 Message* m = output_queue_.front(); | 748 Message* m = output_queue_.front(); |
756 output_queue_.pop(); | 749 output_queue_.pop(); |
757 delete m; | 750 delete m; |
758 } | 751 } |
759 | 752 |
760 // Close any outstanding, received file descriptors | 753 // Close any outstanding, received file descriptors |
761 for (std::vector<int>::iterator | 754 for (std::vector<int>::iterator |
762 i = input_overflow_fds_.begin(); i != input_overflow_fds_.end(); ++i) { | 755 i = input_overflow_fds_.begin(); i != input_overflow_fds_.end(); ++i) { |
763 close(*i); | 756 HANDLE_EINTR(close(*i)); |
764 } | 757 } |
765 input_overflow_fds_.clear(); | 758 input_overflow_fds_.clear(); |
766 } | 759 } |
767 | 760 |
768 //------------------------------------------------------------------------------ | 761 //------------------------------------------------------------------------------ |
769 // Channel's methods simply call through to ChannelImpl. | 762 // Channel's methods simply call through to ChannelImpl. |
770 Channel::Channel(const std::wstring& channel_id, Mode mode, | 763 Channel::Channel(const std::wstring& channel_id, Mode mode, |
771 Listener* listener) | 764 Listener* listener) |
772 : channel_impl_(new ChannelImpl(channel_id, mode, listener)) { | 765 : channel_impl_(new ChannelImpl(channel_id, mode, listener)) { |
773 } | 766 } |
(...skipping 21 matching lines...) Expand all Loading... |
795 void Channel::GetClientFileDescriptorMapping(int *src_fd, int *dest_fd) const { | 788 void Channel::GetClientFileDescriptorMapping(int *src_fd, int *dest_fd) const { |
796 return channel_impl_->GetClientFileDescriptorMapping(src_fd, dest_fd); | 789 return channel_impl_->GetClientFileDescriptorMapping(src_fd, dest_fd); |
797 } | 790 } |
798 | 791 |
799 void Channel::OnClientConnected() { | 792 void Channel::OnClientConnected() { |
800 return channel_impl_->OnClientConnected(); | 793 return channel_impl_->OnClientConnected(); |
801 } | 794 } |
802 | 795 |
803 | 796 |
804 } // namespace IPC | 797 } // namespace IPC |
OLD | NEW |