Ejemplo n.º 1
0
bool
GMPStorageParent::RecvWrite(const nsCString& aRecordName,
                            const InfallibleTArray<uint8_t>& aBytes)
{
  LOGD(("%s::%s: %p record=%s", __CLASS__, __FUNCTION__, this, aRecordName.get()));

  if (mShutdown) {
    return true;
  }
  if (aBytes.Length() > GMP_MAX_RECORD_SIZE) {
    unused << SendWriteComplete(aRecordName, GMPQuotaExceededErr);
    return true;
  }

  PRFileDesc* fd = mFiles.Get(aRecordName);
  if (!fd) {
    unused << SendWriteComplete(aRecordName, GMPGenericErr);
    return true;
  }

  // Write operations overwrite the entire record. So re-open the file
  // in truncate mode, to clear its contents.
  PR_Close(fd);
  mFiles.Remove(aRecordName);
  if (NS_FAILED(OpenStorageFile(aRecordName, mOrigin, Truncate, &fd))) {
    unused << SendWriteComplete(aRecordName, GMPGenericErr);
    return true;
  }
  mFiles.Put(aRecordName, fd);

  int32_t bytesWritten = PR_Write(fd, aBytes.Elements(), aBytes.Length());
  auto res = (bytesWritten == (int32_t)aBytes.Length()) ? GMPNoErr : GMPGenericErr;
  unused << SendWriteComplete(aRecordName, res);
  return true;
}
Ejemplo n.º 2
0
    GMPErr Open(const nsCString& aRecordName) override
    {
        MOZ_ASSERT(!IsOpen(aRecordName));
        nsresult rv;
        Record* record = nullptr;
        if (!mRecords.Get(aRecordName, &record)) {
            // New file.
            nsAutoString filename;
            rv = GetUnusedFilename(aRecordName, filename);
            if (NS_WARN_IF(NS_FAILED(rv))) {
                return GMPGenericErr;
            }
            record = new Record(filename, aRecordName);
            mRecords.Put(aRecordName, record);
        }

        MOZ_ASSERT(record);
        if (record->mFileDesc) {
            NS_WARNING("Tried to open already open record");
            return GMPRecordInUse;
        }

        rv = OpenStorageFile(record->mFilename, ReadWrite, &record->mFileDesc);
        if (NS_WARN_IF(NS_FAILED(rv))) {
            return GMPGenericErr;
        }

        MOZ_ASSERT(IsOpen(aRecordName));

        return GMPNoErr;
    }
Ejemplo n.º 3
0
bool
GMPStorageParent::RecvOpen(const nsCString& aRecordName)
{
  if (mShutdown) {
    return true;
  }

  if (mOrigin.EqualsASCII("null")) {
    // Refuse to open storage if the page is the "null" origin; if the page
    // is opened from disk.
    NS_WARNING("Refusing to open storage for null origin");
    unused << SendOpenComplete(aRecordName, GMPGenericErr);
    return true;
  }

  if (aRecordName.IsEmpty() || mFiles.Contains(aRecordName)) {
    unused << SendOpenComplete(aRecordName, GMPRecordInUse);
    return true;
  }

  PRFileDesc* fd = nullptr;
  nsresult rv = OpenStorageFile(aRecordName, mOrigin, ReadWrite, &fd);
  if (NS_FAILED(rv)) {
    NS_WARNING("Failed to open storage file.");
    unused << SendOpenComplete(aRecordName, GMPGenericErr);
    return true;
  }

  mFiles.Put(aRecordName, fd);
  unused << SendOpenComplete(aRecordName, GMPNoErr);

  return true;
}
Ejemplo n.º 4
0
int main() {
    InitPersistentMemoryManager();

    OpenStorageFile("test.bin");
    SetStorageFileMemoryMapping();

    link_index isA = CreateLink(itself, itself, itself);
    link_index isNotA = CreateLink(itself, itself, isA);
    link_index link = CreateLink(itself, isA, itself);
    link_index thing = CreateLink(itself, isNotA, link);

    UpdateLink(isA, isA, isA, link); // После этого минимальное ядро системы можно считать сформированным

    //DeleteLink(isA); // Одна эта операция удалит все 4 связи

    ResetStorageFileMemoryMapping();
    CloseStorageFile();
    return 0;
}
Ejemplo n.º 5
0
    GMPErr Write(const nsCString& aRecordName,
                 const nsTArray<uint8_t>& aBytes) override
    {
        if (!IsOpen(aRecordName)) {
            return GMPClosedErr;
        }

        Record* record = nullptr;
        mRecords.Get(aRecordName, &record);
        MOZ_ASSERT(record && !!record->mFileDesc); // IsOpen() guarantees this.

        // Write operations overwrite the entire record. So close it now.
        PR_Close(record->mFileDesc);
        record->mFileDesc = nullptr;

        // Writing 0 bytes means removing (deleting) the file.
        if (aBytes.Length() == 0) {
            nsresult rv = RemoveStorageFile(record->mFilename);
            if (NS_WARN_IF(NS_FAILED(rv))) {
                // Could not delete file -> Continue with trying to erase the contents.
            } else {
                return GMPNoErr;
            }
        }

        // Write operations overwrite the entire record. So re-open the file
        // in truncate mode, to clear its contents.
        if (NS_FAILED(OpenStorageFile(record->mFilename,
                                      Truncate,
                                      &record->mFileDesc))) {
            return GMPGenericErr;
        }

        // Store the length of the record name followed by the record name
        // at the start of the file.
        int32_t bytesWritten = 0;
        char buf[sizeof(uint32_t)] = {0};
        LittleEndian::writeUint32(buf, aRecordName.Length());
        bytesWritten = PR_Write(record->mFileDesc, buf, MOZ_ARRAY_LENGTH(buf));
        if (bytesWritten != MOZ_ARRAY_LENGTH(buf)) {
            NS_WARNING("Failed to write GMPStorage record name length.");
            return GMPRecordCorrupted;
        }
        bytesWritten = PR_Write(record->mFileDesc,
                                aRecordName.get(),
                                aRecordName.Length());
        if (bytesWritten != (int32_t)aRecordName.Length()) {
            NS_WARNING("Failed to write GMPStorage record name.");
            return GMPRecordCorrupted;
        }

        bytesWritten = PR_Write(record->mFileDesc, aBytes.Elements(), aBytes.Length());
        if (bytesWritten != (int32_t)aBytes.Length()) {
            NS_WARNING("Failed to write GMPStorage record data.");
            return GMPRecordCorrupted;
        }

        // Try to sync the file to disk, so that in the event of a crash,
        // the record is less likely to be corrupted.
        PR_Sync(record->mFileDesc);

        return GMPNoErr;
    }