String f_shell_exec(CStrRef cmd) { ShellExecContext ctx; FILE *fp = ctx.exec(cmd.c_str()); if (!fp) return ""; StringBuffer sbuf; sbuf.read(fp); return sbuf.detach(); }
CachedUnit createUnitFromUrl(const StringData* const requestedPath) { auto const w = Stream::getWrapperFromURI(StrNR(requestedPath)); if (!w) return CachedUnit{}; auto const f = w->open(StrNR(requestedPath), "r", 0, null_variant); if (!f) return CachedUnit{}; StringBuffer sb; sb.read(f); return createUnitFromString(requestedPath->data(), sb.detach()); }
Variant HHVM_FUNCTION(shell_exec, const String& cmd) { ShellExecContext ctx; FILE *fp = ctx.exec(cmd); if (!fp) return init_null(); StringBuffer sbuf; sbuf.read(fp); auto ret = sbuf.detach(); if (ret.empty() && !RuntimeOption::EnableHipHopSyntax) { // Match php5 return init_null(); } return ret; }
CachedUnit createUnitFromUrl(const StringData* const requestedPath, const Native::FuncTable& nativeFuncs, FileLoadFlags& flags) { auto const w = Stream::getWrapperFromURI(StrNR(requestedPath)); StringBuffer sb; { // Stream wrappers can reenter PHP via user defined callbacks. Roll this // operation into a single event rqtrace::EventGuard trace{"STREAM_WRAPPER_OPEN"}; rqtrace::DisableTracing disable; if (!w) return CachedUnit{}; auto const f = w->open(StrNR(requestedPath), "r", 0, nullptr); if (!f) return CachedUnit{}; sb.read(f.get()); } OptLog ent; return createUnitFromString(requestedPath->data(), sb.detach(), nullptr, ent, nativeFuncs, RepoOptions::defaults(), flags); }
Variant f_stream_get_contents(CResRef handle, int maxlen /* = -1 */, int offset /* = -1 */) { if (maxlen < -1) { throw_invalid_argument("maxlen: %d", maxlen); return false; } if (maxlen == 0) { return String(); } File *file = handle.getTyped<File>(false /* nullOkay */, true /* badTypeOkay */); if (!file) { throw_invalid_argument( "stream_get_contents() expects parameter 1 to be a resource"); return false; } if (offset >= 0 && !file->seek(offset, SEEK_SET) ) { raise_warning("Failed to seek to position %d in the stream", offset); return false; } String ret; if (maxlen != -1) { ret = String(maxlen, ReserveString); char *buf = ret.bufferSlice().ptr; maxlen = file->readImpl(buf, maxlen); if (maxlen < 0) { return false; } ret.setSize(maxlen); } else { StringBuffer sb; sb.read(file); ret = sb.detach(); } return ret; }
bool TestExtProcess::test_proc_open_env_inh() { Array descriptorspec = CREATE_MAP3(0, CREATE_VECTOR2("pipe", "r"), 1, CREATE_VECTOR2("pipe", "w"), 2, CREATE_VECTOR3("file", "/tmp/error-output.txt", "a")); Variant pipes; g_context->setenv("inherit_me", "please"); Variant process = f_proc_open("echo $inherit_me", descriptorspec, ref(pipes)); VERIFY(!same(process, false)); { File *f = pipes[1].toObject().getTyped<File>(); VERIFY(f->valid()); StringBuffer sbuf; sbuf.read(f); f->close(); VS(sbuf.detach(), "please\n"); } VS(f_proc_close(process.toObject()), 0); return Count(true); }
PhpFile *FileRepository::checkoutFile(StringData *rname, const struct stat &s) { FileInfo fileInfo; PhpFile *ret = nullptr; String name(rname); bool isPlainFile = File::IsPlainFilePath(name); if (isPlainFile) { if (rname->data()[0] != '/') { name = String(SourceRootInfo::GetCurrentSourceRoot()) + name; } // Get the common fast path out of the way with as little locking // as possible: it's in the map and has not changed on disk ParsedFilesMap::const_accessor acc; if (s_files.find(acc, name.get()) && !acc->second->isChanged(s)) { TRACE(1, "FR fast path hit %s\n", rname->data()); ret = acc->second->getPhpFile(); return ret; } } else { // Do the read before we get the repo lock, since it will call into the // stream library and will needs its own locks. if (isAuthoritativeRepo()) { throw FatalErrorException( "including urls doesn't work in RepoAuthoritative mode" ); } Stream::Wrapper* w = Stream::getWrapperFromURI(name); File* f = w->open(name, "r", 0, null_variant); if (!f) return nullptr; StringBuffer sb; sb.read(f); fileInfo.m_inputString = sb.detach(); computeMd5(name.get(), fileInfo); } TRACE(1, "FR fast path miss: %s\n", rname->data()); const StringData *n = makeStaticString(name.get()); PhpFile* toKill = nullptr; SCOPE_EXIT { // run this after acc is destroyed (and its lock released) if (toKill) toKill->decRefAndDelete(); }; ParsedFilesMap::accessor acc; bool isNew = s_files.insert(acc, n); PhpFileWrapper* old = acc->second; SCOPE_EXIT { // run this just before acc is released if (old && old != acc->second) { if (old->getPhpFile() != acc->second->getPhpFile()) { toKill = old->getPhpFile(); } delete old; } if (!acc->second) s_files.erase(acc); }; assert(isNew || old); // We don't leave null entries around. bool isChanged = !isNew && old->isChanged(s); if (isNew || isChanged) { if (isPlainFile && !readFile(n, s, fileInfo)) { TRACE(1, "File disappeared between stat and FR::readNewFile: %s\n", rname->data()); return nullptr; } ret = fileInfo.m_phpFile; if (isChanged && ret == old->getPhpFile()) { // The file changed but had the same contents. if (debug && md5Enabled()) { ReadLock lock(s_md5Lock); assert(s_md5Files.find(ret->getMd5())->second == ret); } return ret; } } else if (!isNew) { // Somebody might have loaded the file between when we dropped // our read lock and got the write lock ret = old->getPhpFile(); return ret; } // If we get here the file was not in s_files or has changed on disk if (!ret) { // Try to read Unit from .hhbc repo. ret = readHhbc(n->data(), fileInfo); } if (!ret) { if (isAuthoritativeRepo()) { raise_error("Tried to parse %s in repo authoritative mode", n->data()); } ret = parseFile(n->data(), fileInfo); if (!ret) return nullptr; } assert(ret != nullptr); if (isNew) { acc->second = new PhpFileWrapper(s, ret); ret->incRef(); ret->setId(Transl::TargetCache::allocBit()); } else { PhpFile *f = old->getPhpFile(); if (f != ret) { ret->setId(f->getId()); ret->incRef(); } acc->second = new PhpFileWrapper(s, ret); } if (md5Enabled()) { WriteLock lock(s_md5Lock); s_md5Files[ret->getMd5()] = ret; } return ret; }