bool SXFile::persist(BasePersistenceManager *persistMgr) { BaseScriptable::persist(persistMgr); persistMgr->transfer(TMEMBER(_filename)); persistMgr->transfer(TMEMBER(_mode)); persistMgr->transferBool(TMEMBER(_textMode)); uint32 pos = 0; if (persistMgr->getIsSaving()) { pos = getPos(); persistMgr->transfer(TMEMBER(pos)); } else { persistMgr->transfer(TMEMBER(pos)); // try to re-open file if needed _writeFile = nullptr; _readFile = nullptr; if (_mode != 0) { // open for reading if (_mode == 1) { _readFile = BaseFileManager::getEngineInstance()->openFile(_filename); if (!_readFile) { close(); } } // open for writing / appending else { if (_textMode) { if (_mode == 2) { _writeFile = openForWrite(_filename, false); } else { _writeFile = openForAppend(_filename, false); } } else { if (_mode == 2) { _writeFile = openForWrite(_filename, true); } else { _writeFile = openForAppend(_filename, true); } } if (_writeFile) { close(); } } setPos(pos); } } return STATUS_OK; }
void File::write(const Str & data) { if(file < 0 || !writable) openForWrite(); long unsigned written = 0; while(written < data.length){ errno = 0; int justWritten = ::write(file, data.c_str() + written, data.length - written); if(errno){ int errNo = errno; FileError e(errNo, "Error after writting % bytes into file %.", written, fileName); if(written){ try { resize(fileSize); close(file); } catch (std::exception &ee) { e.note("Failed to revert partial write.\n" "What: %", ee.what()); } } throw e; } written += justWritten; } fileSize += written; // FIXME what if write is not appending, but overwriting }
// Constructor, init variables and open the specified file based on the // specified mode (READ/WRITE). Default is READ.. GlfFile::GlfFile(const char* filename, OpenType mode) : myFilePtr(NULL), myEndMarker() { resetFile(); bool openStatus = true; if(mode == READ) { // open the file for read. openStatus = openForRead(filename); } else { // open the file for write. openStatus = openForWrite(filename); } if(!openStatus) { // Failed to open the file - print error and abort. fprintf(stderr, "%s\n", getStatusMessage()); std::cerr << "FAILURE - EXITING!!!" << std::endl; exit(-1); } }
void File::append(const Str & data) { if(file < 0 || !writable) openForWrite(); if(lseek(file, 0L, SEEK_END) < 0) throw FileError(errno, "Could not seek to end of %.", fileName); write(data); }
void File::writeAtPos(const Str & data, long unsigned pos) { if(file < 0 || !writable) openForWrite(); if(lseek(file, pos, SEEK_SET) < 0) throw FileError(errno, "Could not seek in file %.", fileName); write(data); }
// Constructor that opens the specified file for write. GlfFileWriter::GlfFileWriter(const char* filename) { if(!openForWrite(filename)) { // Failed to open for reading - print error and abort. fprintf(stderr, "%s\n", getStatusMessage()); std::cerr << "FAILURE - EXITING!!!" << std::endl; exit(-1); } }
static void saveAuthenticatorId(const char* filename, uint64_t authenid) { ALOGD("----------------> %s ----------------->", __FUNCTION__); FILE* fp = openForWrite(filename); if (!fp) { ALOGE("Failed to open emulator storage file to save authenticator id"); return; } rewind(fp); int na = fwrite(&authenid, sizeof(authenid), 1, fp); if (na != 1) { ALOGE("Failed while writing authenticator id in emulator storage"); } ALOGD("Save authenticator id (0x%" PRIx64 ")", authenid); fclose(fp); }
/** * Based on stackoverflow answer: * http://stackoverflow.com/questions/575328/fcntl-lockf-which-is-better-to-use-for-file-locking?answertab=active#tab-top * It says: * Locking in unix/linux is by default advisory.... * Also says: * Linux does support mandatory locking, but only if your file system is * mounted with the option on and the file special attributes set. * * length is the number of bytes to lock from the current position; 0 means infinity */ void File::lock(off_t length) { if(file < 0 || !writable) openForWrite(); if(lockf(file, F_TLOCK, length) < 0) throw FileError(errno, "Failed to lock file %.", fileName); locked = true; /* // alternate implementation (void)length; if(0 < file) close(); file = open(fileName, O_RDWR|O_CREAT|O_EXCL, 0600); if(file < 0) throw FileError(errno, "Failed to open file % in exclusive open mode.", fileName); writable = true; eofbit = false; locked = true; */ }
static void saveFingerprint(worker_thread_t* listener, int idx) { ALOGD("----------------> %s -----------------> idx %d", __FUNCTION__, idx); // Save fingerprints to file FILE* fp = openForWrite(listener->fp_filename); if (fp == NULL) { ALOGE("Could not open fingerprints storage at %s; " "fingerprints won't be saved", listener->fp_filename); perror("Failed to open file"); return; } ALOGD("Write fingerprint[%d] (0x%" PRIx64 ",0x%" PRIx64 ")", idx, listener->secureid[idx], listener->fingerid[idx]); if (fseek(fp, (idx) * sizeof(uint64_t), SEEK_SET) < 0) { ALOGE("Failed while seeking for fingerprint[%d] in emulator storage", idx); fclose(fp); return; } int ns = fwrite(&listener->secureid[idx], sizeof(uint64_t), 1, fp); if (fseek(fp, (MAX_NUM_FINGERS + idx) * sizeof(uint64_t), SEEK_SET) < 0) { ALOGE("Failed while seeking for fingerprint[%d] in emulator storage", idx); fclose(fp); return; } int nf = fwrite(&listener->fingerid[idx], sizeof(uint64_t), 1, fp); if (ns != 1 || ns !=1) ALOGW("Corrupt emulator fingerprints storage; could not save " "fingerprints"); fclose(fp); return; }
void* asyncWrite(void* parameters) { pdebug("asyncWrite()\n"); writeParams* params = parameters; int64_t write = openForWrite(params->temp_file_name); if(write < 0) { pdebug("Error opening file for write\n"); *(params->error) = FILE_IO_FAIL; return NULL; } chunk* write_chunk = NULL; uint64_t bytes_written = 0; uint64_t bytes_to_write = 0; uint64_t write_progress = 0; while(*(params->running) && *(params->error) == 0) { if(write_chunk == NULL) //Get a chunk from the queue { pthread_mutex_lock(params->mutex); if(front(params->in) != NULL) { write_chunk = front(params->in); if(write_chunk != NULL) { deque(params->in); } } pthread_mutex_unlock(params->mutex); } //check for termination conditions if((write_chunk != NULL && write_chunk->action == DONE) || ((params->file_size) != NULL && *(params->valid) && bytes_written >= *(params->file_size))) //size constraints { pdebug("^^^^ AsyncWrite() terminating loop ^^^^\n"); destroyChunk(write_chunk); break; } if(write_chunk != NULL && write_chunk->data != NULL) { //ensure we aren't writing padding or attack attempts if(params->file_size == NULL) { bytes_to_write = write_chunk->data_size; } else if(bytes_written + write_chunk->data_size > *(params->file_size)) { bytes_to_write = *(params->file_size) - bytes_written; } else { bytes_to_write = write_chunk->data_size; } write_progress += write_chunk->data_size; if(!writeBytes((uint8_t*)write_chunk->data, bytes_to_write, write)) { pdebug("^^^^ File I/O Error ^^^^\n"); *(params->error) = FILE_IO_FAIL; close(write); break; } ///write it to the file pdebug("^^^^ Writing a chunk of size %lu ^^^^\n", bytes_to_write); bytes_written += bytes_to_write; destroyChunk(write_chunk); //free the chunk write_chunk = NULL; } if(write_progress > 0) //update the progress bar { if(pthread_mutex_trylock(params->progress->progress_mutex) == 0) { params->progress->progress += write_progress; write_progress = 0; pthread_mutex_unlock(params->progress->progress_mutex); } } } close(write); if(*(params->error) == 0) { if(params->args->rename) //change the output file to what the user wanted { rename((char*)params->temp_file_name, (char*)params->args->rename_file); } else //rename the temp file to the original file name (replaces file) { rename((char*)params->temp_file_name, (char*)params->args->target_file); } //signal any other running threads to stop (in case they are stuck) *(params->running) = false; } pdebug("^^^^ writeThread Done ^^^^\n"); //we are done return NULL; }
bool SXFile::scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) { ////////////////////////////////////////////////////////////////////////// // SetFilename ////////////////////////////////////////////////////////////////////////// if (strcmp(name, "SetFilename") == 0) { stack->correctParams(1); const char *filename = stack->pop()->getString(); cleanup(); BaseUtils::setString(&_filename, filename); stack->pushNULL(); return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // OpenAsText / OpenAsBinary ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "OpenAsText") == 0 || strcmp(name, "OpenAsBinary") == 0) { stack->correctParams(1); close(); _mode = stack->pop()->getInt(1); if (_mode < 1 || _mode > 3) { script->runtimeError("File.%s: invalid access mode. Setting read mode.", name); _mode = 1; } if (_mode == 1) { _readFile = BaseFileManager::getEngineInstance()->openFile(_filename); if (!_readFile) { //script->runtimeError("File.%s: Error opening file '%s' for reading.", Name, _filename); close(); } else { _textMode = strcmp(name, "OpenAsText") == 0; } } else { if (strcmp(name, "OpenAsText") == 0) { if (_mode == 2) { _writeFile = openForWrite(_filename, false); } else { _writeFile = openForAppend(_filename, false); } } else { if (_mode == 2) { _writeFile = openForWrite(_filename, true); } else { _writeFile = openForAppend(_filename, true); } } if (!_writeFile) { //script->runtimeError("File.%s: Error opening file '%s' for writing.", Name, _filename); close(); } else { _textMode = strcmp(name, "OpenAsText") == 0; } } if (_readFile || _writeFile) { stack->pushBool(true); } else { stack->pushBool(false); } return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // Close ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "Close") == 0) { stack->correctParams(0); close(); stack->pushNULL(); return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // SetPosition ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "SetPosition") == 0) { stack->correctParams(1); if (_mode == 0) { script->runtimeError("File.%s: File is not open", name); stack->pushBool(false); } else { int pos = stack->pop()->getInt(); stack->pushBool(setPos(pos)); } return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // Delete ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "Delete") == 0) { stack->correctParams(0); close(); error("SXFile-Method: \"Delete\" not supported"); //stack->pushBool(BasePlatform::deleteFile(_filename) != false); stack->pushBool(false); return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // Copy ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "Copy") == 0) { stack->correctParams(2); /* const char *dest = */ stack->pop()->getString(); /* bool overwrite = */ stack->pop()->getBool(true); close(); error("SXFile-Method: Copy not supported"); //stack->pushBool(BasePlatform::copyFile(_filename, Dest, !Overwrite) != false); stack->pushBool(false); return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // ReadLine ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "ReadLine") == 0) { stack->correctParams(0); if (!_textMode || !_readFile) { script->runtimeError("File.%s: File must be open in text mode.", name); stack->pushNULL(); return STATUS_OK; } uint32 bufSize = FILE_BUFFER_SIZE; byte *buf = (byte *)malloc(bufSize); uint32 counter = 0; byte b; bool foundNewLine = false; bool ret = STATUS_FAILED; do { ret = _readFile->read(&b, 1); if (ret != 1) { break; } if (counter > bufSize) { buf = (byte *)realloc(buf, bufSize + FILE_BUFFER_SIZE); bufSize += FILE_BUFFER_SIZE; } if (b == '\n') { buf[counter] = '\0'; foundNewLine = true; break; } else if (b == 0x0D) { continue; } else { buf[counter] = b; counter++; } } while (DID_SUCCEED(ret)); if (counter > bufSize) { buf = (byte *)realloc(buf, bufSize + FILE_BUFFER_SIZE); bufSize += FILE_BUFFER_SIZE; } buf[counter] = '\0'; if (!foundNewLine && counter == 0) { stack->pushNULL(); } else { stack->pushString((char *)buf); } free(buf); return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // ReadText ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "ReadText") == 0) { stack->correctParams(1); int textLen = stack->pop()->getInt(); if (!_textMode || !_readFile) { script->runtimeError("File.%s: File must be open in text mode.", name); stack->pushNULL(); return STATUS_OK; } uint32 bufSize = FILE_BUFFER_SIZE; byte *buf = (byte *)malloc(bufSize); uint32 counter = 0; byte b; bool ret = STATUS_FAILED; while (counter < (uint32)textLen) { ret = _readFile->read(&b, 1); if (ret != 1) { break; } if (counter > bufSize) { buf = (byte *)realloc(buf, bufSize + FILE_BUFFER_SIZE); bufSize += FILE_BUFFER_SIZE; } if (b == 0x0D) { continue; } else { buf[counter] = b; counter++; } } if (counter > bufSize) { buf = (byte *)realloc(buf, bufSize + FILE_BUFFER_SIZE); bufSize += FILE_BUFFER_SIZE; } buf[counter] = '\0'; if (textLen > 0 && counter == 0) { stack->pushNULL(); } else { stack->pushString((char *)buf); } free(buf); return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // WriteLine / WriteText ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "WriteLine") == 0 || strcmp(name, "WriteText") == 0) { stack->correctParams(1); const char *line = stack->pop()->getString(); if (!_textMode || !_writeFile) { script->runtimeError("File.%s: File must be open for writing in text mode.", name); stack->pushBool(false); return STATUS_OK; } Common::String writeLine; if (strcmp(name, "WriteLine") == 0) { writeLine = Common::String::format("%s\n", line); } else { writeLine = Common::String::format("%s", line); } _writeFile->writeString(writeLine); _writeFile->writeByte(0); stack->pushBool(true); return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// // ReadBool ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "ReadBool") == 0) { stack->correctParams(0); if (_textMode || !_readFile) { script->runtimeError("File.%s: File must be open for reading in binary mode.", name); stack->pushNULL(); return STATUS_OK; } bool val; if (_readFile->read(&val, sizeof(bool)) == sizeof(bool)) { stack->pushBool(val); } else { stack->pushNULL(); } return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // ReadByte ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "ReadByte") == 0) { stack->correctParams(0); if (_textMode || !_readFile) { script->runtimeError("File.%s: File must be open for reading in binary mode.", name); stack->pushNULL(); return STATUS_OK; } byte val = _readFile->readByte(); if (!_readFile->err()) { stack->pushInt(val); } else { stack->pushNULL(); } return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // ReadShort ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "ReadShort") == 0) { stack->correctParams(0); if (_textMode || !_readFile) { script->runtimeError("File.%s: File must be open for reading in binary mode.", name); stack->pushNULL(); return STATUS_OK; } int16 val = _readFile->readSint16LE(); if (!_readFile->err()) { stack->pushInt(65536 + val); } else { stack->pushNULL(); } return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // ReadInt / ReadLong ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "ReadInt") == 0 || strcmp(name, "ReadLong") == 0) { stack->correctParams(0); if (_textMode || !_readFile) { script->runtimeError("File.%s: File must be open for reading in binary mode.", name); stack->pushNULL(); return STATUS_OK; } int32 val = _readFile->readSint32LE(); if (!_readFile->err()) { stack->pushInt(val); } else { stack->pushNULL(); } return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // ReadFloat ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "ReadFloat") == 0) { stack->correctParams(0); if (_textMode || !_readFile) { script->runtimeError("File.%s: File must be open for reading in binary mode.", name); stack->pushNULL(); return STATUS_OK; } float val; (*(uint32 *)&val) = _readFile->readUint32LE(); if (!_readFile->err()) { stack->pushFloat(val); } else { stack->pushNULL(); } return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // ReadDouble ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "ReadDouble") == 0) { // TODO: Solve reading a 8 byte double. error("SXFile::ReadDouble - Not endian safe yet"); stack->correctParams(0); if (_textMode || !_readFile) { script->runtimeError("File.%s: File must be open for reading in binary mode.", name); stack->pushNULL(); return STATUS_OK; } double val; if (_readFile->read(&val, sizeof(double)) == sizeof(double)) { stack->pushFloat(val); } else { stack->pushNULL(); } return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // ReadString ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "ReadString") == 0) { stack->correctParams(0); if (_textMode || !_readFile) { script->runtimeError("File.%s: File must be open for reading in binary mode.", name); stack->pushNULL(); return STATUS_OK; } uint32 size = _readFile->readUint32LE(); if (!_readFile->err()) { byte *str = new byte[size + 1]; if (str) { if (_readFile->read(str, size) == size) { str[size] = '\0'; stack->pushString((char *)str); } delete[] str; } else { stack->pushNULL(); } } else { stack->pushNULL(); } return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // WriteBool ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "WriteBool") == 0) { stack->correctParams(1); bool val = stack->pop()->getBool(); if (_textMode || !_writeFile) { script->runtimeError("File.%s: File must be open for writing in binary mode.", name); stack->pushBool(false); return STATUS_OK; } _writeFile->writeByte(val); stack->pushBool(true); return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // WriteByte ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "WriteByte") == 0) { stack->correctParams(1); byte val = stack->pop()->getInt(); if (_textMode || !_writeFile) { script->runtimeError("File.%s: File must be open for writing in binary mode.", name); stack->pushBool(false); return STATUS_OK; } _writeFile->writeByte(val); stack->pushBool(true); return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // WriteShort ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "WriteShort") == 0) { stack->correctParams(1); int16 val = stack->pop()->getInt(); if (_textMode || !_writeFile) { script->runtimeError("File.%s: File must be open for writing in binary mode.", name); stack->pushBool(false); return STATUS_OK; } _writeFile->writeSint16LE(val); stack->pushBool(true); return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // WriteInt / WriteLong ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "WriteInt") == 0 || strcmp(name, "WriteLong") == 0) { stack->correctParams(1); int32 val = stack->pop()->getInt(); if (_textMode || !_writeFile) { script->runtimeError("File.%s: File must be open for writing in binary mode.", name); stack->pushBool(false); return STATUS_OK; } _writeFile->writeSint32LE(val); stack->pushBool(true); return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // WriteFloat ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "WriteFloat") == 0) { stack->correctParams(1); float val = stack->pop()->getFloat(); if (_textMode || !_writeFile) { script->runtimeError("File.%s: File must be open for writing in binary mode.", name); stack->pushBool(false); return STATUS_OK; } uint32 *ptr = (uint32 *)&val; _writeFile->writeUint32LE(*ptr); stack->pushBool(true); return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // WriteDouble ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "WriteDouble") == 0) { error("SXFile::WriteDouble - Not endian safe yet"); stack->correctParams(1); /* double val = */ stack->pop()->getFloat(); if (_textMode || !_writeFile) { script->runtimeError("File.%s: File must be open for writing in binary mode.", name); stack->pushBool(false); return STATUS_OK; } //fwrite(&val, sizeof(val), 1, (FILE *)_writeFile); stack->pushBool(true); return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // WriteString ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "WriteString") == 0) { stack->correctParams(1); const char *val = stack->pop()->getString(); if (_textMode || !_writeFile) { script->runtimeError("File.%s: File must be open for writing in binary mode.", name); stack->pushBool(false); return STATUS_OK; } uint32 size = strlen(val); _writeFile->writeUint32LE(size); _writeFile->writeString(val); stack->pushBool(true); return STATUS_OK; } else { return BaseScriptable::scCallMethod(script, stack, thisStack, name); } }