aboutsummaryrefslogtreecommitdiffstats
path: root/src/libstrongswan/plugins/sqlite/sqlite_database.c
diff options
context:
space:
mode:
authorTobias Brunner <tobias@strongswan.org>2017-05-26 13:57:57 +0200
committerTobias Brunner <tobias@strongswan.org>2017-05-26 14:24:13 +0200
commitb668bf3f9ec1e6e44cb31c727ac928105e383b32 (patch)
treedb62e4fcd1a955b5179c6f172a9403500bb24e50 /src/libstrongswan/plugins/sqlite/sqlite_database.c
parent0da10b73addd8c181bed0772c7eac32d28d8af77 (diff)
parent2e4d110d1e94a3be9da06894832492ff469eec37 (diff)
downloadstrongswan-b668bf3f9ec1.tar.bz2
strongswan-b668bf3f9ec1.tar.xz
Merge branch 'variadic-enumerators'
This adds several changes to enumerator_t and linked_list_t to improve portability. In particular to Apple's ARM64 iOS platform, whose calling convention for variadic and regular functions are different. This means that assigning a non-variadic function to a variadic function pointer, as we did with our enumerator_t::enumerate() implementations and several callbacks, will result in crashes as the called function will access the arguments differently than the caller provided them. To avoid this issue the enumerator_t interface is now fully variadic. A new mandatory method is added, venumerate(), that takes a va_list with the arguments provided while enumerating. enumerate() is replaced with a generic implementation that prepares a va_list and calls the enumerator's venumerate() implementation. As this allows passing the arguments of one enumerator to another it avoids the five pointer hack used by enumerator_create_nested() and enumerator_create_cleaner(). To simplify the implementation of venumerate() a helper macro is provided that assigns values from a given va_list to local variables. The signature of the callback passed to enumerator_create_filter() has also changed significantly. It's now required to enumerate over the original enumerator in the callback as this avoids the previous in/out pointer hack. The arguments to the outer enumerator are provided in a va_list. Similar changes to avoid such five pointer hacks affect the signatures of the callbacks for linked_list_t's invoke_function() and find_first() methods. For the latter the return type also changed from status_t to bool, which is important as SUCCESS is defined as 0, so checks for == SUCCESS will now fail.
Diffstat (limited to 'src/libstrongswan/plugins/sqlite/sqlite_database.c')
-rw-r--r--src/libstrongswan/plugins/sqlite/sqlite_database.c33
1 files changed, 15 insertions, 18 deletions
diff --git a/src/libstrongswan/plugins/sqlite/sqlite_database.c b/src/libstrongswan/plugins/sqlite/sqlite_database.c
index 0a35e3017..9f874212e 100644
--- a/src/libstrongswan/plugins/sqlite/sqlite_database.c
+++ b/src/libstrongswan/plugins/sqlite/sqlite_database.c
@@ -174,10 +174,8 @@ typedef struct {
private_sqlite_database_t *database;
} sqlite_enumerator_t;
-/**
- * destroy a sqlite enumerator
- */
-static void sqlite_enumerator_destroy(sqlite_enumerator_t *this)
+METHOD(enumerator_t, sqlite_enumerator_destroy, void,
+ sqlite_enumerator_t *this)
{
sqlite3_finalize(this->stmt);
if (!is_threadsave())
@@ -188,13 +186,10 @@ static void sqlite_enumerator_destroy(sqlite_enumerator_t *this)
free(this);
}
-/**
- * Implementation of database.query().enumerate
- */
-static bool sqlite_enumerator_enumerate(sqlite_enumerator_t *this, ...)
+METHOD(enumerator_t, sqlite_enumerator_enumerate, bool,
+ sqlite_enumerator_t *this, va_list args)
{
int i;
- va_list args;
switch (sqlite3_step(this->stmt))
{
@@ -207,7 +202,7 @@ static bool sqlite_enumerator_enumerate(sqlite_enumerator_t *this, ...)
case SQLITE_DONE:
return FALSE;
}
- va_start(args, this);
+
for (i = 0; i < this->count; i++)
{
switch (this->columns[i])
@@ -245,11 +240,9 @@ static bool sqlite_enumerator_enumerate(sqlite_enumerator_t *this, ...)
}
default:
DBG1(DBG_LIB, "invalid result type supplied");
- va_end(args);
return FALSE;
}
}
- va_end(args);
return TRUE;
}
@@ -270,13 +263,17 @@ METHOD(database_t, query, enumerator_t*,
stmt = run(this, sql, &args);
if (stmt)
{
- enumerator = malloc_thing(sqlite_enumerator_t);
- enumerator->public.enumerate = (void*)sqlite_enumerator_enumerate;
- enumerator->public.destroy = (void*)sqlite_enumerator_destroy;
- enumerator->stmt = stmt;
- enumerator->count = sqlite3_column_count(stmt);
+ INIT(enumerator,
+ .public = {
+ .enumerate = enumerator_enumerate_default,
+ .venumerate = _sqlite_enumerator_enumerate,
+ .destroy = _sqlite_enumerator_destroy,
+ },
+ .stmt = stmt,
+ .count = sqlite3_column_count(stmt),
+ .database = this,
+ );
enumerator->columns = malloc(sizeof(db_type_t) * enumerator->count);
- enumerator->database = this;
for (i = 0; i < enumerator->count; i++)
{
enumerator->columns[i] = va_arg(args, db_type_t);