diff --git a/librz/core/cmd/cmd_search.c b/librz/core/cmd/cmd_search.c index 2bb493ca318..a869405be96 100644 --- a/librz/core/cmd/cmd_search.c +++ b/librz/core/cmd/cmd_search.c @@ -25,7 +25,7 @@ rz_search_opt_set_cancel_cb(core->search_opts, NULL, NULL); \ } while (0) -static bool cmd_search_progress_cancel(void *user, size_t n_hits) { +static bool cmd_search_progress_cancel(void *user, size_t n_hits, RzSearchCancelReason invoke_reason) { if (user) { // we have RzCmdStateOutput state rz_cons_printf("Searching... hits: %" PFMTSZu "\r", n_hits); diff --git a/librz/include/rz_search.h b/librz/include/rz_search.h index fb8dc45ca46..b3a545a2786 100644 --- a/librz/include/rz_search.h +++ b/librz/include/rz_search.h @@ -14,6 +14,7 @@ extern "C" { RZ_LIB_VERSION_HEADER(rz_search); #define RZ_SEARCH_MIN_BUFFER_SIZE 512u +#define RZ_SEARCH_CANCEL_CHECK_INTERVAL_USEC 1000 * 1000 typedef struct rz_search_opt_t RzSearchOpt; @@ -25,7 +26,22 @@ typedef struct rz_search_hit_t { size_t size; ///< Size of the matched data (can be 0) } RzSearchHit; -typedef bool (*RzSearchCancelCallback)(void *user, size_t n_hits); +typedef enum { + RZ_SEARCH_CANCEL_REGULAR_CHECK, ///< Regular cancel check. Repeated every RZ_SEARCH_CANCEL_CHECK_INTERVAL_USEC microseconds. + RZ_SEARCH_CANCEL_SIGINT, ///< Interrupt signal (likely ctrl + c). +} RzSearchCancelReason; + +/** + * \brief The cancel callback. It is invoked to check, if the search should be stopped. + * + * \param user The private user data. + * \param n_hits Number of hits already found during the search. + * \param invoe_reason The reason it is called. + * + * \return True, if the search should be canceled. + * \return False, if the search should continue. + */ +typedef bool (*RzSearchCancelCallback)(void *user, size_t n_hits, RzSearchCancelReason invoke_reason); RZ_API RZ_OWN RzSearchOpt *rz_search_opt_new(); RZ_API void rz_search_opt_free(RZ_NULLABLE RzSearchOpt *opt); diff --git a/librz/main/rz-find.c b/librz/main/rz-find.c index 057249649af..12709000e03 100644 --- a/librz/main/rz-find.c +++ b/librz/main/rz-find.c @@ -260,7 +260,7 @@ static inline RzBinFile *core_get_file(RzCoreFile *cfile) { return rz_pvector_at(&cfile->binfiles, 0); } -static bool rz_find_search_progress_cancel(void *user, size_t n_hits) { +static bool rz_find_search_progress_cancel(void *user, size_t n_hits, RzSearchCancelReason invoke_reason) { return rz_cons_is_breaked(); } diff --git a/librz/search/search.c b/librz/search/search.c index 3afc413fe5e..1d6cae82733 100644 --- a/librz/search/search.c +++ b/librz/search/search.c @@ -12,7 +12,7 @@ typedef struct search_ctx { RzSearchCollection *col; ///< collection to use RzSearchOpt *opt; ///< User options RzThreadQueue *hits; ///< Hits list - RzAtomicBool *loop; ///< used to stop or not the execution + RzAtomicBool *loop; ///< If set, the execution will continue until it terminates. If unset, the execution cancels. } search_ctx_t; static void *search_cancel_th(void *user) { @@ -21,11 +21,11 @@ static void *search_cancel_th(void *user) { do { size_t n_hits = rz_th_queue_size(ctx->hits); - if (!opt->cancel_cb(opt->cancel_usr, n_hits)) { + if (!opt->cancel_cb(opt->cancel_usr, n_hits, RZ_SEARCH_CANCEL_REGULAR_CHECK)) { rz_atomic_bool_set(ctx->loop, false); break; } - rz_sys_usleep(100000); + rz_sys_usleep(RZ_SEARCH_CANCEL_CHECK_INTERVAL_USEC); } while (rz_atomic_bool_get(ctx->loop)); return NULL; @@ -174,4 +174,4 @@ RZ_API void rz_search_hit_free(RZ_NULLABLE RzSearchHit *hit) { } free(hit->metadata); free(hit); -} \ No newline at end of file +}