diff options
Diffstat (limited to 'dom/system/gonk/OpenFileFinder.cpp')
-rw-r--r-- | dom/system/gonk/OpenFileFinder.cpp | 251 |
1 files changed, 0 insertions, 251 deletions
diff --git a/dom/system/gonk/OpenFileFinder.cpp b/dom/system/gonk/OpenFileFinder.cpp deleted file mode 100644 index 388e813e1..000000000 --- a/dom/system/gonk/OpenFileFinder.cpp +++ /dev/null @@ -1,251 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "OpenFileFinder.h" - -#include "mozilla/FileUtils.h" -#include "nsPrintfCString.h" - -#include <sys/stat.h> -#include <errno.h> - -#undef USE_DEBUG -#define USE_DEBUG 0 - -#undef LOG -#undef LOGW -#undef ERR -#define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "OpenFileFinder", ## args) -#define LOGW(args...) __android_log_print(ANDROID_LOG_WARN, "OpenFileFinder", ## args) -#define ERR(args...) __android_log_print(ANDROID_LOG_ERROR, "OpenFileFinder", ## args) - -#undef DBG -#if USE_DEBUG -#define DBG(args...) __android_log_print(ANDROID_LOG_DEBUG, "OpenFileFinder" , ## args) -#else -#define DBG(args...) -#endif - -namespace mozilla { -namespace system { - -OpenFileFinder::OpenFileFinder(const nsACString& aPath, - bool aCheckIsB2gOrDescendant /* = true */) - : mPath(aPath), - mProcDir(nullptr), - mFdDir(nullptr), - mPid(0), - mCheckIsB2gOrDescendant(aCheckIsB2gOrDescendant) -{ - // We assume that we're running in the parent process - mMyPid = getpid(); -} - -OpenFileFinder::~OpenFileFinder() -{ - Close(); -} - -bool -OpenFileFinder::First(OpenFileFinder::Info* aInfo) -{ - Close(); - - mProcDir = opendir("/proc"); - if (!mProcDir) { - return false; - } - mState = NEXT_PID; - return Next(aInfo); -} - -bool -OpenFileFinder::Next(OpenFileFinder::Info* aInfo) -{ - // NOTE: This function calls readdir and readlink, neither of which should - // block since we're using the proc filesystem, which is a purely - // kernel in-memory filesystem and doesn't depend on external driver - // behaviour. - while (mState != DONE) { - switch (mState) { - case NEXT_PID: { - struct dirent *pidEntry; - pidEntry = readdir(mProcDir); - if (!pidEntry) { - mState = DONE; - break; - } - char *endPtr; - mPid = strtol(pidEntry->d_name, &endPtr, 10); - if (mPid == 0 || *endPtr != '\0') { - // Not a +ve number - ignore - continue; - } - // We've found a /proc/PID directory. Scan open file descriptors. - if (mFdDir) { - closedir(mFdDir); - } - nsPrintfCString fdDirPath("/proc/%d/fd", mPid); - mFdDir = opendir(fdDirPath.get()); - if (!mFdDir) { - continue; - } - mState = CHECK_FDS; - } - // Fall through - case CHECK_FDS: { - struct dirent *fdEntry; - while((fdEntry = readdir(mFdDir))) { - if (!strcmp(fdEntry->d_name, ".") || - !strcmp(fdEntry->d_name, "..")) { - continue; - } - nsPrintfCString fdSymLink("/proc/%d/fd/%s", mPid, fdEntry->d_name); - nsCString resolvedPath; - if (ReadSymLink(fdSymLink, resolvedPath) && PathMatches(resolvedPath)) { - // We found an open file contained within the directory tree passed - // into the constructor. - FillInfo(aInfo, resolvedPath); - // If sCheckIsB2gOrDescendant is set false, the caller cares about - // all processes which have open files. If sCheckIsB2gOrDescendant - // is set false, we only care about the b2g proccess or its descendants. - if (!mCheckIsB2gOrDescendant || aInfo->mIsB2gOrDescendant) { - return true; - } - LOG("Ignore process(%d), not a b2g process or its descendant.", - aInfo->mPid); - } - } - // We've checked all of the files for this pid, move onto the next one. - mState = NEXT_PID; - continue; - } - case DONE: - default: - mState = DONE; // covers the default case - break; - } - } - return false; -} - -void -OpenFileFinder::Close() -{ - if (mFdDir) { - closedir(mFdDir); - } - if (mProcDir) { - closedir(mProcDir); - } -} - -void -OpenFileFinder::FillInfo(OpenFileFinder::Info* aInfo, const nsACString& aPath) -{ - aInfo->mFileName = aPath; - aInfo->mPid = mPid; - nsPrintfCString exePath("/proc/%d/exe", mPid); - ReadSymLink(exePath, aInfo->mExe); - aInfo->mComm.Truncate(); - aInfo->mAppName.Truncate(); - nsPrintfCString statPath("/proc/%d/stat", mPid); - nsCString statString; - statString.SetLength(200); - char *stat = statString.BeginWriting(); - if (!stat) { - return; - } - ReadSysFile(statPath.get(), stat, statString.Length()); - // The stat line includes the comm field, surrounded by parenthesis. - // However, the contents of the comm field itself is arbitrary and - // and can include ')', so we search for the rightmost ) as being - // the end of the comm field. - char *closeParen = strrchr(stat, ')'); - if (!closeParen) { - return; - } - char *openParen = strchr(stat, '('); - if (!openParen) { - return; - } - if (openParen >= closeParen) { - return; - } - nsDependentCSubstring comm(&openParen[1], closeParen - openParen - 1); - aInfo->mComm = comm; - // There is a single character field after the comm and then - // the parent pid (the field we're interested in). - // ) X ppid - // 01234 - int ppid = atoi(&closeParen[4]); - - if (mPid == mMyPid) { - // This is chrome process - aInfo->mIsB2gOrDescendant = true; - DBG("Chrome process has open file(s)"); - return; - } - // For the rest (non-chrome process), we recursively check the ppid to know - // it is a descendant of b2g or not. See bug 931456. - while (ppid != mMyPid && ppid != 1) { - DBG("Process(%d) is not forked from b2g(%d) or Init(1), keep looking", - ppid, mMyPid); - nsPrintfCString ppStatPath("/proc/%d/stat", ppid); - ReadSysFile(ppStatPath.get(), stat, statString.Length()); - closeParen = strrchr(stat, ')'); - if (!closeParen) { - return; - } - ppid = atoi(&closeParen[4]); - } - if (ppid == 1) { - // This is a not a b2g process. - DBG("Non-b2g process has open file(s)"); - aInfo->mIsB2gOrDescendant = false; - return; - } - if (ppid == mMyPid) { - // This is a descendant of b2g. - DBG("Child process of chrome process has open file(s)"); - aInfo->mIsB2gOrDescendant = true; - } - - // This looks like a content process. The comm field will be the - // app name. - aInfo->mAppName = aInfo->mComm; -} - -bool -OpenFileFinder::ReadSymLink(const nsACString& aSymLink, nsACString& aOutPath) -{ - aOutPath.Truncate(); - const char *symLink = aSymLink.BeginReading(); - - // Verify that we actually have a symlink. - struct stat st; - if (lstat(symLink, &st)) { - return false; - } - if ((st.st_mode & S_IFMT) != S_IFLNK) { - return false; - } - - // Contrary to the documentation st.st_size doesn't seem to be a reliable - // indication of the length when reading from /proc, so we use a fixed - // size buffer instead. - - char resolvedSymLink[PATH_MAX]; - ssize_t pathLength = readlink(symLink, resolvedSymLink, - sizeof(resolvedSymLink) - 1); - if (pathLength <= 0) { - return false; - } - resolvedSymLink[pathLength] = '\0'; - aOutPath.Assign(resolvedSymLink); - return true; -} - -} // system -} // mozilla |