OLD | NEW |
---|---|
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 "ipc/ipc_channel_posix.h" | 5 #include "ipc/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> |
(...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
366 | 366 |
367 // Four possible cases: | 367 // Four possible cases: |
368 // 1) It's a channel wrapping a pipe that is given to us. | 368 // 1) It's a channel wrapping a pipe that is given to us. |
369 // 2) It's for a named channel, so we create it. | 369 // 2) It's for a named channel, so we create it. |
370 // 3) It's for a client that we implement ourself. This is used | 370 // 3) It's for a client that we implement ourself. This is used |
371 // in unittesting. | 371 // in unittesting. |
372 // 4) It's the initial IPC channel: | 372 // 4) It's the initial IPC channel: |
373 // 4a) Client side: Pull the pipe out of the GlobalDescriptors set. | 373 // 4a) Client side: Pull the pipe out of the GlobalDescriptors set. |
374 // 4b) Server side: create the pipe. | 374 // 4b) Server side: create the pipe. |
375 | 375 |
376 int local_pipe = -1; | |
376 if (channel_handle.socket.fd != -1) { | 377 if (channel_handle.socket.fd != -1) { |
377 // Case 1 from comment above. | 378 // Case 1 from comment above. |
378 pipe_ = channel_handle.socket.fd; | 379 local_pipe = channel_handle.socket.fd; |
379 #if defined(IPC_USES_READWRITE) | 380 #if defined(IPC_USES_READWRITE) |
380 // Test the socket passed into us to make sure it is nonblocking. | 381 // Test the socket passed into us to make sure it is nonblocking. |
381 // We don't want to call read/write on a blocking socket. | 382 // We don't want to call read/write on a blocking socket. |
382 int value = fcntl(pipe_, F_GETFL); | 383 int value = fcntl(local_pipe, F_GETFL); |
383 if (value == -1) { | 384 if (value == -1) { |
384 PLOG(ERROR) << "fcntl(F_GETFL) " << pipe_name_; | 385 PLOG(ERROR) << "fcntl(F_GETFL) " << pipe_name_; |
385 return false; | 386 return false; |
386 } | 387 } |
387 if (!(value & O_NONBLOCK)) { | 388 if (!(value & O_NONBLOCK)) { |
388 LOG(ERROR) << "Socket " << pipe_name_ << " must be O_NONBLOCK"; | 389 LOG(ERROR) << "Socket " << pipe_name_ << " must be O_NONBLOCK"; |
389 return false; | 390 return false; |
390 } | 391 } |
391 #endif // IPC_USES_READWRITE | 392 #endif // IPC_USES_READWRITE |
392 } else if (mode_ & MODE_NAMED_FLAG) { | 393 } else if (mode_ & MODE_NAMED_FLAG) { |
393 // Case 2 from comment above. | 394 // Case 2 from comment above. |
394 if (mode_ & MODE_SERVER_FLAG) { | 395 if (mode_ & MODE_SERVER_FLAG) { |
395 if (!CreateServerUnixDomainSocket(pipe_name_, &pipe_)) { | 396 if (!CreateServerUnixDomainSocket(pipe_name_, &local_pipe)) { |
396 return false; | 397 return false; |
397 } | 398 } |
398 must_unlink_ = true; | 399 must_unlink_ = true; |
399 } else if (mode_ & MODE_CLIENT_FLAG) { | 400 } else if (mode_ & MODE_CLIENT_FLAG) { |
400 if (!CreateClientUnixDomainSocket(pipe_name_, &pipe_)) { | 401 if (!CreateClientUnixDomainSocket(pipe_name_, &local_pipe)) { |
401 return false; | 402 return false; |
402 } | 403 } |
403 } else { | 404 } else { |
404 NOTREACHED(); | 405 LOG(ERROR) << "Bad mode: " << mode_; |
jeremy
2011/03/02 19:05:45
Why did you changed the NOTREACHED()'s to LOG(ERRO
| |
405 return false; | 406 return false; |
406 } | 407 } |
407 } else { | 408 } else { |
408 pipe_ = PipeMap::GetInstance()->Lookup(pipe_name_); | 409 local_pipe = PipeMap::GetInstance()->Lookup(pipe_name_); |
409 if (mode_ & MODE_CLIENT_FLAG) { | 410 if (mode_ & MODE_CLIENT_FLAG) { |
410 if (pipe_ != -1) { | 411 if (local_pipe != -1) { |
411 // Case 3 from comment above. | 412 // Case 3 from comment above. |
412 // We only allow one connection. | 413 // We only allow one connection. |
413 pipe_ = HANDLE_EINTR(dup(pipe_)); | 414 local_pipe = HANDLE_EINTR(dup(local_pipe)); |
414 PipeMap::GetInstance()->RemoveAndClose(pipe_name_); | 415 PipeMap::GetInstance()->RemoveAndClose(pipe_name_); |
415 } else { | 416 } else { |
416 // Case 4a from comment above. | 417 // Case 4a from comment above. |
417 // Guard against inappropriate reuse of the initial IPC channel. If | 418 // Guard against inappropriate reuse of the initial IPC channel. If |
418 // an IPC channel closes and someone attempts to reuse it by name, the | 419 // an IPC channel closes and someone attempts to reuse it by name, the |
419 // initial channel must not be recycled here. http://crbug.com/26754. | 420 // initial channel must not be recycled here. http://crbug.com/26754. |
420 static bool used_initial_channel = false; | 421 static bool used_initial_channel = false; |
421 if (used_initial_channel) { | 422 if (used_initial_channel) { |
422 LOG(FATAL) << "Denying attempt to reuse initial IPC channel for " | 423 LOG(FATAL) << "Denying attempt to reuse initial IPC channel for " |
423 << pipe_name_; | 424 << pipe_name_; |
424 return false; | 425 return false; |
425 } | 426 } |
426 used_initial_channel = true; | 427 used_initial_channel = true; |
427 | 428 |
428 pipe_ = base::GlobalDescriptors::GetInstance()->Get(kPrimaryIPCChannel); | 429 local_pipe = |
430 base::GlobalDescriptors::GetInstance()->Get(kPrimaryIPCChannel); | |
429 } | 431 } |
430 } else if (mode_ & MODE_SERVER_FLAG) { | 432 } else if (mode_ & MODE_SERVER_FLAG) { |
431 // Case 4b from comment above. | 433 // Case 4b from comment above. |
432 if (pipe_ != -1) { | 434 if (local_pipe != -1) { |
433 LOG(ERROR) << "Server already exists for " << pipe_name_; | 435 LOG(ERROR) << "Server already exists for " << pipe_name_; |
434 return false; | 436 return false; |
435 } | 437 } |
436 if (!SocketPair(&pipe_, &client_pipe_)) | 438 if (!SocketPair(&local_pipe, &client_pipe_)) |
437 return false; | 439 return false; |
438 PipeMap::GetInstance()->Insert(pipe_name_, client_pipe_); | 440 PipeMap::GetInstance()->Insert(pipe_name_, client_pipe_); |
439 } else { | 441 } else { |
440 NOTREACHED(); | 442 LOG(ERROR) << "Bad mode: " << mode_; |
441 return false; | 443 return false; |
442 } | 444 } |
443 } | 445 } |
444 | 446 |
445 if ((mode_ & MODE_SERVER_FLAG) && (mode_ & MODE_NAMED_FLAG)) { | |
446 server_listen_pipe_ = pipe_; | |
447 pipe_ = -1; | |
448 } | |
449 | |
450 #if defined(IPC_USES_READWRITE) | 447 #if defined(IPC_USES_READWRITE) |
451 // Create a dedicated socketpair() for exchanging file descriptors. | 448 // Create a dedicated socketpair() for exchanging file descriptors. |
452 // See comments for IPC_USES_READWRITE for details. | 449 // See comments for IPC_USES_READWRITE for details. |
453 if (mode_ & MODE_CLIENT_FLAG) { | 450 if (mode_ & MODE_CLIENT_FLAG) { |
454 if (!SocketPair(&fd_pipe_, &remote_fd_pipe_)) { | 451 if (!SocketPair(&fd_pipe_, &remote_fd_pipe_)) { |
455 return false; | 452 return false; |
456 } | 453 } |
457 } | 454 } |
458 #endif // IPC_USES_READWRITE | 455 #endif // IPC_USES_READWRITE |
459 | 456 |
457 if ((mode_ & MODE_SERVER_FLAG) && (mode_ & MODE_NAMED_FLAG)) { | |
458 server_listen_pipe_ = local_pipe; | |
459 local_pipe = -1; | |
460 } | |
461 | |
462 pipe_ = local_pipe; | |
460 return true; | 463 return true; |
461 } | 464 } |
462 | 465 |
463 bool Channel::ChannelImpl::Connect() { | 466 bool Channel::ChannelImpl::Connect() { |
464 if (server_listen_pipe_ == -1 && pipe_ == -1) { | 467 if (server_listen_pipe_ == -1 && pipe_ == -1) { |
465 DLOG(INFO) << "Must call create on a channel before calling connect"; | 468 DLOG(INFO) << "Channel creation failed: " << pipe_name_; |
466 return false; | 469 return false; |
467 } | 470 } |
468 | 471 |
469 bool did_connect = true; | 472 bool did_connect = true; |
470 if (server_listen_pipe_ != -1) { | 473 if (server_listen_pipe_ != -1) { |
471 // Watch the pipe for connections, and turn any connections into | 474 // Watch the pipe for connections, and turn any connections into |
472 // active sockets. | 475 // active sockets. |
473 MessageLoopForIO::current()->WatchFileDescriptor( | 476 MessageLoopForIO::current()->WatchFileDescriptor( |
474 server_listen_pipe_, | 477 server_listen_pipe_, |
475 true, | 478 true, |
(...skipping 680 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1156 | 1159 |
1157 bool Channel::HasAcceptedConnection() const { | 1160 bool Channel::HasAcceptedConnection() const { |
1158 return channel_impl_->HasAcceptedConnection(); | 1161 return channel_impl_->HasAcceptedConnection(); |
1159 } | 1162 } |
1160 | 1163 |
1161 void Channel::ResetToAcceptingConnectionState() { | 1164 void Channel::ResetToAcceptingConnectionState() { |
1162 channel_impl_->ResetToAcceptingConnectionState(); | 1165 channel_impl_->ResetToAcceptingConnectionState(); |
1163 } | 1166 } |
1164 | 1167 |
1165 } // namespace IPC | 1168 } // namespace IPC |
OLD | NEW |