1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/common/multi_process_lock.h"
8 #include <sys/socket.h>
12 #include "base/compiler_specific.h"
13 #include "base/logging.h"
14 #include "base/posix/eintr_wrapper.h"
16 class MultiProcessLockLinux : public MultiProcessLock {
18 explicit MultiProcessLockLinux(const std::string& name)
19 : name_(name), fd_(-1) { }
21 virtual ~MultiProcessLockLinux() {
27 virtual bool TryLock() OVERRIDE {
28 struct sockaddr_un address;
30 // +1 for terminator, +1 for 0 in position 0 that makes it an
31 // abstract named socket.
32 const size_t max_len = sizeof(address.sun_path) - 2;
35 DLOG(ERROR) << "MultiProcessLock is already locked - " << name_;
39 if (name_.length() > max_len) {
40 LOG(ERROR) << "Socket name too long (" << name_.length()
41 << " > " << max_len << ") - " << name_;
45 memset(&address, 0, sizeof(address));
46 int print_length = snprintf(&address.sun_path[1],
50 if (print_length < 0 ||
51 print_length > static_cast<int>(max_len)) {
52 PLOG(ERROR) << "Couldn't create sun_path - " << name_;
56 // Must set the first character of the path to something non-zero
57 // before we call SUN_LEN which depends on strcpy working.
58 address.sun_path[0] = '@';
59 size_t length = SUN_LEN(&address);
61 // Reset the first character of the path back to zero so that
62 // bind returns an abstract name socket.
63 address.sun_path[0] = 0;
64 address.sun_family = AF_LOCAL;
66 int socket_fd = socket(AF_LOCAL, SOCK_STREAM, 0);
68 PLOG(ERROR) << "Couldn't create socket - " << name_;
73 reinterpret_cast<sockaddr *>(&address),
78 DVLOG(1) << "Couldn't bind socket - "
79 << &(address.sun_path[1])
80 << " Length: " << length;
81 if (HANDLE_EINTR(close(socket_fd)) < 0) {
82 PLOG(ERROR) << "close";
88 virtual void Unlock() OVERRIDE {
90 DLOG(ERROR) << "Over-unlocked MultiProcessLock - " << name_;
93 if (HANDLE_EINTR(close(fd_)) < 0) {
94 DPLOG(ERROR) << "close";
102 DISALLOW_COPY_AND_ASSIGN(MultiProcessLockLinux);
105 MultiProcessLock* MultiProcessLock::Create(const std::string &name) {
106 return new MultiProcessLockLinux(name);