annotate open.cpp @ 392:78fed0d4c108 api-inversion

Include some necessary information in struct adb. Now the struct adb contains a database fd, the flags used to open that fd (so that we can later tell if it was for write or not) and a database header pointer. audiodb_open() is now responsible for filling in all of that information. To do that, it needs to take an open(2) flag; that's good, because it means that the call to open(2) is no longer invoking undefined behaviour. (Also, the previous version of audiodb_open() leaked an fd). Unfortunately, that means we have broken ABI and API compatibility. (Fortunately, we have fewer than 12 users). Use audiodb_open() in audioDB::initDBHeader(). We've temporarily(?) put acquire_lock(int, bool) in the API header; that means we need to include <stdbool.h> and compile C files with -std=c99. Do so. Make audiodb_close() free resources allocated by audiodb_open(). Include a struct adb * field in the audioDB C++ object... ... which lets us actually implement memory-correctness, by audiodb_close()ing the database in audioDB::cleanup(). [ The lock is, I think, correctly disposed of; man fcntl(2) on Linux says that the locks are released once any file descriptor relating to the file is closed, and we close the fd in audiodb_close(). ]
author mas01cr
date Mon, 24 Nov 2008 15:42:15 +0000
parents
children 58b88ab69424
rev   line source
mas01cr@392 1 #include "audioDB.h"
mas01cr@392 2 extern "C" {
mas01cr@392 3 #include "audioDB_API.h"
mas01cr@392 4 }
mas01cr@392 5
mas01cr@392 6 bool audiodb_check_header(adb_header_t *header) {
mas01cr@392 7 /* FIXME: use syslog() or write to stderr or something to give the
mas01cr@392 8 poor user some diagnostics. */
mas01cr@392 9 if(header->magic == O2_OLD_MAGIC) {
mas01cr@392 10 return false;
mas01cr@392 11 }
mas01cr@392 12 if(header->magic != O2_MAGIC) {
mas01cr@392 13 return false;
mas01cr@392 14 }
mas01cr@392 15 if(header->version != O2_FORMAT_VERSION) {
mas01cr@392 16 return false;
mas01cr@392 17 }
mas01cr@392 18 if(header->headerSize != O2_HEADERSIZE) {
mas01cr@392 19 return false;
mas01cr@392 20 }
mas01cr@392 21 return true;
mas01cr@392 22 }
mas01cr@392 23
mas01cr@392 24 adb_t *audiodb_open(const char *path, int flags) {
mas01cr@392 25 adb_t *adb = 0;
mas01cr@392 26 int fd = -1;
mas01cr@392 27
mas01cr@392 28 flags &= (O_RDONLY|O_RDWR);
mas01cr@392 29 fd = open(path, flags);
mas01cr@392 30 if(fd == -1) {
mas01cr@392 31 goto error;
mas01cr@392 32 }
mas01cr@392 33 if(acquire_lock(fd, flags == O_RDWR)) {
mas01cr@392 34 goto error;
mas01cr@392 35 }
mas01cr@392 36
mas01cr@392 37 adb = (adb_t *) malloc(sizeof(adb_t));
mas01cr@392 38 if(!adb) {
mas01cr@392 39 goto error;
mas01cr@392 40 }
mas01cr@392 41 adb->fd = fd;
mas01cr@392 42 adb->flags = flags;
mas01cr@392 43 adb->path = (char *) malloc(1+strlen(path));
mas01cr@392 44 if(!(adb->path)) {
mas01cr@392 45 goto error;
mas01cr@392 46 }
mas01cr@392 47 strcpy(adb->path, path);
mas01cr@392 48
mas01cr@392 49 adb->header = (adb_header_t *) malloc(sizeof(adb_header_t));
mas01cr@392 50 if(!(adb->header)) {
mas01cr@392 51 goto error;
mas01cr@392 52 }
mas01cr@392 53 if(read(fd, (char *) adb->header, O2_HEADERSIZE) != O2_HEADERSIZE) {
mas01cr@392 54 goto error;
mas01cr@392 55 }
mas01cr@392 56 if(!audiodb_check_header(adb->header)) {
mas01cr@392 57 goto error;
mas01cr@392 58 }
mas01cr@392 59
mas01cr@392 60 return adb;
mas01cr@392 61
mas01cr@392 62 error:
mas01cr@392 63 if(adb) {
mas01cr@392 64 if(adb->header) {
mas01cr@392 65 free(adb->header);
mas01cr@392 66 }
mas01cr@392 67 if(adb->path) {
mas01cr@392 68 free(adb->path);
mas01cr@392 69 }
mas01cr@392 70 free(adb);
mas01cr@392 71 }
mas01cr@392 72 if(fd != -1) {
mas01cr@392 73 close(fd);
mas01cr@392 74 }
mas01cr@392 75 return NULL;
mas01cr@392 76 }