diff options
author | Vito Caputo <vcaputo@pengaru.com> | 2021-02-14 16:50:32 -0800 |
---|---|---|
committer | Vito Caputo <vcaputo@pengaru.com> | 2021-02-14 16:50:32 -0800 |
commit | b31ee4be7739ccd8cf36048da212410514758949 (patch) | |
tree | 5d5a7a16f27a47c2f4fdd4e015c702526c817ae6 /src/sdl_fb.c | |
parent | 4ba92170fcc18d5c194f3bc18ea96d36adf9d9ce (diff) |
*fb: improve error propagation out of setup/init
A lot of errors were being conflated as ENOMEM due to the lazy
use of NULL pointer returns for errors.
This commit reworks a handful of those return paths to instead
return an errno-style int, storing the results on success at a
supplied result pointer.
It's kind of ugly, and I make some assumptions about libdrm
setting errno on failure - it too uses this lazy API of returning
NULL pointers on failure. Hopefully errno is always set by an
underlying ioctl failing.
The SDL error API is also pretty gross, being cross-platform it
defines its own error codes so I try vaguely map these to errno
values.
I'm considering this a first approximation at fixing this up, but
there are probably bugs as I did it real fast and nasty.
It at least seems to all still work OK here in the non-error
paths I tested. So it doesn't seem more broken than before at a
glance.
Diffstat (limited to 'src/sdl_fb.c')
-rw-r--r-- | src/sdl_fb.c | 42 |
1 files changed, 33 insertions, 9 deletions
diff --git a/src/sdl_fb.c b/src/sdl_fb.c index dfb319a..8e48329 100644 --- a/src/sdl_fb.c +++ b/src/sdl_fb.c @@ -1,4 +1,5 @@ #define SDL_MAIN_HANDLED +#include <assert.h> #include <SDL.h> #include <stdlib.h> #include <errno.h> @@ -86,24 +87,43 @@ static int sdl_fb_setup(const settings_t *settings, setting_desc_t **next_settin return 0; } +static int sdl_err_to_errno(int err) +{ + switch (err) { + case SDL_ENOMEM: + return ENOMEM; + case SDL_EFREAD: + case SDL_EFWRITE: + case SDL_EFSEEK: + return EIO; + case SDL_UNSUPPORTED: + return ENOTSUP; + default: + return EINVAL; + } +} -static void * sdl_fb_init(const settings_t *settings) +static int sdl_fb_init(const settings_t *settings, void **res_context) { const char *fullscreen; const char *size; sdl_fb_t *c; + int r; + + assert(settings); + assert(res_context); fullscreen = settings_get_value(settings, "fullscreen"); if (!fullscreen) - return NULL; + return -EINVAL; size = settings_get_value(settings, "size"); if (!size && !strcasecmp(fullscreen, "off")) - return NULL; + return -EINVAL; c = calloc(1, sizeof(sdl_fb_t)); if (!c) - return NULL; + return -ENOMEM; if (!strcasecmp(fullscreen, "on")) { if (!size) @@ -116,25 +136,29 @@ static void * sdl_fb_init(const settings_t *settings) sscanf(size, "%u%*[xX]%u", &c->width, &c->height); SDL_SetMainReady(); - if (SDL_Init(SDL_INIT_VIDEO) < 0) { + r = SDL_Init(SDL_INIT_VIDEO); + if (r < 0) { free(c); - return NULL; + return -sdl_err_to_errno(r); } if (c->flags == SDL_WINDOW_FULLSCREEN_DESKTOP) { SDL_DisplayMode mode; - if (SDL_GetDesktopDisplayMode(0, &mode) != 0) { + r = SDL_GetDesktopDisplayMode(0, &mode); + if (r != 0) { SDL_Quit(); free(c); - return NULL; + return -sdl_err_to_errno(r); } c->width = mode.w; c->height = mode.h; } - return c; + *res_context = c; + + return 0; } |