/** * Creates a file filled with zeroes * * @param fh the file handle * @param size the size of the file * @return GNUNET_OK if created ok, GNUNET_SYSERR otherwise */ static int make_empty_file (const struct GNUNET_DISK_FileHandle *fh, size_t size) { char buffer[BUFFSIZE]; size_t bytesleft = size; int res = 0; if (GNUNET_DISK_handle_invalid (fh)) return GNUNET_SYSERR; memset (buffer, 0, sizeof (buffer)); GNUNET_DISK_file_seek (fh, 0, GNUNET_DISK_SEEK_SET); while (bytesleft > 0) { if (bytesleft > sizeof (buffer)) { res = GNUNET_DISK_file_write (fh, buffer, sizeof (buffer)); if (res >= 0) bytesleft -= res; } else { res = GNUNET_DISK_file_write (fh, buffer, bytesleft); if (res >= 0) bytesleft -= res; } if (GNUNET_SYSERR == res) return GNUNET_SYSERR; } return GNUNET_OK; }
/** * Report result of hash computation to callback * and free associated resources. */ static void file_hash_finish (struct GNUNET_CRYPTO_FileHashContext *fhc, const struct GNUNET_HashCode * res) { fhc->callback (fhc->callback_cls, res); GNUNET_free (fhc->filename); if (!GNUNET_DISK_handle_invalid (fhc->fh)) GNUNET_break (GNUNET_OK == GNUNET_DISK_file_close (fhc->fh)); gcry_md_close (fhc->md); GNUNET_free (fhc); /* also frees fhc->buffer */ }
/** * Clears a bit from bitArray if the respective usage * counter on the disk hits/is zero. * * @param bitArray memory area to set the bit in * @param bitIdx which bit to test * @param fh A file to keep the 4bit address usage counters in */ static void decrementBit (char *bitArray, unsigned int bitIdx, const struct GNUNET_DISK_FileHandle *fh) { off_t fileslot; unsigned char value; unsigned int high; unsigned int low; unsigned int targetLoc; if (GNUNET_DISK_handle_invalid (fh)) return; /* cannot decrement! */ /* Each char slot in the counter file holds two 4 bit counters */ fileslot = bitIdx / 2; targetLoc = bitIdx % 2; if (GNUNET_SYSERR == GNUNET_DISK_file_seek (fh, fileslot, GNUNET_DISK_SEEK_SET)) { GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "seek"); return; } if (1 != GNUNET_DISK_file_read (fh, &value, 1)) value = 0; low = value & 0xF; high = (value & 0xF0) >> 4; /* decrement, but once we have reached the max, never go back! */ if (targetLoc == 0) { if ((low > 0) && (low < 0xF)) low--; if (low == 0) { clearBit (bitArray, bitIdx); } } else { if ((high > 0) && (high < 0xF)) high--; if (high == 0) { clearBit (bitArray, bitIdx); } } value = ((high << 4) | low); if (GNUNET_SYSERR == GNUNET_DISK_file_seek (fh, fileslot, GNUNET_DISK_SEEK_SET)) { GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "seek"); return; } GNUNET_assert (1 == GNUNET_DISK_file_write (fh, &value, 1)); }
static int testOpenClose () { struct GNUNET_DISK_FileHandle *fh; uint64_t size; fh = GNUNET_DISK_file_open (".testfile", GNUNET_DISK_OPEN_READWRITE | GNUNET_DISK_OPEN_CREATE, GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE); GNUNET_assert (GNUNET_NO == GNUNET_DISK_handle_invalid (fh)); GNUNET_break (5 == GNUNET_DISK_file_write (fh, "Hello", 5)); GNUNET_DISK_file_close (fh); GNUNET_break (GNUNET_OK == GNUNET_DISK_file_size (".testfile", &size, GNUNET_NO, GNUNET_YES)); if (size != 5) return 1; GNUNET_break (0 == UNLINK (".testfile")); return 0; }
/** * Sets a bit active in the bitArray and increments * bit-specific usage counter on disk (but only if * the counter was below 4 bit max (==15)). * * @param bitArray memory area to set the bit in * @param bitIdx which bit to test * @param fh A file to keep the 4 bit address usage counters in */ static void incrementBit (char *bitArray, unsigned int bitIdx, const struct GNUNET_DISK_FileHandle *fh) { OFF_T fileSlot; unsigned char value; unsigned int high; unsigned int low; unsigned int targetLoc; setBit (bitArray, bitIdx); if (GNUNET_DISK_handle_invalid (fh)) return; /* Update the counter file on disk */ fileSlot = bitIdx / 2; targetLoc = bitIdx % 2; GNUNET_assert (fileSlot == GNUNET_DISK_file_seek (fh, fileSlot, GNUNET_DISK_SEEK_SET)); if (1 != GNUNET_DISK_file_read (fh, &value, 1)) value = 0; low = value & 0xF; high = (value & (~0xF)) >> 4; if (targetLoc == 0) { if (low < 0xF) low++; } else { if (high < 0xF) high++; } value = ((high << 4) | low); GNUNET_assert (fileSlot == GNUNET_DISK_file_seek (fh, fileSlot, GNUNET_DISK_SEEK_SET)); GNUNET_assert (1 == GNUNET_DISK_file_write (fh, &value, 1)); }