File* FileStreamWrapper::open(const String& filename, const String& mode,
                              int options, const Variant& context) {
  String fname =
    !strncmp(filename.data(), "file://", sizeof("file://") - 1)
    ? filename.substr(sizeof("file://") - 1) : filename;

  if (MemFile *file = openFromCache(fname, mode)) {
    return file;
  }

  if (options & File::USE_INCLUDE_PATH) {
    struct stat s;
    String resolved_fname = resolveVmInclude(fname.get(), "", &s);
    if (!resolved_fname.isNull()) {
      fname = resolved_fname;
    }
  }

  std::unique_ptr<PlainFile> file(NEWOBJ(PlainFile)());
  bool ret = file->open(File::TranslatePath(fname), mode);
  if (!ret) {
    raise_warning("%s", file->getLastError().c_str());
    return nullptr;
  }
  return file.release();
}
예제 #2
0
SmartPtr<File>
FileStreamWrapper::open(const String& filename, const String& mode,
                        int options, const SmartPtr<StreamContext>& context) {
  String fname;
  if (StringUtil::IsFileUrl(filename)) {
    fname = StringUtil::DecodeFileUrl(filename);
    if (fname.empty()) {
      raise_warning("invalid file:// URL");
      return nullptr;
    }
  } else {
    fname = filename;
  }

  if (auto file = openFromCache(fname, mode)) {
    return file;
  }

  if (options & File::USE_INCLUDE_PATH) {
    struct stat s;
    String resolved_fname = resolveVmInclude(fname.get(), "", &s);
    if (!resolved_fname.isNull()) {
      fname = resolved_fname;
    }
  }

  auto file = makeSmartPtr<PlainFile>();
  bool ret = file->open(File::TranslatePath(fname), mode);
  if (!ret) {
    raise_warning("%s", file->getLastError().c_str());
    return nullptr;
  }
  return file;
}
예제 #3
0
Variant f_stream_resolve_include_path(const String& filename,
                                     const Resource& context /* = null_object */) {
  struct stat s;
  String ret = resolveVmInclude(filename.get(), "", &s, true);
  if (ret.isNull()) {
    return false;
  }
  return ret;
}
예제 #4
0
파일: unit-cache.cpp 프로젝트: shixiao/hhvm
Unit* lookupUnit(StringData* path, const char* currentDir, bool* initial_opt) {
  bool init;
  bool& initial = initial_opt ? *initial_opt : init;
  initial = true;

  /*
   * NB: the m_evaledFiles map is only for the debugger, and could be omitted
   * in RepoAuthoritative mode, but currently isn't.
   */

  struct stat s;
  auto const spath = resolveVmInclude(path, currentDir, &s);
  if (spath.isNull()) return nullptr;

  auto const eContext = g_context.getNoCheck();

  // Check if this file has already been included.
  auto it = eContext->m_evaledFiles.find(spath.get());
  if (it != end(eContext->m_evaledFiles)) {
    initial = false;
    return it->second;
  }

  // This file hasn't been included yet, so we need to parse the file
  auto const cunit = checkoutFile(spath.get(), s);
  if (cunit.unit && initial_opt) {
    // if initial_opt is not set, this shouldn't be recorded as a
    // per request fetch of the file.
    if (rds::testAndSetBit(cunit.rdsBitId)) {
      initial = false;
    }
    // if parsing was successful, update the mappings for spath and
    // rpath (if it exists).
    eContext->m_evaledFilesOrder.push_back(cunit.unit->filepath());
    eContext->m_evaledFiles[spath.get()] = cunit.unit;
    spath.get()->incRefCount();
    if (!cunit.unit->filepath()->same(spath.get())) {
      eContext->m_evaledFiles[cunit.unit->filepath()] = cunit.unit;
    }
    if (g_system_profiler) {
      g_system_profiler->fileLoadCallBack(path->toCppString());
    }
    DEBUGGER_ATTACHED_ONLY(phpDebuggerFileLoadHook(cunit.unit));
  }

  return cunit.unit;
}
예제 #5
0
파일: ext_hh.cpp 프로젝트: wonhyo/hhvm
bool HHVM_FUNCTION(could_include, const String& file) {
  struct stat s;
  return !resolveVmInclude(file.get(), "", &s).isNull();
}
예제 #6
0
파일: unit-cache.cpp 프로젝트: QiuYe/hhvm
Unit* lookupUnit(StringData* path, const char* currentDir, bool* initial_opt) {
  bool init;
  bool& initial = initial_opt ? *initial_opt : init;
  initial = true;

  /*
   * NB: the m_evaledFiles map is only for the debugger, and could be omitted
   * in RepoAuthoritative mode, but currently isn't.
   */

  struct stat s;
  auto const spath = resolveVmInclude(path, currentDir, &s);
  if (spath.isNull()) return nullptr;

  auto const eContext = g_context.getNoCheck();

  // Check if this file has already been included.
  auto it = eContext->m_evaledFiles.find(spath.get());
  if (it != end(eContext->m_evaledFiles)) {
    initial = false;
    return it->second;
  }

  // We didn't find it, so try the realpath.
  auto const alreadyResolved =
    RuntimeOption::RepoAuthoritative ||
    (!RuntimeOption::CheckSymLink && (spath[0] == '/'));
  bool hasRealpath = false;
  String rpath;
  if (!alreadyResolved) {
    std::string rp = StatCache::realpath(spath.data());
    if (rp.size() != 0) {
      rpath = StringData::Make(rp.data(), rp.size(), CopyString);
      if (!rpath.same(spath)) {
        hasRealpath = true;
        it = eContext->m_evaledFiles.find(rpath.get());
        if (it != eContext->m_evaledFiles.end()) {
          // We found it! Update the mapping for spath and return the
          // unit.
          auto const unit = it->second;
          spath.get()->incRefCount();
          eContext->m_evaledFiles[spath.get()] = unit;
          initial = false;
          return unit;
        }
      }
    }
  }

  // This file hasn't been included yet, so we need to parse the file
  auto const cunit = checkoutFile(hasRealpath ? rpath.get() : spath.get(), s);
  if (cunit.unit && initial_opt) {
    // if initial_opt is not set, this shouldn't be recorded as a
    // per request fetch of the file.
    if (RDS::testAndSetBit(cunit.rdsBitId)) {
      initial = false;
    }
    // if parsing was successful, update the mappings for spath and
    // rpath (if it exists).
    eContext->m_evaledFilesOrder.push_back(cunit.unit->filepath());
    eContext->m_evaledFiles[spath.get()] = cunit.unit;
    spath.get()->incRefCount();
    if (hasRealpath) {
      eContext->m_evaledFiles[rpath.get()] = cunit.unit;
      rpath.get()->incRefCount();
    }
    DEBUGGER_ATTACHED_ONLY(phpDebuggerFileLoadHook(cunit.unit));
  }

  return cunit.unit;
}