void *read_file (const char *path, size_t *size) { FILE *fp; void *buffer; size_t file_size; size_t read_return; fp = fopen (path, "rb"); if (!fp) { xerror (__FILE__ ": can't open file `%s'", path); return NULL; } if (!_file_size (fp, path, &file_size)) { return NULL; } buffer = xmalloc (file_size); rewind (fp); read_return = fread (buffer, 1, file_size, fp); fclose (fp); if (read_return != file_size) { error (__FILE__ ": can't fully read file `%s'", path); free (buffer); return NULL; } if (size) *size = file_size; return buffer; }
struct logr *logr_open(struct options *opts, uint64_t logsn) { int flag; mode_t mode; struct logr *lgr; char name[FILE_NAME_MAXLEN]; mode = S_IRWXU | S_IRWXG | S_IRWXO; flag = O_RDONLY | O_BINARY; memset(name, 0, FILE_NAME_MAXLEN); snprintf(name, FILE_NAME_MAXLEN, "%s/ness.redo.%" PRIu64, opts->redo_path, logsn); lgr = xcalloc(1, sizeof(*lgr)); lgr->fd = ness_os_open(name, flag, mode); lgr->fsize = _file_size(name); lgr->base = xmalloc(LOG_BASE_SIZE); lgr->base_size = LOG_BASE_SIZE; return lgr; }
void *_laytube_toFile(void *args){ long unsigned int expansion_size; void *pause_after; tubeID *pTube; rohrStation sendingStation; rohrStation receivingStation; pTube = (tubeID *) args; /* Populate Station Information */ sendingStation.stationSize = comedi_get_buffer_size(pTube->dev, pTube->subdev); receivingStation.stationSize = _file_size(pTube->tail); expansion_size = 64 * sysconf(_SC_PAGESIZE); /* Set file expansion size to a mulitple of memory page size */ if (expansion_size < sendingStation.stationSize){ pTube->tubeStatus = pTube->tubeStatus | TUBE_FAILED; pthread_exit(NULL); } /* Check for empty file */ if (receivingStation.stationSize < 1){ receivingStation.stationSize = expansion_size; /* Let's make the file one page-size in length */ ftruncate(pTube->tail, receivingStation.stationSize); } /* Set up COMEDI ring buffer memory map */ sendingStation.firstByte = mmap(NULL, sendingStation.stationSize, PROT_READ, MAP_SHARED, pTube->mouth, 0); if (sendingStation.firstByte == MAP_FAILED){ pTube->tubeStatus = pTube->tubeStatus | TUBE_FAILED; pthread_exit(NULL); } sendingStation.address = sendingStation.firstByte; sendingStation.lastByte = sendingStation.firstByte + sendingStation.stationSize - 1; /* Last valid byte */ /* Set up HDD file memory map */ receivingStation.firstByte = mmap(NULL, receivingStation.stationSize, PROT_WRITE | MAP_HUGETLB, MAP_SHARED, pTube->tail, 0); if (receivingStation.firstByte == MAP_FAILED){ pTube->tubeStatus = pTube->tubeStatus | TUBE_FAILED; pthread_exit(NULL); } receivingStation.address = receivingStation.firstByte; receivingStation.lastByte = receivingStation.firstByte + receivingStation.stationSize - 1; /* Last valid byte */ /* Stations are setup... set status and command flags... */ pTube->tubeCmd = 0x00; pTube->tubeStatus = TUBE_INPLACE; /* <-- un-blocks laytube_toFile to return to calling function */ /* Core algorithm - This while loop handles the data transfer from ring buffer to disk */ while( !(pTube->tubeCmd & TUBE_STOP) ){ /* Check if the storage file is out or about to be out of space */ if (sendingStation.stationSize >= (receivingStation.lastByte - receivingStation.address) ){ if (_growStation(&receivingStation, pTube->tail, expansion_size) == -1){ pTube->tubeStatus = pTube->tubeStatus | TUBE_FAILED; pthread_exit(NULL); } } pause_after = sendingStation.firstByte + comedi_get_buffer_contents(pTube->dev, pTube->subdev) - 1; if (pause_after < sendingStation.address){ pTube->bytesMoved = receivingStation.address - receivingStation.firstByte; /* comedi_poll(pTube->dev, pTube->subdev)); */ usleep(10); /* TODO: optimize by setting sleep number to best guess at when data might show up again */ } else if (pause_after < sendingStation.lastByte) /* Confirm COMEDI ring buffer has not aliased */ { do { *((CARRIER *)receivingStation.address++) = *((CARRIER *)sendingStation.address++); } while(sendingStation.address <= pause_after); } else if (pause_after >= sendingStation.lastByte) /* COMEDI ring buffer has aliased... copy up to end of ring buffer and reset */ { do { *((CARRIER *)receivingStation.address++) = *((CARRIER *)sendingStation.address++); } while(sendingStation.address <= sendingStation.lastByte); comedi_mark_buffer_read(pTube->dev, pTube->subdev, sendingStation.stationSize); /* Reset the ring buffer mark */ sendingStation.address = sendingStation.firstByte; } else { pTube->tubeStatus = pTube->tubeStatus | TUBE_FAILED; pthread_exit(0); } } /* Clean up Stations, truncate file, flush tube */ expansion_size = receivingStation.address - receivingStation.firstByte; /* 'address' should point to one byte past last byte written */ ftruncate(pTube->tail, expansion_size); fsync(pTube->tail); pTube->bytesMoved = expansion_size; pTube->tubeStatus = pTube->tubeStatus | TUBE_EXIT; pthread_exit(0); }
wvpinfo * _wavpack_parse(PerlIO *infile, char *file, HV *info, uint8_t seeking) { int err = 0; int done = 0; u_char *bptr; wvpinfo *wvp; Newz(0, wvp, sizeof(wvpinfo), wvpinfo); Newz(0, wvp->buf, sizeof(Buffer), Buffer); Newz(0, wvp->header, sizeof(WavpackHeader), WavpackHeader); wvp->infile = infile; wvp->file = file; wvp->info = info; wvp->file_offset = 0; wvp->audio_offset = 0; wvp->seeking = seeking ? 1 : 0; buffer_init(wvp->buf, WAVPACK_BLOCK_SIZE); wvp->file_size = _file_size(infile); my_hv_store( info, "file_size", newSVuv(wvp->file_size) ); // Loop through each wvpk block until we find a good one while (!done) { if ( !_check_buf(infile, wvp->buf, 32, WAVPACK_BLOCK_SIZE) ) { err = -1; goto out; } bptr = buffer_ptr(wvp->buf); // If first byte is 'R', assume old version if ( bptr[0] == 'R' ) { if ( !_wavpack_parse_old(wvp) ) { err = -1; goto out; } break; } // May need to read past some junk before wvpk header while ( bptr[0] != 'w' || bptr[1] != 'v' || bptr[2] != 'p' || bptr[3] != 'k' ) { buffer_consume(wvp->buf, 1); wvp->audio_offset++; if ( !buffer_len(wvp->buf) ) { if ( !_check_buf(infile, wvp->buf, 32, WAVPACK_BLOCK_SIZE) ) { PerlIO_printf(PerlIO_stderr(), "Unable to find a valid WavPack block in file: %s\n", file); err = -1; goto out; } } bptr = buffer_ptr(wvp->buf); } if ( _wavpack_parse_block(wvp) ) { done = 1; } } my_hv_store( info, "audio_offset", newSVuv(wvp->audio_offset) ); my_hv_store( info, "audio_size", newSVuv(wvp->file_size - wvp->audio_offset) ); out: buffer_free(wvp->buf); Safefree(wvp->buf); Safefree(wvp->header); return wvp; }
static int get_wav_metadata(PerlIO *infile, char *file, HV *info, HV *tags) { Buffer buf; off_t file_size; int err = 0; uint32_t chunk_size; file_size = _file_size(infile); buffer_init(&buf, WAV_BLOCK_SIZE); if ( !_check_buf(infile, &buf, 12, WAV_BLOCK_SIZE) ) { err = -1; goto out; } if ( !strncmp( (char *)buffer_ptr(&buf), "RIFF", 4 ) ) { // We've got a RIFF file buffer_consume(&buf, 4); chunk_size = buffer_get_int_le(&buf); // Check format if ( strncmp( (char *)buffer_ptr(&buf), "WAVE", 4 ) ) { PerlIO_printf(PerlIO_stderr(), "Invalid WAV file: missing WAVE header: %s\n", file); err = -1; goto out; } buffer_consume(&buf, 4); my_hv_store( info, "file_size", newSVuv(file_size) ); _parse_wav(infile, &buf, file, file_size, info, tags); } else if ( !strncmp( (char *)buffer_ptr(&buf), "FORM", 4 ) ) { // We've got an AIFF file char *bptr; buffer_consume(&buf, 4); chunk_size = buffer_get_int(&buf); // Check format bptr = buffer_ptr(&buf); if ( bptr[0] == 'A' && bptr[1] == 'I' && bptr[2] == 'F' && (bptr[3] == 'F' || bptr[3] == 'C') ) { buffer_consume(&buf, 4); my_hv_store( info, "file_size", newSVuv(file_size) ); _parse_aiff(infile, &buf, file, file_size, info, tags); } else { PerlIO_printf(PerlIO_stderr(), "Invalid AIFF file: missing AIFF header: %s\n", file); err = -1; goto out; } } else { PerlIO_printf(PerlIO_stderr(), "Invalid WAV file: missing RIFF header: %s\n", file); err = -1; goto out; } out: buffer_free(&buf); if (err) return err; return 0; }