Radish alpha
H
rad:z3QDZAW2FAfuLvihrhiyDC9fAD8G9
HardenedBSD Package Manager
Radicle
Git
Add a mechanism to register some callback for singal handing from the frontend
Baptiste Daroussin committed 10 years ago
commit a3aea6d1a043daed198657da388d2240453feddd
parent 7b287b1
4 files changed +80 -2
modified libpkg/pkg.h.in
@@ -1299,6 +1299,8 @@ typedef enum {
	PKG_EVENT_NEW_ACTION,
	PKG_EVENT_MESSAGE,
	PKG_EVENT_FILE_MISSING,
+
	PKG_EVENT_CLEANUP_CALLBACK_REGISTER,
+
	PKG_EVENT_CLEANUP_CALLBACK_UNREGISTER,
} pkg_event_t;

struct pkg_event {
@@ -1334,7 +1336,7 @@ struct pkg_event {
		} e_install_begin;
		struct {
			struct pkg *pkg;
-
      struct pkg *old;
+
			struct pkg *old;
		} e_install_finished;
		struct {
			struct pkg *pkg;
@@ -1455,6 +1457,10 @@ struct pkg_event {
			struct pkg *pkg;
			struct pkg_file *file;
		} e_file_missing;
+
		struct {
+
			void *data;
+
			void (*cleanup_cb)(void *data);
+
		} e_cleanup_callback;
	};
};

modified libpkg/pkg_event.c
@@ -1037,3 +1037,25 @@ pkg_emit_message(const char *message)
	ev.e_pkg_message.msg = message;
	pkg_emit_event(&ev);
}
+

+
void
+
pkg_register_cleanup_callback(void (*cleanup_cb)(void *data), void *data)
+
{
+
	struct pkg_event ev;
+

+
	ev.type = PKG_EVENT_CLEANUP_CALLBACK_REGISTER;
+
	ev.e_cleanup_callback.cleanup_cb = cleanup_cb;
+
	ev.e_cleanup_callback.data = data;
+
	pkg_emit_event(&ev);
+
}
+

+
void
+
pkg_unregister_cleanup_callback(void (*cleanup_cb)(void *data), void *data)
+
{
+
	struct pkg_event ev;
+

+
	ev.type = PKG_EVENT_CLEANUP_CALLBACK_UNREGISTER;
+
	ev.e_cleanup_callback.cleanup_cb = cleanup_cb;
+
	ev.e_cleanup_callback.data = data;
+
	pkg_emit_event(&ev);
+
}
modified libpkg/private/event.h
@@ -79,5 +79,7 @@ void pkg_emit_delete_files_finished(struct pkg *p);
void pkg_emit_new_action(void);
void pkg_emit_message(const char *msg);
void pkg_emit_file_missing(struct pkg *p, struct pkg_file *f);
+
void pkg_register_cleanup_callback(void (*cleanup_cb)(void *data), void *data);
+
void pkg_unregister_cleanup_callback(void (*cleanup_cb)(void *data), void *data);

#endif
modified src/event.c
@@ -50,6 +50,7 @@
#ifdef HAVE_LIBUTIL_H
#include <libutil.h>
#endif
+
#include <kvec.h>

#include <bsd_compat.h>

@@ -60,6 +61,11 @@

struct sbuf *messages = NULL;

+
struct cleanup {
+
	void *data;
+
	void (*cb)(void *);
+
};
+

static char *progress_message = NULL;
static struct sbuf *msg_buf = NULL;
static int last_progress_percent = -1;
@@ -72,6 +78,8 @@ static int64_t bytes_per_second;
static time_t last_update;
static time_t begin = 0;
static int add_deps_depth;
+
static kvec_t(struct cleanup *) cleanup_list;
+
static bool signal_handler_installed = false;

/* units for format_size */
static const char *unit_SI[] = { " ", "k", "M", "G", "T", };
@@ -80,6 +88,22 @@ static const char *unit_IEC[] = { " ", "Ki", "Mi", "Gi", "Ti", };
static void draw_progressbar(int64_t current, int64_t total);

static void
+
cleanup_handler(int dummy __unused)
+
{
+
	struct cleanup *ev;
+
	int i;
+

+
	if (kv_size(cleanup_list) == 0)
+
		return;
+
	warnx("\nsignal received, cleaning up");
+
	for (i = 0; i < kv_size(cleanup_list); i++) {
+
		ev = kv_A(cleanup_list, i);
+
		ev->cb(ev->data);
+
	}
+
	exit(1);
+
}
+

+
static void
format_rate_IEC(char *buf, int size, off_t bytes)
{
	int i;
@@ -544,7 +568,8 @@ int
event_callback(void *data, struct pkg_event *ev)
{
	struct pkg *pkg = NULL, *pkg_new, *pkg_old;
-
	int *debug = data;
+
	struct cleanup *evtmp;
+
	int *debug = data, i;
	struct pkg_event_conflict *cur_conflict;
	const char *filename;

@@ -850,6 +875,29 @@ event_callback(void *data, struct pkg_event *ev)
			messages = sbuf_new_auto();
		sbuf_cat(messages, ev->e_pkg_message.msg);
		break;
+
	case PKG_EVENT_CLEANUP_CALLBACK_REGISTER:
+
		if (!signal_handler_installed) {
+
			kv_init(cleanup_list);
+
			signal(SIGINT, cleanup_handler);
+
			signal_handler_installed = true;
+
		}
+
		evtmp = malloc(sizeof(struct cleanup));
+
		evtmp->cb = ev->e_cleanup_callback.cleanup_cb;
+
		evtmp->data = ev->e_cleanup_callback.data;
+
		kv_push(struct cleanup *, cleanup_list, evtmp);
+
		break;
+
	case PKG_EVENT_CLEANUP_CALLBACK_UNREGISTER:
+
		if (!signal_handler_installed)
+
			break;
+
		for (i = 0; i < kv_size(cleanup_list); i++) {
+
			evtmp = kv_A(cleanup_list, i);
+
			if (evtmp->cb == ev->e_cleanup_callback.cleanup_cb &&
+
			    evtmp->data == ev->e_cleanup_callback.data) {
+
				kv_del(struct cleanup *, cleanup_list, i);
+
				break;
+
			}
+
		}
+
		break;
	default:
		break;
	}