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 (IGNORE_EINTR(close(socket_fd
)) < 0) {
82 PLOG(ERROR
) << "close";
88 virtual void Unlock() OVERRIDE
{
90 DLOG(ERROR
) << "Over-unlocked MultiProcessLock - " << name_
;
93 if (IGNORE_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
);