コード例 #1
0
static boolean CheckSymLink(int pid, const char* mountPoint, const char* name, const char* message)
{
    char    path[PATH_MAX];
    char    link[PATH_MAX];

    sprintf(path, "/proc/%d/%s", pid, name);
    if (ReadSymLink(path, link) && PathMatchesMountPoint(link, mountPoint)) 
    {
        char    name[PATH_MAX];
        GetProcessName(pid, name);
        LOG_ERROR("process %s (%d) has %s in %s\n", name, pid, message, mountPoint);
        return true;
    }
    else
        return false;
}
コード例 #2
0
static boolean CheckFileDescriptorSymLinks(int pid, const char* mountPoint)
{
    DIR*    dir;
    struct dirent* de;
    boolean fileOpen = false;
    char    path[PATH_MAX];
    char    link[PATH_MAX];
    int     parent_length;

    // compute path to process's directory of open files
    sprintf(path, "/proc/%d/fd", pid);
    dir = opendir(path);
    if (!dir)
        return false;

    // remember length of the path
    parent_length = strlen(path);
    // append a trailing '/'
    path[parent_length++] = '/';
    
    while ((de = readdir(dir)) != 0 && !fileOpen) {
        if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, ".."))
            continue;
        
        // append the file name, after truncating to parent directory
        path[parent_length] = 0;
        strcat(path, de->d_name);

        if (ReadSymLink(path, link) && PathMatchesMountPoint(link, mountPoint))
        {
            char    name[PATH_MAX];
            GetProcessName(pid, name);
            LOG_ERROR("process %s (%d) has open file %s\n", name, pid, link);
            fileOpen = true;
        }
    }

    closedir(dir);
    return fileOpen;
}
コード例 #3
0
ファイル: OpenFileFinder.cpp プロジェクト: JaminLiu/gecko-dev
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;
}
コード例 #4
0
ファイル: progname.c プロジェクト: BackupTheBerlios/texlive
expand_symlinks P1C(char *, s)
{
  static char pre[BSIZE];	/* return value */
  char post[BSIZE], sym[BSIZE], tmp[BSIZE], before[BSIZE];
  char *cp;
  char a;
  struct stat st;
  int done;

  /* Check for symlink loops.  It's difficult to check for all the
     possibilities ourselves, so let the kernel do it.  And make it
     conditional so that people can see where the infinite loop is
     being caused (see engtools#1536).  */
  if (!ll_loop) {
    FILE *f = fopen (s, "r");
    if (!f && errno == ELOOP) {
      /* Not worried about other errors, we'll get to them in due course.  */
      perror (s);
      return NULL;
    }
    if (f) fclose (f);
  }

  strcpy (post, s);
  strcpy (pre, "");

  while (strlen (post) != 0) {
    CopyFirst (pre, post);

    if (lstat (pre, &st) != 0) {
      fprintf (stderr, "lstat(%s) failed ...\n", pre);
      perror (pre);
      return NULL;
    }

    if (S_ISLNK (st.st_mode)) {
      ReadSymLink (pre, sym);

      if (!strncmp (sym, "/", 1)) {
        if (ll_verbose)
          printf ("[%s]%s%s -> [%s]%s%s\n", pre, EXPOS, post, sym, EXPOS,post);
        strcpy (pre, "");

      } else {
        a = pre[0];	/* handle links through the root */
        strcpy (tmp, StripLast (pre));
        if (!strlen (pre) && a == '/')
          strcpy (pre, "/");

        if (ll_verbose) {
          sprintf (before, "%s%s[%s]%s%s", pre, EXPRE, tmp, EXPOS, post);
          printf ("%s -> %s%s[%s]%s%s\n", before, pre, EXPRE, sym, EXPOS,post);
        }

        /* Strip "../" path elements from the front of sym; print
           new result if there were any such elements.  */
        done = 0;
        a = pre[0];	/* handle links through the root */
        while (!strncmp (sym, "..", 2)
               && (sym[2] == 0 || sym[2] == '/')
               && strlen (pre) != 0
               && strcmp (pre, ".")
               && strcmp (pre, "..")
               && (strlen (pre) < 3
                   || strcmp (pre + strlen (pre) - 3, "/.."))) {
          done = 1;
          StripFirst (sym);
          StripLast (pre);
        }

        if (done && ll_verbose) {
          for (cp = before; *cp;)
            *cp++ = ' ';
          if (strlen (sym))
            printf ("%s == %s%s%s%s%s\n", before, pre, EXPRE, sym, EXPOS,post);
          else
            printf ("%s == %s%s%s\n", before, pre, EXPOS, post);
        }
        if (!strlen (pre) && a == '/')
          strcpy (pre, "/");
      }

      if (strlen (post) != 0 && strlen (sym) != 0)
        strcat (sym, "/");

      strcat (sym, post);
      strcpy (post, sym);
    }
  }

  return pre;
}
コード例 #5
0
ファイル: OpenFileFinder.cpp プロジェクト: JaminLiu/gecko-dev
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;
}