Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(19)

Side by Side Diff: base/linux_util.cc

Issue 312002: Move FileDescriptorGetInode() and FindProcessHoldingSocket() into base/linux_... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « base/linux_util.h ('k') | chrome/browser/renderer_host/render_crash_handler_host_linux.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2009 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 "base/linux_util.h" 5 #include "base/linux_util.h"
6 6
7 #include <dirent.h>
8 #include <errno.h>
7 #include <stdlib.h> 9 #include <stdlib.h>
10 #include <sys/stat.h>
11 #include <sys/types.h>
12 #include <unistd.h>
8 13
9 #include <vector> 14 #include <vector>
10 15
11 #include "base/command_line.h" 16 #include "base/command_line.h"
12 #include "base/lock.h" 17 #include "base/lock.h"
13 #include "base/process_util.h" 18 #include "base/process_util.h"
14 #include "base/singleton.h" 19 #include "base/singleton.h"
15 #include "base/string_util.h" 20 #include "base/string_util.h"
16 21
17 namespace { 22 namespace {
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
85 DCHECK(state_ == STATE_CHECK_STARTED); 90 DCHECK(state_ == STATE_CHECK_STARTED);
86 state_ = STATE_CHECK_FINISHED; 91 state_ = STATE_CHECK_FINISHED;
87 } 92 }
88 93
89 private: 94 private:
90 Lock lock_; 95 Lock lock_;
91 LinuxDistroState state_; 96 LinuxDistroState state_;
92 }; 97 };
93 #endif // if defined(OS_LINUX) 98 #endif // if defined(OS_LINUX)
94 99
100 // expected prefix of the target of the /proc/self/fd/%d link for a socket
101 static const char kSocketLinkPrefix[] = "socket:[";
102
103 // Parse a symlink in /proc/pid/fd/$x and return the inode number of the
104 // socket.
105 // inode_out: (output) set to the inode number on success
106 // path: e.g. /proc/1234/fd/5 (must be a UNIX domain socket descriptor)
107 // log: if true, log messages about failure details
108 bool ProcPathGetInode(ino_t* inode_out, const char* path, bool log = false) {
109 DCHECK(inode_out);
110 DCHECK(path);
111
112 char buf[256];
113 const ssize_t n = readlink(path, buf, sizeof(buf) - 1);
114 if (n == -1) {
115 if (log) {
116 LOG(WARNING) << "Failed to read the inode number for a socket from /proc"
117 "(" << errno << ")";
118 }
119 return false;
120 }
121 buf[n] = 0;
122
123 if (memcmp(kSocketLinkPrefix, buf, sizeof(kSocketLinkPrefix) - 1)) {
124 if (log) {
125 LOG(WARNING) << "The descriptor passed from the crashing process wasn't a"
126 " UNIX domain socket.";
127 }
128 return false;
129 }
130
131 char *endptr;
132 const unsigned long long int inode_ul =
133 strtoull(buf + sizeof(kSocketLinkPrefix) - 1, &endptr, 10);
134 if (*endptr != ']')
135 return false;
136
137 if (inode_ul == ULLONG_MAX) {
138 if (log) {
139 LOG(WARNING) << "Failed to parse a socket's inode number: the number was "
140 "too large. Please report this bug: " << buf;
141 }
142 return false;
143 }
144
145 *inode_out = inode_ul;
146 return true;
147 }
148
95 } // anonymous namespace 149 } // anonymous namespace
96 150
97 namespace base { 151 namespace base {
98 152
99 uint8_t* BGRAToRGBA(const uint8_t* pixels, int width, int height, int stride) { 153 uint8_t* BGRAToRGBA(const uint8_t* pixels, int width, int height, int stride) {
100 if (stride == 0) 154 if (stride == 0)
101 stride = width * 4; 155 stride = width * 4;
102 156
103 uint8_t* new_pixels = static_cast<uint8_t*>(malloc(height * stride)); 157 uint8_t* new_pixels = static_cast<uint8_t*>(malloc(height * stride));
104 158
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
202 case DESKTOP_ENVIRONMENT_KDE4: 256 case DESKTOP_ENVIRONMENT_KDE4:
203 return "KDE4"; 257 return "KDE4";
204 } 258 }
205 return NULL; 259 return NULL;
206 } 260 }
207 261
208 const char* GetDesktopEnvironmentName(EnvironmentVariableGetter* env) { 262 const char* GetDesktopEnvironmentName(EnvironmentVariableGetter* env) {
209 return GetDesktopEnvironmentName(GetDesktopEnvironment(env)); 263 return GetDesktopEnvironmentName(GetDesktopEnvironment(env));
210 } 264 }
211 265
266 bool FileDescriptorGetInode(ino_t* inode_out, int fd) {
267 DCHECK(inode_out);
268
269 struct stat buf;
270 if (fstat(fd, &buf) < 0)
271 return false;
272
273 if (!S_ISSOCK(buf.st_mode))
274 return false;
275
276 *inode_out = buf.st_ino;
277 return true;
278 }
279
280 bool FindProcessHoldingSocket(pid_t* pid_out, ino_t socket_inode) {
281 DCHECK(pid_out);
282 bool already_found = false;
283
284 DIR* proc = opendir("/proc");
285 if (!proc) {
286 LOG(WARNING) << "Cannot open /proc";
287 return false;
288 }
289
290 std::vector<pid_t> pids;
291
292 struct dirent* dent;
293 while ((dent = readdir(proc))) {
294 char *endptr;
295 const unsigned long int pid_ul = strtoul(dent->d_name, &endptr, 10);
296 if (pid_ul == ULONG_MAX || *endptr)
297 continue;
298 pids.push_back(pid_ul);
299 }
300 closedir(proc);
301
302 for (std::vector<pid_t>::const_iterator
303 i = pids.begin(); i != pids.end(); ++i) {
304 const pid_t current_pid = *i;
305 char buf[256];
306 snprintf(buf, sizeof(buf), "/proc/%d/fd", current_pid);
307 DIR* fd = opendir(buf);
308 if (!fd)
309 continue;
310
311 while ((dent = readdir(fd))) {
312 if (snprintf(buf, sizeof(buf), "/proc/%d/fd/%s", current_pid,
313 dent->d_name) >= static_cast<int>(sizeof(buf))) {
314 continue;
315 }
316
317 ino_t fd_inode;
318 if (ProcPathGetInode(&fd_inode, buf)) {
319 if (fd_inode == socket_inode) {
320 if (already_found) {
321 closedir(fd);
322 return false;
323 }
324
325 already_found = true;
326 *pid_out = current_pid;
327 break;
328 }
329 }
330 }
331
332 closedir(fd);
333 }
334
335 return already_found;
336 }
337
212 } // namespace base 338 } // namespace base
OLDNEW
« no previous file with comments | « base/linux_util.h ('k') | chrome/browser/renderer_host/render_crash_handler_host_linux.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698