OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/unix_domain_socket_util.h" | 5 #include "ipc/unix_domain_socket_util.h" |
6 | 6 |
7 #include <errno.h> | 7 #include <errno.h> |
8 #include <sys/socket.h> | 8 #include <sys/socket.h> |
9 #include <sys/stat.h> | |
10 #include <sys/un.h> | 9 #include <sys/un.h> |
11 #include <unistd.h> | 10 #include <unistd.h> |
12 | 11 |
13 #include "base/files/file_path.h" | 12 #include "base/files/file_path.h" |
14 #include "base/files/file_util.h" | 13 #include "base/files/file_util.h" |
15 #include "base/files/scoped_file.h" | 14 #include "base/files/scoped_file.h" |
16 #include "base/logging.h" | 15 #include "base/logging.h" |
17 #include "base/posix/eintr_wrapper.h" | 16 #include "base/posix/eintr_wrapper.h" |
18 #include "build/build_config.h" | 17 #include "build/build_config.h" |
19 | 18 |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
60 | 59 |
61 // Create unix_addr structure. | 60 // Create unix_addr structure. |
62 memset(unix_addr, 0, sizeof(struct sockaddr_un)); | 61 memset(unix_addr, 0, sizeof(struct sockaddr_un)); |
63 unix_addr->sun_family = AF_UNIX; | 62 unix_addr->sun_family = AF_UNIX; |
64 strncpy(unix_addr->sun_path, socket_name.c_str(), kMaxSocketNameLength); | 63 strncpy(unix_addr->sun_path, socket_name.c_str(), kMaxSocketNameLength); |
65 *unix_addr_len = | 64 *unix_addr_len = |
66 offsetof(struct sockaddr_un, sun_path) + socket_name.length(); | 65 offsetof(struct sockaddr_un, sun_path) + socket_name.length(); |
67 return fd.release(); | 66 return fd.release(); |
68 } | 67 } |
69 | 68 |
| 69 bool IsRecoverableError() { |
| 70 return errno == ECONNABORTED || errno == EMFILE || errno == ENFILE || |
| 71 errno == ENOMEM || errno == ENOBUFS; |
| 72 } |
| 73 |
70 } // namespace | 74 } // namespace |
71 | 75 |
72 bool CreateServerUnixDomainSocket(const base::FilePath& socket_path, | 76 bool CreateServerUnixDomainSocket(const base::FilePath& socket_path, |
73 int* server_listen_fd) { | 77 int* server_listen_fd) { |
74 DCHECK(server_listen_fd); | 78 DCHECK(server_listen_fd); |
75 | 79 |
76 std::string socket_name = socket_path.value(); | 80 std::string socket_name = socket_path.value(); |
77 base::FilePath socket_dir = socket_path.DirName(); | 81 base::FilePath socket_dir = socket_path.DirName(); |
78 | 82 |
79 struct sockaddr_un unix_addr; | 83 struct sockaddr_un unix_addr; |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
165 uid_t peer_euid; | 169 uid_t peer_euid; |
166 if (!GetPeerEuid(peer_fd, &peer_euid)) | 170 if (!GetPeerEuid(peer_fd, &peer_euid)) |
167 return false; | 171 return false; |
168 if (peer_euid != geteuid()) { | 172 if (peer_euid != geteuid()) { |
169 DLOG(ERROR) << "Client euid is not authorised"; | 173 DLOG(ERROR) << "Client euid is not authorised"; |
170 return false; | 174 return false; |
171 } | 175 } |
172 return true; | 176 return true; |
173 } | 177 } |
174 | 178 |
175 bool IsRecoverableError(int err) { | |
176 return errno == ECONNABORTED || errno == EMFILE || errno == ENFILE || | |
177 errno == ENOMEM || errno == ENOBUFS; | |
178 } | |
179 | |
180 bool ServerAcceptConnection(int server_listen_fd, int* server_socket) { | 179 bool ServerAcceptConnection(int server_listen_fd, int* server_socket) { |
181 DCHECK(server_socket); | 180 DCHECK(server_socket); |
182 *server_socket = -1; | 181 *server_socket = -1; |
183 | 182 |
184 base::ScopedFD accept_fd(HANDLE_EINTR(accept(server_listen_fd, NULL, 0))); | 183 base::ScopedFD accept_fd(HANDLE_EINTR(accept(server_listen_fd, NULL, 0))); |
185 if (!accept_fd.is_valid()) | 184 if (!accept_fd.is_valid()) |
186 return IsRecoverableError(errno); | 185 return IsRecoverableError(); |
187 if (!base::SetNonBlocking(accept_fd.get())) { | 186 if (!base::SetNonBlocking(accept_fd.get())) { |
188 PLOG(ERROR) << "base::SetNonBlocking() failed " << accept_fd.get(); | 187 PLOG(ERROR) << "base::SetNonBlocking() failed " << accept_fd.get(); |
189 // It's safe to keep listening on |server_listen_fd| even if the attempt to | 188 // It's safe to keep listening on |server_listen_fd| even if the attempt to |
190 // set O_NONBLOCK failed on the client fd. | 189 // set O_NONBLOCK failed on the client fd. |
191 return true; | 190 return true; |
192 } | 191 } |
193 | 192 |
194 *server_socket = accept_fd.release(); | 193 *server_socket = accept_fd.release(); |
195 return true; | 194 return true; |
196 } | 195 } |
197 | 196 |
198 } // namespace IPC | 197 } // namespace IPC |
OLD | NEW |