From a6e66d7cb703cf183e52e9bc7c4c86e375dbbb25 Mon Sep 17 00:00:00 2001 From: Scoopta Date: Wed, 7 Feb 2024 18:16:11 -0800 Subject: [PATCH] Added wofi_exit(). This allows correct handling of custom exit status codes on non-glibc systems. This function should always be used for exiting wofi as libc exit() will no longer correctly handle error situations. --- inc/wofi_api.h | 4 +++- man/wofi-api.3 | 4 ++++ meson.build | 2 +- modes/dmenu.c | 4 ++-- modes/drun.c | 18 +++++++++--------- modes/run.c | 6 +++--- src/wofi.c | 38 +++++++++++++++++++++++--------------- 7 files changed, 45 insertions(+), 31 deletions(-) diff --git a/inc/wofi_api.h b/inc/wofi_api.h index eced395..45fd0c4 100644 --- a/inc/wofi_api.h +++ b/inc/wofi_api.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020 Scoopta + * Copyright (C) 2020-2024 Scoopta * This file is part of Wofi * Wofi is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -58,4 +58,6 @@ bool wofi_mod_control(void); void wofi_term_run(const char* cmd); +void wofi_exit(int status); + #endif diff --git a/man/wofi-api.3 b/man/wofi-api.3 index 816c27b..fb067b6 100644 --- a/man/wofi-api.3 +++ b/man/wofi-api.3 @@ -110,3 +110,7 @@ Runs the provided cmd in a terminal emulator. The following order is used for pi .B const char* cmd \- The command to run, this is invoked by doing \fBterm \-\- cmd\fR. + +.TP +.B void wofi_exit(void) +This function is how you should call to exit wofi. It checks the status given and only sets a custom exit code if you pass EXIT_SUCCESS. If you call the libc exit() function then the custom exit code will always be used even if an error should be reported diff --git a/meson.build b/meson.build index fc72bb3..e141508 100644 --- a/meson.build +++ b/meson.build @@ -1,4 +1,4 @@ -project('wofi', 'c', version : 'v1.4', default_options : ['c_std=c99', 'buildtype=release', 'warning_level=2']) +project('wofi', 'c', version : 'hg', default_options : ['c_std=c99', 'buildtype=release', 'warning_level=2']) cc = meson.get_compiler('c') pkgcfg = import('pkgconfig') diff --git a/modes/dmenu.c b/modes/dmenu.c index 377df4f..787000d 100644 --- a/modes/dmenu.c +++ b/modes/dmenu.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019-2020 Scoopta + * Copyright (C) 2019-2024 Scoopta * This file is part of Wofi * Wofi is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -156,7 +156,7 @@ void wofi_dmenu_exec(const gchar* cmd) { } printf("%s\n", action); free(action); - exit(0); + wofi_exit(0); } const char** wofi_dmenu_get_arg_names(void) { diff --git a/modes/drun.c b/modes/drun.c index afafba0..ac61afa 100644 --- a/modes/drun.c +++ b/modes/drun.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019-2023 Scoopta + * Copyright (C) 2019-2024 Scoopta * This file is part of Wofi * Wofi is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -398,7 +398,7 @@ struct widget* wofi_drun_get_widget(void) { static void launch_done(GObject* obj, GAsyncResult* result, gpointer data) { GError* err = NULL; if(g_app_info_launch_uris_finish(G_APP_INFO(obj), result, &err)) { - exit(0); + wofi_exit(0); } else if(err != NULL) { char* cmd = data; fprintf(stderr, "%s cannot be executed: %s\n", cmd, err->message); @@ -407,7 +407,7 @@ static void launch_done(GObject* obj, GAsyncResult* result, gpointer data) { char* cmd = data; fprintf(stderr, "%s cannot be executed\n", cmd); } - exit(1); + wofi_exit(1); } static void set_dri_prime(GDesktopAppInfo* info) { @@ -449,17 +449,17 @@ void wofi_drun_exec(const gchar* cmd) { char* cmd = get_cmd(G_APP_INFO(info)); printf("%s\n", cmd); free(cmd); - exit(0); + wofi_exit(0); } else if(print_desktop_file) { printf("%s\n", cmd); - exit(0); + wofi_exit(0); } else { set_dri_prime(info); if(uses_dbus(info)) { g_app_info_launch_uris_async(G_APP_INFO(info), NULL, NULL, NULL, launch_done, (gchar*) cmd); } else { g_app_info_launch_uris(G_APP_INFO(info), NULL, NULL, NULL); - exit(0); + wofi_exit(0); } } } else if(strrchr(cmd, ' ') != NULL) { @@ -475,15 +475,15 @@ void wofi_drun_exec(const gchar* cmd) { fprintf(stderr, "Printing the command line for an action is not supported\n"); } else if(print_desktop_file) { printf("%s %s\n", cmd, action); - exit(0); + wofi_exit(0); } else { set_dri_prime(info); g_desktop_app_info_launch_action(info, action, NULL); } - exit(0); + wofi_exit(0); } else { fprintf(stderr, "%s cannot be executed\n", cmd); - exit(1); + wofi_exit(1); } } diff --git a/modes/run.c b/modes/run.c index 804a07e..b505dec 100644 --- a/modes/run.c +++ b/modes/run.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019-2020 Scoopta + * Copyright (C) 2019-2024 Scoopta * This file is part of Wofi * Wofi is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -192,7 +192,7 @@ void wofi_run_exec(const char* cmd) { } if(print_command) { printf("%s\n", cmd); - exit(0); + wofi_exit(0); } if(arg_run) { size_t space_count = 2; @@ -215,7 +215,7 @@ void wofi_run_exec(const char* cmd) { execl(cmd, cmd, NULL); } fprintf(stderr, "%s cannot be executed %s\n", cmd, strerror(errno)); - exit(errno); + wofi_exit(errno); } const char** wofi_run_get_arg_names(void) { diff --git a/src/wofi.c b/src/wofi.c index 61d1498..82755c0 100644 --- a/src/wofi.c +++ b/src/wofi.c @@ -418,14 +418,14 @@ static GtkWidget* create_label(char* mode, char* text, char* search_text, char* // first, prepare cmd_labeltext to be each entry's actual comamand to run, aka replacing 'cat %s' to be 'cat filename' if(asprintf(&cmd_labeltext, pre_display_cmd, nodetext) == -1) { fprintf(stderr, "error parsing pre_display_cmd to run\n"); - exit(EXIT_FAILURE); + wofi_exit(EXIT_FAILURE); } // then, run the command if(pre_display_exec) { int fds[2]; if(pipe(fds) == -1) { perror("pipe broken"); - exit(1); + wofi_exit(1); } if(fork() == 0) { close(fds[0]); @@ -477,7 +477,7 @@ static GtkWidget* create_label(char* mode, char* text, char* search_text, char* } if(fp_labeltext == NULL) { fprintf(stderr, "error executing '%s'\n", cmd_labeltext); - exit(EXIT_FAILURE); + wofi_exit(EXIT_FAILURE); } else if(fgets(line, sizeof(line), fp_labeltext) != NULL) { // lastly, read the output of said command, and put it into the text variable to be used for the label widgets // consider using 'printf %.10s as your --pre-display-cmd to limit a string to a determined width. 10 here is an example @@ -993,7 +993,7 @@ void wofi_term_run(const char* cmd) { execlp(terminals[count], terminals[count], "-e", cmd, NULL); } fprintf(stderr, "No terminal emulator found please set term in config or use --term\n"); - exit(1); + wofi_exit(1); } static void flag_box(GtkBox* box, GtkStateFlags flags) { @@ -1236,7 +1236,7 @@ static void move_pgdn(void) { } static void do_exit(void) { - exit(1); + wofi_exit(1); } static void do_expand(void) { @@ -1277,7 +1277,7 @@ static void do_copy(void) { int fds[2]; if (pipe(fds) == -1) { perror("pipe broken"); - exit(EXIT_FAILURE); + wofi_exit(EXIT_FAILURE); } if(fork() == 0) { close(fds[1]); @@ -1299,13 +1299,21 @@ static void do_copy(void) { } } -static void on_exit_set_custom_key_return_code(int status, void* data) { - _UNUSED(data); - if (status == EXIT_SUCCESS) { - fflush(stdout); - fflush(stderr); +static void on_exit_set_custom_key_return_code(void) { + fflush(stdout); + fflush(stderr); + _exit(custom_key_return_code); +} + +void wofi_exit(int status) { + fflush(stdout); + fflush(stderr); + + if(status == EXIT_SUCCESS) { _exit(custom_key_return_code); } + + _exit(status); } static void do_custom_key(int custom_key_num) { @@ -1609,7 +1617,7 @@ static struct mode* add_mode(char* _mode) { if(init == NULL) { fprintf(stderr, "I would love to show %s but Idk what it is\n", _mode); - exit(1); + wofi_exit(1); } } } @@ -1748,7 +1756,7 @@ void wofi_init(struct map* _config) { if(width > UINT16_MAX || height > UINT16_MAX) { fprintf(stderr, "Do you actually have a monitor big enough to see this O_o? Dimensions can be no larger than %ux%u\n", UINT16_MAX, UINT16_MAX); - exit(1); + wofi_exit(1); } x = map_get(config, "x"); @@ -1904,7 +1912,7 @@ void wofi_init(struct map* _config) { if(wl == NULL) { fprintf(stderr, "Failed to connect to wayland compositor\n"); - exit(1); + wofi_exit(1); } struct wl_registry* registry = wl_display_get_registry(wl); @@ -2064,5 +2072,5 @@ void wofi_init(struct map* _config) { gtk_window_set_title(GTK_WINDOW(window), prompt); gtk_widget_show_all(window); - on_exit(on_exit_set_custom_key_return_code, NULL); + atexit(on_exit_set_custom_key_return_code); }