void initialize() { if (init>0) return; #ifdef _allow_cachefiles cachedir = makefullpath(ReadConf("bkz.conf","svpccache")); mkdirRecursive(cachedir.c_str(), 0777); #endif init = 1; }
// based on the trial we're currently writing to disk, void updateSignalFileInfo(SignalFileInfo* pSignalFile, DataLoggerStatus* pStatus, unsigned trialIdx) { DataLoggerStatusByTrial* trialStatus = pStatus->byTrial + trialIdx; unsigned msec; struct tm timeInfo; convertWallclockToLocalTime(trialStatus->wallclockStart, &timeInfo, &msec); // append the date as a folder onto dataRoot char dateFolderBuffer[MAX_FILENAME_LENGTH]; strftime(dateFolderBuffer, MAX_FILENAME_LENGTH, "%Y-%m-%d", &timeInfo); // build pathBufferIndex as dataRoot/storeName/subject/YYYYMMDD/ // build pathBufferSaveTag as dataRoot/storeName/subject/YYYYMMDD/protocol/saveTag#/ char pathBufferIndex[MAX_FILENAME_LENGTH]; char pathBufferTrial[MAX_FILENAME_LENGTH]; snprintf(pathBufferIndex, MAX_FILENAME_LENGTH, "%s/%s/%s/%s", dataRoot, pStatus->dataStore, pStatus->subject, dateFolderBuffer); snprintf(pathBufferTrial, MAX_FILENAME_LENGTH, "%s/%s/saveTag%03d", pathBufferIndex, pStatus->protocol, pStatus->saveTag); // check that this data directory exists if it's changed from last time if(strncmp(pathBufferTrial, pSignalFile->filePath, MAX_FILENAME_LENGTH) != 0) { // path has changed, need to check that this path exists, and/or create it if (access( pathBufferTrial, R_OK | W_OK ) == -1) { // this new path doesn't exist or we can't access it --> mkdir it int failed = mkdirRecursive(pathBufferTrial); if(failed) diep("Error creating trial data directory"); } // update the filePath so we don't try to create it again strncpy(pSignalFile->filePath, pathBufferTrial, MAX_FILENAME_LENGTH); logInfo("Updating trial data dir : %s\n", pSignalFile->filePath); } // now check the index file to make sure it exists // the index file is simply a list of .mat files written to this directory // which makes it is easy for other programs to detect when these files // are added, rather than having to stat the whole directory repeatedly char indexFileBuffer[MAX_FILENAME_LENGTH]; snprintf(indexFileBuffer, MAX_FILENAME_LENGTH, "%s/trialIndex.txt", pathBufferIndex); char saveTagIndexFileBuffer[MAX_FILENAME_LENGTH]; snprintf(saveTagIndexFileBuffer, MAX_FILENAME_LENGTH, "%s/trialIndex.txt", pathBufferTrial); // check whether the index file is the same as last time if(strncmp(indexFileBuffer, pSignalFile->indexFileName, MAX_FILENAME_LENGTH) != 0) { // it's changed from last time strncpy(pSignalFile->indexFileName, indexFileBuffer, MAX_FILENAME_LENGTH); logInfo("Updating trial index file : %s\n", pSignalFile->indexFileName); pSignalFile->indexFile = fopen(pSignalFile->indexFileName, "a"); if(pSignalFile->indexFile == NULL) { diep("Error opening index file."); } } // check whether the save tag index file is the same as last time if(strncmp(saveTagIndexFileBuffer, pSignalFile->saveTagIndexFileName, MAX_FILENAME_LENGTH) != 0) { // it's changed from last time strncpy(pSignalFile->saveTagIndexFileName, saveTagIndexFileBuffer, MAX_FILENAME_LENGTH); logInfo("Updating save-tag index file : %s\n", pSignalFile->saveTagIndexFileName); pSignalFile->saveTagIndexFile = fopen(pSignalFile->saveTagIndexFileName, "a"); if(pSignalFile->saveTagIndexFile == NULL) diep("Error opening index file."); } // create a unique mat file name based on <subject>_protocol_<date.time.msec>_id<trialId>.mat char fileTimeBuffer[MAX_FILENAME_LENGTH]; strftime(fileTimeBuffer, MAX_FILENAME_LENGTH, "%Y%m%d.%H%M%S", &timeInfo); // assemble short file name without path snprintf(pSignalFile->fileNameShort, MAX_FILENAME_LENGTH, "%s_%s_id%06d_time%s.%03d.mat", pStatus->subject, pStatus->protocol, trialStatus->trialId, fileTimeBuffer, msec); // path relative to index file, e.g. protocol/saveTag#/fileName.mat snprintf(pSignalFile->fileNameRelativeToIndex, MAX_FILENAME_LENGTH, "%s/saveTag%03d/%s", pStatus->protocol, pStatus->saveTag, pSignalFile->fileNameShort); // assemble file name with path snprintf(pSignalFile->fileName, MAX_FILENAME_LENGTH, "%s/%s", pSignalFile->filePath, pSignalFile->fileNameShort); }
/// Returns false if the data cannot be written to file. // /// If there is no data, the file is removed and the function returns true. bool SharedObject_as::flush(int space) const { /// This is called on on destruction of the SharedObject, or (allegedly) /// on a call to SharedObject.data, so _data is not guaranteed to exist. // /// The function should never be called from SharedObject.flush() when /// _data is 0. if (!_data) return false; if (space > 0) { log_unimpl("SharedObject.flush() called with a minimum disk space " "argument (%d), which is currently ignored", space); } const std::string& filespec = getFilespec(); if (!mkdirRecursive(filespec)) { log_error("Couldn't create dir for flushing SharedObject %s", filespec); return false; } #ifdef USE_SOL_READONLY log_debug(_("SharedObject %s not flushed (compiled as read-only mode)"), filespec); return false; #endif if (rcfile.getSOLReadOnly()) { log_security("Attempting to write object %s when it's SOL " "Read Only is set! Refusing...", filespec); return false; } // Open file std::ofstream ofs(filespec.c_str(), std::ios::binary); if (!ofs) { log_error("SharedObject::flush(): Failed opening file '%s' in " "binary mode", filespec.c_str()); return false; } // Encode data part. SimpleBuffer buf; if (!encodeData(_name, *_data, buf)) { std::remove(filespec.c_str()); return true; } // Encode header part. SimpleBuffer header; encodeHeader(buf.size(), header); // Write header ofs.write(reinterpret_cast<const char*>(header.data()), header.size()); if (!ofs) { log_error("Error writing SOL header"); return false; } // Write AMF data ofs.write(reinterpret_cast<const char*>(buf.data()), buf.size()); if (!ofs) { log_error("Error writing %d bytes to output file %s", buf.size(), filespec.c_str()); return false; } ofs.close(); log_security("SharedObject '%s' written to filesystem.", filespec); return true; }