| 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 |