int stat(const char *path, struct stat *buf) { DirectoryEntry *entry; entry = lookupFile(path); if (!entry) { errno = ENOENT; return -1; } buf->st_size = entry->length; return 0; }
int open(const char *path, int mode) { int fd; struct FileDescriptor *fdPtr; DirectoryEntry *entry; (void) mode; // mode is ignored if (!gInitialized) { if (initFileSystem() < 0) return -1; gInitialized = 1; } for (fd = 0; fd < MAX_DESCRIPTORS; fd++) { if (!gFileDescriptors[fd].isOpen) break; } if (fd == MAX_DESCRIPTORS) { // Too many files open errno = EMFILE; return -1; } fdPtr = &gFileDescriptors[fd]; // Search for file entry = lookupFile(path); if (entry) { fdPtr->isOpen = 1; fdPtr->fileLength = entry->length; fdPtr->startOffset = entry->startOffset; fdPtr->currentOffset = 0; return fd; } errno = ENOENT; return -1; }
int access(const char *path, int mode) { DirectoryEntry *entry; entry = lookupFile(path); if (!entry) { errno = ENOENT; return -1; } if (mode & W_OK) { errno = EPERM; return -1; // Read only filesystem } return 0; }
Error FileSystem::processRequest(FileSystemRequest *req) { char buf[PATHLEN]; FileSystemPath path; FileCache *cache = ZERO; File *file = ZERO; Directory *parent; FileSystemMessage *msg = req->getMessage(); // Copy the file path if ((msg->result = VMCopy(msg->from, API::Read, (Address) buf, (Address) msg->path, PATHLEN)) <= 0) { msg->result = EACCES; msg->type = IPCType; IPCMessage(msg->from, API::Send, msg, sizeof(*msg)); return msg->result; } path.parse(buf + strlen(m_mountPath)); // Do we have this file cached? if ((cache = findFileCache(&path)) || (cache = lookupFile(&path))) { file = cache->file; } // File not found else if (msg->action != CreateFile) { msg->result = ENOENT; msg->type = IPCType; IPCMessage(msg->from, API::Send, msg, sizeof(*msg)); return msg->result; } // Perform I/O on the file switch (msg->action) { case CreateFile: if (cache) msg->result = EEXIST; else { /* Attempt to create the new file. */ if ((file = createFile(msg->filetype, msg->deviceID))) { const char *p = **path.full(); insertFileCache(file, "%s", p); /* Add directory entry to our parent. */ if (path.parent()) { parent = (Directory *) findFileCache(**path.parent())->file; } else parent = (Directory *) m_root->file; parent->insert(file->getType(), **path.full()); msg->result = ESUCCESS; } else msg->result = EIO; } break; case DeleteFile: if (cache->entries.count() == 0) { clearFileCache(cache); msg->result = ESUCCESS; } else msg->result = ENOTEMPTY; break; case StatFile: msg->result = file->status(msg); break; case ReadFile: { msg->result = file->read(req->getBuffer(), msg->size, msg->offset); if (req->getBuffer().getCount()) req->getBuffer().flush(); } break; case WriteFile: { if (!req->getBuffer().getCount()) req->getBuffer().bufferedRead(); msg->result = file->write(req->getBuffer(), msg->size, msg->offset); } break; } // Only send reply if completed (not EAGAIN) if (msg->result != EAGAIN) { msg->type = IPCType; IPCMessage(msg->from, API::Send, msg, sizeof(*msg)); } return msg->result; }
DwarfChunk* DwarfInfo::addTracelet(TCRange range, folly::Optional<std::string> name, const Func *func, PC instr, bool exit, bool inPrologue) { DwarfChunk* chunk = nullptr; FunctionInfo* f = new FunctionInfo(range, exit); const Unit* unit = func ? func->unit(): nullptr; if (name) { f->name = *name; } else { assert(func != nullptr); f->name = lookupFunction(func, exit, inPrologue, true); auto names = func->localNames(); for (int i = 0; i < func->numNamedLocals(); i++) { f->m_namedLocals.push_back(names[i]->toCppString()); } } f->file = lookupFile(unit); TCA start = range.begin(); const TCA end = range.end(); Lock lock(s_lock); auto const it = m_functions.lower_bound(range.begin()); auto const fi = it->second; if (it != m_functions.end() && fi->name == f->name && fi->file == f->file && start > fi->range.begin() && end > fi->range.end()) { // XXX: verify that overlapping address come from jmp fixups start = fi->range.end(); fi->range.extend(end); m_functions[end] = fi; m_functions.erase(it); delete f; f = m_functions[end]; assert(f->m_chunk != nullptr); f->m_chunk->clearSynced(); f->clearPerfSynced(); } else { m_functions[end] = f; } addLineEntries(TCRange(start, end, range.isAcold()), unit, instr, f); if (f->m_chunk == nullptr) { if (m_dwarfChunks.size() == 0 || m_dwarfChunks[0] == nullptr) { // new chunk of base size chunk = new DwarfChunk(); m_dwarfChunks.push_back(chunk); } else if (m_dwarfChunks[0]->m_functions.size() < RuntimeOption::EvalGdbSyncChunks) { // reuse first chunk chunk = m_dwarfChunks[0]; chunk->clearSynced(); } else { // compact chunks compactChunks(); m_dwarfChunks[0] = chunk = new DwarfChunk(); } chunk->m_functions.push_back(f); f->m_chunk = chunk; } #ifdef USE_ELF_WRITER if (f->m_chunk->m_functions.size() >= RuntimeOption::EvalGdbSyncChunks) { ElfWriter e = ElfWriter(f->m_chunk); } #endif return f->m_chunk; }
inline SourceFile *lookupFile(const QMakeLocalFileName &f) { return lookupFile(f.local().toLatin1().constData()); }
inline SourceFile *lookupFile(const QString &f) { return lookupFile(f.toLatin1().constData()); }