#include "external-agent.h"
#include "logging.h"
+#include "lock-tracking.h"
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
static struct tdb_context *tdb;
-#if 1 /* FIXME */
-static unsigned int locking_would_block = 0;
-static bool nonblocking_locks = false;
-#endif
-
static enum agent_return do_operation(enum operation op, const char *name)
{
TDB_DATA k;
enum agent_return ret;
TDB_DATA data;
+ enum TDB_ERROR ecode;
if (op != OPEN && !tdb) {
diag("external: No tdb open!");
return OTHER_FAILURE;
}
- k.dptr = (void *)name;
- k.dsize = strlen(name);
+ diag("external: %s", operation_name(op));
+
+ k = tdb_mkdata(name, strlen(name));
locking_would_block = 0;
switch (op) {
if (!tdb) {
if (!locking_would_block)
diag("Opening tdb gave %s", strerror(errno));
+ forget_locking();
ret = OTHER_FAILURE;
} else
ret = SUCCESS;
break;
case FETCH:
- data = tdb_fetch(tdb, k);
- if (data.dptr == NULL) {
- if (tdb_error(tdb) == TDB_ERR_NOEXIST)
- ret = FAILED;
- else
- ret = OTHER_FAILURE;
- } else if (data.dsize != k.dsize
- || memcmp(data.dptr, k.dptr, k.dsize) != 0) {
+ ecode = tdb_fetch(tdb, k, &data);
+ if (ecode == TDB_ERR_NOEXIST) {
+ ret = FAILED;
+ } else if (ecode < 0) {
+ ret = OTHER_FAILURE;
+ } else if (!tdb_deq(data, k)) {
ret = OTHER_FAILURE;
+ free(data.dptr);
} else {
ret = SUCCESS;
+ free(data.dptr);
}
- free(data.dptr);
break;
case STORE:
ret = tdb_store(tdb, k, k, 0) == 0 ? SUCCESS : OTHER_FAILURE;
break;
-#if 0 /* FIXME */
case TRANSACTION_START:
ret = tdb_transaction_start(tdb) == 0 ? SUCCESS : OTHER_FAILURE;
break;
case NEEDS_RECOVERY:
ret = tdb_needs_recovery(tdb) ? SUCCESS : FAILED;
break;
-#endif
case CHECK:
ret = tdb_check(tdb, NULL, NULL) == 0 ? SUCCESS : OTHER_FAILURE;
break;
case FETCH: return "FETCH";
case STORE: return "STORE";
case CHECK: return "CHECK";
-#if 0
case TRANSACTION_START: return "TRANSACTION_START";
case TRANSACTION_COMMIT: return "TRANSACTION_COMMIT";
case NEEDS_RECOVERY: return "NEEDS_RECOVERY";
-#endif
case CLOSE: return "CLOSE";
}
return "**INVALID**";
}
+
+void free_external_agent(struct agent *agent)
+{
+ close(agent->cmdfd);
+ close(agent->responsefd);
+ free(agent);
+}