Commit 9a04478c authored by Yoni Fogel's avatar Yoni Fogel

All malloced memory is freed before quitting.

git-svn-id: file:///svn/tokudb@432 c7de825b-a66e-492c-adef-691d508d4ae1
parent 4ea05c72
CFLAGS = -std=gnu89 -W -Wall -Wno-unused -g -fPIC -I /usr/local/Berkeleydb.4.1/include/ -ldb CFLAGS = -std=gnu89 -W -Wall -Wno-unused -g -fPIC -I /usr/local/Berkeleydb.4.1/include/ -ldb
LFLAGS = -l CPPFLAGS = -I../include -I../newbrt LFLAGS = -l CPPFLAGS =
#cc $(CPPFLAGS) $(DBBINS) -shared -o libdb.so $(CFLAGS)
BDB_DUMP=/usr/local/Berkeleydb.4.1/bin/db_dump BDB_DUMP=/usr/local/Berkeleydb.4.1/bin/db_dump
BDB_LOAD=/usr/local/Berkeleydb.4.1/bin/db_load BDB_LOAD=/usr/local/Berkeleydb.4.1/bin/db_load
...@@ -12,7 +10,7 @@ UTILS= \ ...@@ -12,7 +10,7 @@ UTILS= \
# tokudb_dump \ # tokudb_dump \
#End #End
.PHONY: all clean test test_gen test_gen_hex .PHONY: all clean test test_gen test_gen_hex test_load
all: $(UTILS) all: $(UTILS)
...@@ -54,7 +52,6 @@ test_load: test_gen ...@@ -54,7 +52,6 @@ test_load: test_gen
$(BDB_DUMP) $@.tokudb.temp > $@.dump.tokudb.temp $(BDB_DUMP) $@.tokudb.temp > $@.dump.tokudb.temp
if ! diff -q $@.dump.bdb.temp $@.dump.tokudb.temp; then echo "Test Failed!"; exit 1; fi if ! diff -q $@.dump.bdb.temp $@.dump.tokudb.temp; then echo "Test Failed!"; exit 1; fi
#if diff -q <(echo "foo") <(echo "foo") > /dev/null; then echo yes; else echo no; fi #if diff -q <(echo "foo") <(echo "foo") > /dev/null; then echo yes; else echo no; fi
clean: clean:
rm -rf *.so *.o $(UTILS) *.temp rm -rf *.so *.o $(UTILS) *.temp
......
...@@ -52,7 +52,7 @@ int name(DB* db, char* progname, char* str, type* num, type min, type max, int b ...@@ -52,7 +52,7 @@ int name(DB* db, char* progname, char* str, type* num, type min, type max, int b
value = strtofunc(str, &test, base); \ value = strtofunc(str, &test, base); \
if ((*test != '\0' && *test != '\n') || test == str) { \ if ((*test != '\0' && *test != '\n') || test == str) { \
if (db == NULL) fprintf(stderr, "%s: %s: Invalid numeric argument\n", progname, str); \ if (db == NULL) fprintf(stderr, "%s: %s: Invalid numeric argument\n", progname, str); \
else db->errx(db, "%s: Invalid numeric argument", str); \ else db->errx(db, "%s: Invalid numeric argument", str); \
errno = EINVAL; \ errno = EINVAL; \
goto error; \ goto error; \
} \ } \
......
...@@ -6,17 +6,16 @@ ...@@ -6,17 +6,16 @@
#include <ctype.h> #include <ctype.h>
#include <errno.h> #include <errno.h>
#include <getopt.h> #include <getopt.h>
#include <db.h> #include <db.h>
#include "tokudb_common.h" #include "tokudb_common.h"
extern char* optarg; typedef struct {
extern int optind; char* data[2];
extern int optopt; } gdbt;
extern int opterr;
extern int optreset;
typedef struct {
char* data;
} rhdr;
typedef struct { typedef struct {
bool leadingspace; bool leadingspace;
...@@ -37,6 +36,12 @@ typedef struct { ...@@ -37,6 +36,12 @@ typedef struct {
DBTYPE dbtype; DBTYPE dbtype;
DB* db; DB* db;
DB_ENV* dbenv; DB_ENV* dbenv;
struct {
char* data[2];
} get_dbt;
struct {
char* data;
} read_header;
} load_globals; } load_globals;
load_globals g; load_globals g;
...@@ -92,7 +97,8 @@ int main(int argc, char *argv[]) { ...@@ -92,7 +97,8 @@ int main(int argc, char *argv[]) {
goto error; goto error;
} }
case ('H'): { case ('H'): {
return longusage(); g.exitcode = longusage();
goto cleanup;
} }
case ('T'): { case ('T'): {
g.plaintext = true; g.plaintext = true;
...@@ -141,40 +147,43 @@ int main(int argc, char *argv[]) { ...@@ -141,40 +147,43 @@ int main(int argc, char *argv[]) {
} }
case ('?'): case ('?'):
default: { default: {
return usage(); g.exitcode = usage();
goto cleanup;
} }
} }
} }
argc -= optind; argc -= optind;
argv += optind; argv += optind;
if (argc != 1) return usage(); if (argc != 1) {
g.exitcode = usage();
goto cleanup;
}
//TODO: /* Handle possible interruptions/signals. */ //TODO: /* Handle possible interruptions/signals. */
g.database = argv[0]; g.database = argv[0];
if (create_init_env() != 0) goto error; if (create_init_env() != 0) goto error;
while (!g.eof) { while (!g.eof) {
//BOOKMARK if (load_database() != 0) goto error;
if (load_database() != 0) goto errorcleanup;
} }
if (false) { if (false) {
errorcleanup: error:
g.exitcode = EXIT_FAILURE; g.exitcode = EXIT_FAILURE;
fprintf(stderr, "%s: Quitting out due to errors.\n", g.progname);
} }
cleanup: cleanup:
if ((retval = g.dbenv->close(g.dbenv, 0)) != 0) { if (g.dbenv && (retval = g.dbenv->close(g.dbenv, 0)) != 0) {
g.exitcode = EXIT_FAILURE; g.exitcode = EXIT_FAILURE;
fprintf(stderr, "%s: dbenv->close: %s\n", g.progname, db_strerror(retval)); fprintf(stderr, "%s: dbenv->close: %s\n", g.progname, db_strerror(retval));
} }
//TODO: /* Resend any caught signal. */ //TODO: /* Resend any caught signal. */
free(g.config_options); if (g.config_options) free(g.config_options);
if (g.subdatabase) free(g.subdatabase);
if (g.read_header.data) free(g.read_header.data);
if (g.get_dbt.data[0]) free(g.get_dbt.data[0]);
if (g.get_dbt.data[1]) free(g.get_dbt.data[1]);
return g.exitcode; return g.exitcode;
error:
fprintf(stderr, "%s: Quitting out due to errors.\n", g.progname);
return EXIT_FAILURE;
//TODO:free all malloced memory (may require static stuff turning global)
} }
int load_database() int load_database()
...@@ -256,7 +265,7 @@ int create_init_env() ...@@ -256,7 +265,7 @@ int create_init_env()
fprintf(stderr, "%s: db_dbenv_create: %s\n", g.progname, db_strerror(retval)); fprintf(stderr, "%s: db_dbenv_create: %s\n", g.progname, db_strerror(retval));
goto error; goto error;
} }
dbenv->set_errfile(dbenv, stderr); ///TODO: UNCOMMENT/IMPLEMENT dbenv->set_errfile(dbenv, stderr);
dbenv->set_errpfx(dbenv, g.progname); dbenv->set_errpfx(dbenv, g.progname);
/* /*
TODO: If/when supporting encryption TODO: If/when supporting encryption
...@@ -269,11 +278,18 @@ int create_init_env() ...@@ -269,11 +278,18 @@ int create_init_env()
/* Open the dbenvironment. */ /* Open the dbenvironment. */
g.is_private = false; g.is_private = false;
// flags = DB_JOINENV | DB_INIT_LOCK | DB_INIT_LOG | DB_INIT_MPOOL | DB_USE_ENVIRON; // flags = DB_JOINENV | DB_INIT_LOCK | DB_INIT_LOG | DB_INIT_MPOOL | DB_USE_ENVIRON;
flags = DB_INIT_LOCK | DB_INIT_LOG | DB_INIT_MPOOL | DB_USE_ENVIRON; flags = DB_INIT_LOCK | DB_INIT_LOG | DB_INIT_MPOOL; ///TODO: UNCOMMENT/IMPLEMENT | DB_USE_ENVIRON;
//TODO: Transactions.. SET_BITS(flags, DB_INIT_TXN); //TODO: Transactions.. SET_BITS(flags, DB_INIT_TXN);
/*
///TODO: UNCOMMENT/IMPLEMENT Notes: We require DB_PRIVATE
if (!dbenv->open(dbenv, g.homedir, flags, 0)) goto success; if (!dbenv->open(dbenv, g.homedir, flags, 0)) goto success;
*/
/*
///TODO: UNCOMMENT/IMPLEMENT
retval = dbenv->set_cachesize(dbenv, 0, cache, 1); retval = dbenv->set_cachesize(dbenv, 0, cache, 1);
*/
if (retval) { if (retval) {
dbenv->err(dbenv, retval, "DB_ENV->set_cachesize"); dbenv->err(dbenv, retval, "DB_ENV->set_cachesize");
goto error; goto error;
...@@ -285,7 +301,7 @@ int create_init_env() ...@@ -285,7 +301,7 @@ int create_init_env()
REMOVE_BITS(flags, DB_INIT_LOCK | DB_INIT_LOG | DB_INIT_TXN); REMOVE_BITS(flags, DB_INIT_LOCK | DB_INIT_LOG | DB_INIT_TXN);
SET_BITS(flags, DB_CREATE | DB_PRIVATE); SET_BITS(flags, DB_CREATE | DB_PRIVATE);
retval = dbenv->open(dbenv, g.homedir, flags, 0); retval = dbenv->open(dbenv, g.homedir ? g.homedir : ".", flags, 0);
if (retval) { if (retval) {
dbenv->err(dbenv, retval, "DB_ENV->open"); dbenv->err(dbenv, retval, "DB_ENV->open");
goto error; goto error;
...@@ -309,6 +325,7 @@ int printabletocstring(char* inputstr, char** poutputstr) ...@@ -309,6 +325,7 @@ int printabletocstring(char* inputstr, char** poutputstr)
assert(inputstr); assert(inputstr);
assert(poutputstr); assert(poutputstr);
assert(*poutputstr == NULL);
cstring = (char*)malloc((strlen(inputstr) + 1) * sizeof(char)); cstring = (char*)malloc((strlen(inputstr) + 1) * sizeof(char));
if (cstring == NULL) { if (cstring == NULL) {
...@@ -353,13 +370,15 @@ int printabletocstring(char* inputstr, char** poutputstr) ...@@ -353,13 +370,15 @@ int printabletocstring(char* inputstr, char** poutputstr)
return EXIT_FAILURE; return EXIT_FAILURE;
} }
///TODO: IMPLEMENT/Replace original line.
#define PARSE_NUMBER(match, dbfunction) \ #define PARSE_NUMBER(match, dbfunction) \
if (!strcmp(field, match)) { \ if (!strcmp(field, match)) { \
if (strtoint32(db, NULL, value, &num, 1, INT32_MAX, 10)) goto error; \ if (strtoint32(db, NULL, value, &num, 1, INT32_MAX, 10)) goto error; \
if ((retval = dbfunction(db, num)) != 0) goto printerror; \ /*if ((retval = dbfunction(db, num)) != 0) goto printerror;*/ \
continue; \ continue; \
} }
///TODO: IMPLEMENT/Replace original line.
#define PARSE_UNSUPPORTEDNUMBER(match, dbfunction) \ #define PARSE_UNSUPPORTEDNUMBER(match, dbfunction) \
if (!strcmp(field, match)) { \ if (!strcmp(field, match)) { \
if (strtoint32(db, NULL, value, &num, 1, INT32_MAX, 10)) goto error; \ if (strtoint32(db, NULL, value, &num, 1, INT32_MAX, 10)) goto error; \
...@@ -412,7 +431,6 @@ if (!strcmp(field, match)) { \ ...@@ -412,7 +431,6 @@ if (!strcmp(field, match)) { \
int read_header() int read_header()
{ {
static char* data = NULL;
static uint64_t datasize = 1 << 10; static uint64_t datasize = 1 << 10;
uint64_t index = 0; uint64_t index = 0;
char* field; char* field;
...@@ -425,7 +443,7 @@ int read_header() ...@@ -425,7 +443,7 @@ int read_header()
assert(g.header); assert(g.header);
if (data == NULL && (data = (char*)malloc(datasize * sizeof(char))) == NULL) { if (g.read_header.data == NULL && (g.read_header.data = (char*)malloc(datasize * sizeof(char))) == NULL) {
dbenv->err(dbenv, errno, ""); dbenv->err(dbenv, errno, "");
goto error; goto error;
} }
...@@ -442,17 +460,17 @@ int read_header() ...@@ -442,17 +460,17 @@ int read_header()
} }
if (ch == '\n') break; if (ch == '\n') break;
data[index] = ch; g.read_header.data[index] = ch;
index++; index++;
/* Ensure room exists for next character/null terminator. */ /* Ensure room exists for next character/null terminator. */
if (index == datasize && doublechararray(&data, &datasize)) goto error; if (index == datasize && doublechararray(&g.read_header.data, &datasize)) goto error;
} }
if (index == 0 && g.eof) goto success; if (index == 0 && g.eof) goto success;
data[index] = '\0'; g.read_header.data[index] = '\0';
field = data; field = g.read_header.data;
if ((value = strchr(data, '=')) == NULL) goto formaterror; if ((value = strchr(g.read_header.data, '=')) == NULL) goto formaterror;
value[0] = '\0'; value[0] = '\0';
value++; value++;
...@@ -610,6 +628,8 @@ int apply_commandline_options() ...@@ -610,6 +628,8 @@ int apply_commandline_options()
} }
continue; continue;
} }
/*
///TODO: UNCOMMENT/IMPLEMENT
PARSE_NUMBER( "bt_minkey", db->set_bt_minkey); PARSE_NUMBER( "bt_minkey", db->set_bt_minkey);
PARSE_NUMBER( "db_lorder", db->set_lorder); PARSE_NUMBER( "db_lorder", db->set_lorder);
PARSE_NUMBER( "db_pagesize", db->set_pagesize); PARSE_NUMBER( "db_pagesize", db->set_pagesize);
...@@ -623,6 +643,7 @@ int apply_commandline_options() ...@@ -623,6 +643,7 @@ int apply_commandline_options()
PARSE_FLAG( "dupsort", DB_DUPSORT); PARSE_FLAG( "dupsort", DB_DUPSORT);
PARSE_FLAG( "recnum", DB_RECNUM); PARSE_FLAG( "recnum", DB_RECNUM);
PARSE_UNSUPPORTEDFLAG( "renumber", DB_RENUMBER); PARSE_UNSUPPORTEDFLAG( "renumber", DB_RENUMBER);
*/
db->errx(db, "unknown input-file header configuration keyword \"%s\"", field); db->errx(db, "unknown input-file header configuration keyword \"%s\"", field);
goto error; goto error;
...@@ -660,6 +681,9 @@ int open_database() ...@@ -660,6 +681,9 @@ int open_database()
//TODO: Ensure we have enough cache to store some min number of btree pages. //TODO: Ensure we have enough cache to store some min number of btree pages.
//NOTE: This may require closing db, environment, and creating new ones. //NOTE: This may require closing db, environment, and creating new ones.
/*
///TODO: UNCOMMENT/IMPLEMENT
DBTYPE existingtype; DBTYPE existingtype;
retval = db->get_type(db, &existingtype); retval = db->get_type(db, &existingtype);
if (retval != 0) { if (retval != 0) {
...@@ -671,6 +695,7 @@ int open_database() ...@@ -671,6 +695,7 @@ int open_database()
fprintf(stderr, "Existing database is not a dictionary (DB_BTREE).\n"); fprintf(stderr, "Existing database is not a dictionary (DB_BTREE).\n");
goto error; goto error;
} }
*/
return EXIT_SUCCESS; return EXIT_SUCCESS;
error: error:
fprintf(stderr, "Quitting out due to errors.\n"); fprintf(stderr, "Quitting out due to errors.\n");
...@@ -718,7 +743,6 @@ int doublechararray(char** pmem, uint64_t* size) ...@@ -718,7 +743,6 @@ int doublechararray(char** pmem, uint64_t* size)
int get_dbt(DBT* pdbt) int get_dbt(DBT* pdbt)
{ {
/* Need to store a key and value. */ /* Need to store a key and value. */
static char* data[2] = {NULL, NULL};
static uint64_t datasize[2] = {1 << 10, 1 << 10}; static uint64_t datasize[2] = {1 << 10, 1 << 10};
static int which = 0; static int which = 0;
char* datum; char* datum;
...@@ -729,13 +753,13 @@ int get_dbt(DBT* pdbt) ...@@ -729,13 +753,13 @@ int get_dbt(DBT* pdbt)
/* *pdbt should have been memset to 0 before being called. */ /* *pdbt should have been memset to 0 before being called. */
which = 1 - which; which = 1 - which;
if (data[which] == NULL && if (g.get_dbt.data[which] == NULL &&
(data[which] = (char*)malloc(datasize[which] * sizeof(char))) == NULL) { (g.get_dbt.data[which] = (char*)malloc(datasize[which] * sizeof(char))) == NULL) {
db->err(db, errno, ""); db->err(db, errno, "");
goto error; goto error;
} }
datum = data[which]; datum = g.get_dbt.data[which];
if (g.plaintext) { if (g.plaintext) {
int firstch; int firstch;
...@@ -793,8 +817,8 @@ int get_dbt(DBT* pdbt) ...@@ -793,8 +817,8 @@ int get_dbt(DBT* pdbt)
} }
if (index == datasize[which]) { if (index == datasize[which]) {
/* Overflow, double the memory. */ /* Overflow, double the memory. */
if (doublechararray(&data[which], &datasize[which])) goto error; if (doublechararray(&g.get_dbt.data[which], &datasize[which])) goto error;
datum = data[which]; datum = g.get_dbt.data[which];
} }
datum[index] = nextch; datum[index] = nextch;
index++; index++;
...@@ -824,8 +848,8 @@ int get_dbt(DBT* pdbt) ...@@ -824,8 +848,8 @@ int get_dbt(DBT* pdbt)
} }
if (index == datasize[which]) { if (index == datasize[which]) {
/* Overflow, double the memory. */ /* Overflow, double the memory. */
if (doublechararray(&data[which], &datasize[which])) goto error; if (doublechararray(&g.get_dbt.data[which], &datasize[which])) goto error;
datum = data[which]; datum = g.get_dbt.data[which];
} }
datum[index] = (hextoint(highch) << 4) | hextoint(lowch); datum[index] = (hextoint(highch) << 4) | hextoint(lowch);
index++; index++;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment