annotate open.cpp @ 601:82d23418d867

Fix some fd leaks in the command-line binary Strictly speaking, they're not really leaks, because the only codepath that suffers from these leaks exits immediately afterwards. On the other hand, this fix makes valgrind on e.g. tests/0025 happier, going from 5 errors to none.
author mas01cr
date Fri, 14 Aug 2009 16:39:32 +0000
parents 6ad0a6e67d4c
children b1723ae7675e
rev   line source
mas01cr@498 1 extern "C" {
mas01cr@498 2 #include "audioDB_API.h"
mas01cr@509 3 }
mas01cr@498 4 #include "audioDB-internals.h"
mas01cr@498 5
mas01cr@498 6 static bool audiodb_check_header(adb_header_t *header) {
mas01cr@498 7 /* FIXME: use syslog() or write to stderr or something to give the
mas01cr@498 8 poor user some diagnostics. */
mas01cr@509 9 if(header->magic == ADB_OLD_MAGIC) {
mas01cr@498 10 return false;
mas01cr@498 11 }
mas01cr@509 12 if(header->magic != ADB_MAGIC) {
mas01cr@498 13 return false;
mas01cr@498 14 }
mas01cr@509 15 if(header->version != ADB_FORMAT_VERSION) {
mas01cr@498 16 return false;
mas01cr@498 17 }
mas01cr@509 18 if(header->headerSize != ADB_HEADER_SIZE) {
mas01cr@498 19 return false;
mas01cr@498 20 }
mas01cr@498 21 return true;
mas01cr@498 22 }
mas01cr@498 23
mas01cr@498 24 static int audiodb_collect_keys(adb_t *adb) {
mas01cr@498 25 char *key_table = 0;
mas01cr@498 26 size_t key_table_length = 0;
mas01cr@498 27
mas01cr@498 28 if(adb->header->length > 0) {
mas01cr@498 29 unsigned nfiles = adb->header->numFiles;
mas01cr@509 30 key_table_length = align_page_up(nfiles * ADB_FILETABLE_ENTRY_SIZE);
mas01cr@596 31 malloc_and_fill_or_goto_error(char *, key_table, adb->header->fileTableOffset, key_table_length);
mas01cr@498 32 for (unsigned int k = 0; k < nfiles; k++) {
mas01cr@509 33 adb->keys->push_back(key_table + k*ADB_FILETABLE_ENTRY_SIZE);
mas01cr@509 34 (*adb->keymap)[(key_table + k*ADB_FILETABLE_ENTRY_SIZE)] = k;
mas01cr@498 35 }
mas01cr@592 36 free(key_table);
mas01cr@498 37 }
mas01cr@498 38
mas01cr@498 39 return 0;
mas01cr@498 40
mas01cr@498 41 error:
mas01cr@596 42 maybe_free(key_table);
mas01cr@498 43 return 1;
mas01cr@498 44 }
mas01cr@498 45
mas01cr@498 46 static int audiodb_collect_track_lengths(adb_t *adb) {
mas01cr@498 47 uint32_t *track_table = 0;
mas01cr@498 48 size_t track_table_length = 0;
mas01cr@498 49 if(adb->header->length > 0) {
mas01cr@498 50 unsigned nfiles = adb->header->numFiles;
mas01cr@509 51 track_table_length = align_page_up(nfiles * ADB_TRACKTABLE_ENTRY_SIZE);
mas01cr@596 52 malloc_and_fill_or_goto_error(uint32_t *, track_table, adb->header->trackTableOffset, track_table_length);
mas01cr@498 53 off_t offset = 0;
mas01cr@498 54 for (unsigned int k = 0; k < nfiles; k++) {
mas01cr@498 55 uint32_t track_length = track_table[k];
mas01cr@498 56 adb->track_lengths->push_back(track_length);
mas01cr@498 57 adb->track_offsets->push_back(offset);
mas01cr@498 58 offset += track_length * adb->header->dim * sizeof(double);
mas01cr@498 59 }
mas01cr@592 60 free(track_table);
mas01cr@498 61 }
mas01cr@498 62
mas01cr@498 63 return 0;
mas01cr@498 64
mas01cr@498 65 error:
mas01cr@596 66 maybe_free(track_table);
mas01cr@498 67 return 1;
mas01cr@498 68 }
mas01cr@498 69
mas01cr@498 70 adb_t *audiodb_open(const char *path, int flags) {
mas01cr@498 71 adb_t *adb = 0;
mas01cr@498 72 int fd = -1;
mas01cr@498 73
mas01cr@498 74 flags &= (O_RDONLY|O_RDWR);
mas01cr@498 75 fd = open(path, flags);
mas01cr@498 76 if(fd == -1) {
mas01cr@498 77 goto error;
mas01cr@498 78 }
mas01cr@498 79 if(acquire_lock(fd, flags == O_RDWR)) {
mas01cr@498 80 goto error;
mas01cr@498 81 }
mas01cr@498 82
mas01cr@498 83 adb = (adb_t *) calloc(1, sizeof(adb_t));
mas01cr@498 84 if(!adb) {
mas01cr@498 85 goto error;
mas01cr@498 86 }
mas01cr@498 87 adb->fd = fd;
mas01cr@498 88 adb->flags = flags;
mas01cr@498 89 adb->path = (char *) malloc(1+strlen(path));
mas01cr@498 90 if(!(adb->path)) {
mas01cr@498 91 goto error;
mas01cr@498 92 }
mas01cr@498 93 strcpy(adb->path, path);
mas01cr@498 94
mas01cr@498 95 adb->header = (adb_header_t *) malloc(sizeof(adb_header_t));
mas01cr@498 96 if(!(adb->header)) {
mas01cr@498 97 goto error;
mas01cr@498 98 }
mas01cr@509 99 if(read(fd, (char *) adb->header, ADB_HEADER_SIZE) != ADB_HEADER_SIZE) {
mas01cr@498 100 goto error;
mas01cr@498 101 }
mas01cr@498 102 if(!audiodb_check_header(adb->header)) {
mas01cr@498 103 goto error;
mas01cr@498 104 }
mas01cr@498 105
mas01cr@498 106 adb->keys = new std::vector<std::string>;
mas01cr@498 107 if(!adb->keys) {
mas01cr@498 108 goto error;
mas01cr@498 109 }
mas01cr@498 110 adb->keymap = new std::map<std::string,uint32_t>;
mas01cr@498 111 if(!adb->keymap) {
mas01cr@498 112 goto error;
mas01cr@498 113 }
mas01cr@498 114 if(audiodb_collect_keys(adb)) {
mas01cr@498 115 goto error;
mas01cr@498 116 }
mas01cr@498 117 adb->track_lengths = new std::vector<uint32_t>;
mas01cr@498 118 if(!adb->track_lengths) {
mas01cr@498 119 goto error;
mas01cr@498 120 }
mas01cr@498 121 adb->track_lengths->reserve(adb->header->numFiles);
mas01cr@498 122 adb->track_offsets = new std::vector<off_t>;
mas01cr@498 123 if(!adb->track_offsets) {
mas01cr@498 124 goto error;
mas01cr@498 125 }
mas01cr@498 126 adb->track_offsets->reserve(adb->header->numFiles);
mas01cr@498 127 if(audiodb_collect_track_lengths(adb)) {
mas01cr@498 128 goto error;
mas01cr@498 129 }
mas01cr@498 130 adb->cached_lsh = 0;
mas01cr@498 131 return adb;
mas01cr@498 132
mas01cr@498 133 error:
mas01cr@498 134 if(adb) {
mas01cr@596 135 maybe_free(adb->header);
mas01cr@596 136 maybe_free(adb->path);
mas01cr@498 137 if(adb->keys) {
mas01cr@498 138 delete adb->keys;
mas01cr@498 139 }
mas01cr@498 140 if(adb->keymap) {
mas01cr@498 141 delete adb->keymap;
mas01cr@498 142 }
mas01cr@498 143 if(adb->track_lengths) {
mas01cr@498 144 delete adb->track_lengths;
mas01cr@498 145 }
mas01cr@498 146 free(adb);
mas01cr@498 147 }
mas01cr@498 148 if(fd != -1) {
mas01cr@498 149 close(fd);
mas01cr@498 150 }
mas01cr@498 151 return NULL;
mas01cr@498 152 }