diff --git a/i3-config-wizard/cfgparse.y b/i3-config-wizard/cfgparse.y index 018b37b2..bbe11937 100644 --- a/i3-config-wizard/cfgparse.y +++ b/i3-config-wizard/cfgparse.y @@ -14,6 +14,8 @@ #include +#include "libi3.h" + extern Display *dpy; struct context { @@ -141,7 +143,7 @@ bindcode: char *str = XKeysymToString(sym); char *modifiers = modifier_to_string($3); // TODO: modifier to string - asprintf(&(context->result), "bindsym %s%s %s\n", modifiers, str, $6); + sasprintf(&(context->result), "bindsym %s%s %s\n", modifiers, str, $6); free(modifiers); } ; diff --git a/i3-input/main.c b/i3-input/main.c index fbc776e2..0d9d964e 100644 --- a/i3-input/main.c +++ b/i3-input/main.c @@ -306,7 +306,7 @@ int main(int argc, char *argv[]) { /* This option is deprecated, but will still work in i3 v4.1, 4.2 and 4.3 */ fprintf(stderr, "i3-input: WARNING: the -p option is DEPRECATED in favor of the -F (format) option\n"); FREE(format); - asprintf(&format, "%s%%s", optarg); + sasprintf(&format, "%s%%s", optarg); break; case 'l': limit = atoi(optarg); diff --git a/i3bar/Makefile b/i3bar/Makefile index adf3b859..79d0e7cd 100644 --- a/i3bar/Makefile +++ b/i3bar/Makefile @@ -14,7 +14,7 @@ i3bar: $(TOPDIR)/libi3/libi3.a ${FILES} echo "[i3bar] LINK" $(CC) $(LDFLAGS) -o $@ $(filter-out libi3/libi3.a,$^) $(LIBS) -$(TOPDIR)/libi3/%.a: +$(TOPDIR)/libi3/%.a: $(TOPDIR)/libi3/*.c $(MAKE) -C $(TOPDIR)/libi3 doc: diff --git a/i3bar/src/config.c b/i3bar/src/config.c index 9e4552ed..92ba772f 100644 --- a/i3bar/src/config.c +++ b/i3bar/src/config.c @@ -89,13 +89,13 @@ static int config_string_cb(void *params_, const unsigned char *val, unsigned in * Therefore we save the command in 'config' and access it later in * got_bar_config() */ DLOG("command = %.*s\n", len, val); - asprintf(&config.command, "%.*s", len, val); + sasprintf(&config.command, "%.*s", len, val); return 1; } if (!strcmp(cur_key, "font")) { DLOG("font = %.*s\n", len, val); - asprintf(&config.fontname, "%.*s", len, val); + sasprintf(&config.fontname, "%.*s", len, val); return 1; } @@ -103,7 +103,7 @@ static int config_string_cb(void *params_, const unsigned char *val, unsigned in DLOG("+output %.*s\n", len, val); int new_num_outputs = config.num_outputs + 1; config.outputs = srealloc(config.outputs, sizeof(char*) * new_num_outputs); - asprintf(&config.outputs[config.num_outputs], "%.*s", len, val); + sasprintf(&config.outputs[config.num_outputs], "%.*s", len, val); config.num_outputs = new_num_outputs; return 1; } @@ -111,7 +111,7 @@ static int config_string_cb(void *params_, const unsigned char *val, unsigned in if (!strcmp(cur_key, "tray_output")) { DLOG("tray_output %.*s\n", len, val); FREE(config.tray_output); - asprintf(&config.tray_output, "%.*s", len, val); + sasprintf(&config.tray_output, "%.*s", len, val); return 1; } @@ -119,7 +119,7 @@ static int config_string_cb(void *params_, const unsigned char *val, unsigned in do { \ if (!strcmp(cur_key, #json_name)) { \ DLOG(#json_name " = " #struct_name " = %.*s\n", len, val); \ - asprintf(&(config.colors.struct_name), "%.*s", len, val); \ + sasprintf(&(config.colors.struct_name), "%.*s", len, val); \ return 1; \ } \ } while (0) diff --git a/include/libi3.h b/include/libi3.h index 123e5895..9613b7f3 100644 --- a/include/libi3.h +++ b/include/libi3.h @@ -5,6 +5,7 @@ #ifndef _LIBI3_H #define _LIBI3_H +#include #include #include @@ -45,6 +46,13 @@ void *srealloc(void *ptr, size_t size); */ char *sstrdup(const char *str); +/** + * Safe-wrapper around asprintf which exits if it returns -1 (meaning that + * there is no more memory available) + * + */ +int sasprintf(char **strp, const char *fmt, ...); + /** * Formats a message (payload) of the given size and type and sends it to i3 via * the given socket file descriptor. diff --git a/libi3/safewrappers.c b/libi3/safewrappers.c index 82311fe3..2403578d 100644 --- a/libi3/safewrappers.c +++ b/libi3/safewrappers.c @@ -10,6 +10,8 @@ */ #include #include +#include +#include #include @@ -45,3 +47,14 @@ char *sstrdup(const char *str) { err(EXIT_FAILURE, "strdup()"); return result; } + +int sasprintf(char **strp, const char *fmt, ...) { + va_list args; + int result; + + va_start(args, fmt); + if ((result = vasprintf(strp, fmt, args)) == -1) + err(EXIT_FAILURE, "asprintf(%s)", fmt); + va_end(args); + return result; +} diff --git a/src/assignments.c b/src/assignments.c index 1a586807..7795d46a 100644 --- a/src/assignments.c +++ b/src/assignments.c @@ -40,7 +40,7 @@ void run_assignments(i3Window *window) { if (current->type == A_COMMAND) { DLOG("execute command %s\n", current->dest.command); char *full_command; - asprintf(&full_command, "[id=\"%d\"] %s", window->id, current->dest.command); + sasprintf(&full_command, "[id=\"%d\"] %s", window->id, current->dest.command); char *json_result = parse_cmd(full_command); FREE(full_command); FREE(json_result); diff --git a/src/cfgparse.y b/src/cfgparse.y index 8232ae57..178434d1 100644 --- a/src/cfgparse.y +++ b/src/cfgparse.y @@ -280,10 +280,8 @@ static void start_configerror_nagbar(const char *config_path) { if (configerror_pid == 0) { char *editaction, *pageraction; - if (asprintf(&editaction, "i3-sensible-terminal -e sh -c \"i3-sensible-editor \\\"%s\\\" && i3-msg reload\"", config_path) == -1) - exit(1); - if (asprintf(&pageraction, "i3-sensible-terminal -e i3-sensible-pager \"%s\"", errorfilename) == -1) - exit(1); + sasprintf(&editaction, "i3-sensible-terminal -e sh -c \"i3-sensible-editor \\\"%s\\\" && i3-msg reload\"", config_path); + sasprintf(&pageraction, "i3-sensible-terminal -e i3-sensible-pager \"%s\"", errorfilename); char *argv[] = { NULL, /* will be replaced by the executable path */ "-t", @@ -938,7 +936,7 @@ word_or_number: WORD | NUMBER { - asprintf(&$$, "%d", $1); + sasprintf(&$$, "%d", $1); } ; @@ -1345,7 +1343,7 @@ workspace: } else { char *ws_name = NULL; if ($5 == NULL) { - asprintf(&ws_name, "%d", ws_num); + sasprintf(&ws_name, "%d", ws_num); } else { ws_name = $5; } @@ -1422,20 +1420,14 @@ assign: if ((separator = strchr(criteria, '/')) != NULL) { *(separator++) = '\0'; char *pattern; - if (asprintf(&pattern, "(?i)%s", separator) == -1) { - ELOG("asprintf failed\n"); - break; - } + sasprintf(&pattern, "(?i)%s", separator); match->title = regex_new(pattern); free(pattern); printf(" title = %s\n", separator); } if (*criteria != '\0') { char *pattern; - if (asprintf(&pattern, "(?i)%s", criteria) == -1) { - ELOG("asprintf failed\n"); - break; - } + sasprintf(&pattern, "(?i)%s", criteria); match->class = regex_new(pattern); free(pattern); printf(" class = %s\n", criteria); diff --git a/src/cmdparse.y b/src/cmdparse.y index a43d2be0..17621389 100644 --- a/src/cmdparse.y +++ b/src/cmdparse.y @@ -90,8 +90,8 @@ char *parse_cmd(const char *new) { context->filename = "cmd"; if (cmdyyparse() != 0) { fprintf(stderr, "Could not parse command\n"); - asprintf(&json_output, "{\"success\":false, \"error\":\"%s at position %d\"}", - context->compact_error, context->first_column); + sasprintf(&json_output, "{\"success\":false, \"error\":\"%s at position %d\"}", + context->compact_error, context->first_column); FREE(context->line_copy); FREE(context->compact_error); free(context); @@ -433,8 +433,8 @@ focus: ELOG("You have to specify which window/container should be focused.\n"); ELOG("Example: [class=\"urxvt\" title=\"irssi\"] focus\n"); - asprintf(&json_output, "{\"success\":false, \"error\":\"You have to " - "specify which window/container should be focused\"}"); + sasprintf(&json_output, "{\"success\":false, \"error\":\"You have to " + "specify which window/container should be focused\"}"); break; } @@ -623,7 +623,7 @@ open: printf("opening new container\n"); Con *con = tree_open_con(NULL, NULL); con_focus(con); - asprintf(&json_output, "{\"success\":true, \"id\":%ld}", (long int)con); + sasprintf(&json_output, "{\"success\":true, \"id\":%ld}", (long int)con); tree_render(); } diff --git a/src/config.c b/src/config.c index a75d0aa6..8efb491e 100644 --- a/src/config.c +++ b/src/config.c @@ -196,8 +196,7 @@ static char *get_config_path(const char *override_configpath) { xdg_config_home = "~/.config"; xdg_config_home = resolve_tilde(xdg_config_home); - if (asprintf(&config_path, "%s/i3/config", xdg_config_home) == -1) - die("asprintf() failed"); + sasprintf(&config_path, "%s/i3/config", xdg_config_home); free(xdg_config_home); if (path_exists(config_path)) @@ -217,8 +216,7 @@ static char *get_config_path(const char *override_configpath) { char *tok = strtok(buf, ":"); while (tok != NULL) { tok = resolve_tilde(tok); - if (asprintf(&config_path, "%s/i3/config", tok) == -1) - die("asprintf() failed"); + sasprintf(&config_path, "%s/i3/config", tok); free(tok); if (path_exists(config_path)) { free(buf); diff --git a/src/floating.c b/src/floating.c index 0f2d9b05..83e20ee2 100644 --- a/src/floating.c +++ b/src/floating.c @@ -90,7 +90,7 @@ void floating_enable(Con *con, bool automatic) { } char *name; - asprintf(&name, "[i3 con] floatingcon around %p", con); + sasprintf(&name, "[i3 con] floatingcon around %p", con); x_set_name(nc, name); free(name); diff --git a/src/load_layout.c b/src/load_layout.c index eeb0cc75..ef787fd1 100644 --- a/src/load_layout.c +++ b/src/load_layout.c @@ -117,7 +117,7 @@ static int json_string(void *ctx, const unsigned char *val, unsigned int len) { LOG("sticky_group of this container is %s\n", json_node->sticky_group); } else if (strcasecmp(last_key, "orientation") == 0) { char *buf = NULL; - asprintf(&buf, "%.*s", (int)len, val); + sasprintf(&buf, "%.*s", (int)len, val); if (strcasecmp(buf, "none") == 0) json_node->orientation = NO_ORIENTATION; else if (strcasecmp(buf, "horizontal") == 0) @@ -128,7 +128,7 @@ static int json_string(void *ctx, const unsigned char *val, unsigned int len) { free(buf); } else if (strcasecmp(last_key, "border") == 0) { char *buf = NULL; - asprintf(&buf, "%.*s", (int)len, val); + sasprintf(&buf, "%.*s", (int)len, val); if (strcasecmp(buf, "none") == 0) json_node->border_style = BS_NONE; else if (strcasecmp(buf, "1pixel") == 0) @@ -139,7 +139,7 @@ static int json_string(void *ctx, const unsigned char *val, unsigned int len) { free(buf); } else if (strcasecmp(last_key, "layout") == 0) { char *buf = NULL; - asprintf(&buf, "%.*s", (int)len, val); + sasprintf(&buf, "%.*s", (int)len, val); if (strcasecmp(buf, "default") == 0) json_node->layout = L_DEFAULT; else if (strcasecmp(buf, "stacked") == 0) @@ -154,7 +154,7 @@ static int json_string(void *ctx, const unsigned char *val, unsigned int len) { free(buf); } else if (strcasecmp(last_key, "mark") == 0) { char *buf = NULL; - asprintf(&buf, "%.*s", (int)len, val); + sasprintf(&buf, "%.*s", (int)len, val); json_node->mark = buf; } } diff --git a/src/main.c b/src/main.c index 4f1dc78b..a9d71416 100644 --- a/src/main.c +++ b/src/main.c @@ -339,8 +339,7 @@ int main(int argc, char *argv[]) { payload = sstrdup(argv[optind]); } else { char *both; - if (asprintf(&both, "%s %s", payload, argv[optind]) == -1) - err(EXIT_FAILURE, "asprintf"); + sasprintf(&both, "%s %s", payload, argv[optind]); free(payload); payload = both; } @@ -647,8 +646,8 @@ int main(int argc, char *argv[]) { Barconfig *barconfig; TAILQ_FOREACH(barconfig, &barconfigs, configs) { char *command = NULL; - asprintf(&command, "i3bar --bar_id=%s --socket=\"%s\"", - barconfig->id, current_socketpath); + sasprintf(&command, "i3bar --bar_id=%s --socket=\"%s\"", + barconfig->id, current_socketpath); LOG("Starting bar process: %s\n", command); start_application(command); free(command); diff --git a/src/manage.c b/src/manage.c index df4dc11e..ee1b3d6c 100644 --- a/src/manage.c +++ b/src/manage.c @@ -265,7 +265,7 @@ void manage_window(xcb_window_t window, xcb_get_window_attributes_cookie_t cooki nc->border_width = geom->border_width; char *name; - asprintf(&name, "[i3 con] container around %p", cwindow); + sasprintf(&name, "[i3 con] container around %p", cwindow); x_set_name(nc, name); free(name); diff --git a/src/randr.c b/src/randr.c index 0329038b..ac61dd88 100644 --- a/src/randr.c +++ b/src/randr.c @@ -243,7 +243,7 @@ void output_init_con(Output *output) { output->con = con; char *name; - asprintf(&name, "[i3 con] output %s", con->name); + sasprintf(&name, "[i3 con] output %s", con->name); x_set_name(con, name); FREE(name); @@ -267,7 +267,7 @@ void output_init_con(Output *output) { FREE(topdock->name); topdock->name = sstrdup("topdock"); - asprintf(&name, "[i3 con] top dockarea %s", con->name); + sasprintf(&name, "[i3 con] top dockarea %s", con->name); x_set_name(topdock, name); FREE(name); DLOG("attaching\n"); @@ -281,7 +281,7 @@ void output_init_con(Output *output) { FREE(content->name); content->name = sstrdup("content"); - asprintf(&name, "[i3 con] content %s", con->name); + sasprintf(&name, "[i3 con] content %s", con->name); x_set_name(content, name); FREE(name); con_attach(content, con, false); @@ -301,7 +301,7 @@ void output_init_con(Output *output) { FREE(bottomdock->name); bottomdock->name = sstrdup("bottomdock"); - asprintf(&name, "[i3 con] bottom dockarea %s", con->name); + sasprintf(&name, "[i3 con] bottom dockarea %s", con->name); x_set_name(bottomdock, name); FREE(name); DLOG("attaching\n"); @@ -464,7 +464,7 @@ void init_ws_for_output(Output *output, Con *content) { c++; FREE(ws->name); - asprintf(&(ws->name), "%d", c); + sasprintf(&(ws->name), "%d", c); current = NULL; TAILQ_FOREACH(out, &(croot->nodes_head), nodes) @@ -477,7 +477,7 @@ void init_ws_for_output(Output *output, Con *content) { } con_attach(ws, content, false); - asprintf(&name, "[i3 con] workspace %s", ws->name); + sasprintf(&name, "[i3 con] workspace %s", ws->name); x_set_name(ws, name); free(name); @@ -562,7 +562,7 @@ static void handle_output(xcb_connection_t *conn, xcb_randr_output_t id, new->id = id; new->primary = (primary && primary->output == id); FREE(new->name); - asprintf(&new->name, "%.*s", + sasprintf(&new->name, "%.*s", xcb_randr_get_output_info_name_length(output), xcb_randr_get_output_info_name(output)); diff --git a/src/util.c b/src/util.c index 81ef083d..fa50d2e8 100644 --- a/src/util.c +++ b/src/util.c @@ -85,7 +85,7 @@ void exec_i3_utility(char *name, char *argv[]) { * argv[0]’s dirname */ char *pathbuf = strdup(start_argv[0]); char *dir = dirname(pathbuf); - asprintf(&migratepath, "%s/%s", dir, name); + sasprintf(&migratepath, "%s/%s", dir, name); argv[0] = migratepath; execvp(migratepath, argv); @@ -97,7 +97,7 @@ void exec_i3_utility(char *name, char *argv[]) { exit(1); } dir = dirname(buffer); - asprintf(&migratepath, "%s/%s", dir, name); + sasprintf(&migratepath, "%s/%s", dir, name); argv[0] = migratepath; execvp(migratepath, argv); #endif @@ -237,16 +237,10 @@ char *get_process_filename(const char *prefix) { if (dir == NULL) { struct passwd *pw = getpwuid(getuid()); const char *username = pw ? pw->pw_name : "unknown"; - if (asprintf(&dir, "/tmp/i3-%s", username) == -1) { - perror("asprintf()"); - return NULL; - } + sasprintf(&dir, "/tmp/i3-%s", username); } else { char *tmp; - if (asprintf(&tmp, "%s/i3", dir) == -1) { - perror("asprintf()"); - return NULL; - } + sasprintf(&tmp, "%s/i3", dir); dir = tmp; } if (!path_exists(dir)) { @@ -256,11 +250,7 @@ char *get_process_filename(const char *prefix) { } } char *filename; - if (asprintf(&filename, "%s/%s.%d", dir, prefix, getpid()) == -1) { - perror("asprintf()"); - filename = NULL; - } - + sasprintf(&filename, "%s/%s.%d", dir, prefix, getpid()); free(dir); return filename; } diff --git a/src/workspace.c b/src/workspace.c index cca85e83..1721ec60 100644 --- a/src/workspace.c +++ b/src/workspace.c @@ -46,7 +46,7 @@ Con *workspace_get(const char *num, bool *created) { * will handle CT_WORKSPACEs differently */ workspace = con_new(NULL, NULL); char *name; - asprintf(&name, "[i3 con] workspace %s", num); + sasprintf(&name, "[i3 con] workspace %s", num); x_set_name(workspace, name); free(name); workspace->type = CT_WORKSPACE; diff --git a/src/xinerama.c b/src/xinerama.c index 6f3a30db..c3ad97c3 100644 --- a/src/xinerama.c +++ b/src/xinerama.c @@ -56,7 +56,7 @@ static void query_screens(xcb_connection_t *conn) { s->rect.height = min(s->rect.height, screen_info[screen].height); } else { s = scalloc(sizeof(Output)); - asprintf(&(s->name), "xinerama-%d", num_screens); + sasprintf(&(s->name), "xinerama-%d", num_screens); DLOG("Created new Xinerama screen %s (%p)\n", s->name, s); s->active = true; s->rect.x = screen_info[screen].x_org;