Krolyxon
Commit d3a70a2

Branches

Refs →

nsxivd3a70a2

Revised error handling

- Functions warn() and die() replaced by GNU-like error(3) function
- Register cleanup() with atexit(3)
- Functions called by cleanup() are marked with CLEANUP and are not allowed to
  call exit(3)
Author
Bert Münnich
Date
2015-10-28 23:03 +0100
Parent
851e428
Commit
d3a70a285d03224fde9e6ef36eba9de21b773f39

+108 −138

12 files changed

  1. M commands.c +0 −2
  2. M image.c +6 −5
  3. M image.h +1 −1
  4. M main.c +44 −57
  5. M options.c +13 −20
  6. M thumbs.c +8 −7
  7. M thumbs.h +1 −1
  8. M types.h +2 −0
  9. M util.c +21 −34
  10. M util.h +3 −2
  11. M window.c +8 −8
  12. M window.h +1 −1
M commands.c View
@@ -30,7 +30,6 @@
3030 #define _IMAGE_CONFIG
3131 #include "config.h"
3232
33−void cleanup(void);
3433 void remove_file(int, bool);
3534 void load_image(int);
3635 void open_info(void);
@@ -64,7 +63,6 @@ bool cg_quit(arg_t _)
6463 printf("%s\n", files[i].name);
6564 }
6665 }
67− cleanup();
6866 exit(EXIT_SUCCESS);
6967 }
7068
M image.c View
@@ -16,6 +16,7 @@
1616 * along with sxiv. If not, see <http://www.gnu.org/licenses/>.
1717 */
1818
19+#include <errno.h>
1920 #include <stdlib.h>
2021 #include <string.h>
2122 #include <sys/types.h>
@@ -149,7 +150,7 @@ bool img_load_gif(img_t *img, const fileinfo_t *file)
149150 gif = DGifOpenFileName(file->path);
150151 #endif
151152 if (gif == NULL) {
152− warn("could not open gif file: %s", file->name);
153+ error(0, 0, "%s: Error opening gif image", file->name);
153154 return false;
154155 }
155156 bg = gif->SBackGroundColor;
@@ -274,7 +275,7 @@ bool img_load_gif(img_t *img, const fileinfo_t *file)
274275 #endif
275276
276277 if (err && (file->flags & FF_WARN))
277− warn("corrupted gif file: %s", file->name);
278+ error(0, 0, "%s: Corrupted gif file", file->name);
278279
279280 if (img->multi.cnt > 1) {
280281 imlib_context_set_image(img->im);
@@ -300,7 +301,7 @@ bool img_load(img_t *img, const fileinfo_t *file)
300301 (img->im = imlib_load_image(file->path)) == NULL)
301302 {
302303 if (file->flags & FF_WARN)
303− warn("could not open image: %s", file->name);
304+ error(0, 0, "%s: Error opening image", file->name);
304305 return false;
305306 }
306307
@@ -325,7 +326,7 @@ bool img_load(img_t *img, const fileinfo_t *file)
325326 return true;
326327 }
327328
328−void img_close(img_t *img, bool decache)
329+CLEANUP void img_close(img_t *img, bool decache)
329330 {
330331 int i;
331332
@@ -464,7 +465,7 @@ void img_render(img_t *img)
464465
465466 if (imlib_image_has_alpha()) {
466467 if ((bg = imlib_create_image(dw, dh)) == NULL)
467− die("could not allocate memory");
468+ error(EXIT_FAILURE, ENOMEM, NULL);
468469 imlib_context_set_image(bg);
469470 imlib_image_set_has_alpha(0);
470471
M image.h View
@@ -69,7 +69,7 @@ typedef struct {
6969 void img_init(img_t*, win_t*);
7070
7171 bool img_load(img_t*, const fileinfo_t*);
72−void img_close(img_t*, bool);
72+CLEANUP void img_close(img_t*, bool);
7373
7474 void img_render(img_t*);
7575
M main.c View
@@ -42,11 +42,6 @@
4242 #define _MAPPINGS_CONFIG
4343 #include "config.h"
4444
45−typedef struct {
46− const char *name;
47− char *cmd;
48−} exec_t;
49−
5045 typedef struct {
5146 struct timeval when;
5247 bool active;
@@ -75,15 +70,20 @@ bool extprefix;
7570
7671 bool resized = false;
7772
73+typedef struct {
74+ int err;
75+ char *cmd;
76+} extcmd_t;
77+
7878 struct {
79− char *cmd;
79+ extcmd_t f;
8080 int fd;
8181 unsigned int i, lastsep;
8282 bool open;
8383 } info;
8484
8585 struct {
86− char *cmd;
86+ extcmd_t f;
8787 bool warned;
8888 } keyhandler;
8989
@@ -97,26 +97,24 @@ timeout_t timeouts[] = {
9797
9898 void cleanup(void)
9999 {
100− static bool in = false;
101−
102− if (!in) {
103− in = true;
104− img_close(&img, false);
105− tns_free(&tns);
106− win_close(&win);
107− }
100+ img_close(&img, false);
101+ tns_free(&tns);
102+ win_close(&win);
108103 }
109104
110105 void check_add_file(char *filename, bool given)
111106 {
107+ char *path;
112108 const char *bn;
113109
114110 if (*filename == '\0')
115111 return;
116112
117− if (access(filename, R_OK) < 0) {
113+ if (access(filename, R_OK) < 0 ||
114+ (path = realpath(filename, NULL)) == NULL)
115+ {
118116 if (given)
119− warn("could not open file: %s", filename);
117+ error(0, errno, "%s", filename);
120118 return;
121119 }
122120
@@ -126,12 +124,8 @@ void check_add_file(char *filename, bool given)
126124 memset(&files[filecnt/2], 0, filecnt/2 * sizeof(*files));
127125 }
128126
129− if ((files[fileidx].path = realpath(filename, NULL)) == NULL) {
130− warn("could not get real path of file: %s\n", filename);
131− return;
132− }
133−
134127 files[fileidx].name = estrdup(filename);
128+ files[fileidx].path = path;
135129 if ((bn = strrchr(files[fileidx].name , '/')) != NULL && bn[1] != '\0')
136130 files[fileidx].base = ++bn;
137131 else
@@ -149,7 +143,6 @@ void remove_file(int n, bool manual)
149143 if (filecnt == 1) {
150144 if (!manual)
151145 fprintf(stderr, "sxiv: no more files to display, aborting\n");
152− cleanup();
153146 exit(manual ? EXIT_SUCCESS : EXIT_FAILURE);
154147 }
155148 if (files[n].flags & FF_MARK)
@@ -232,7 +225,7 @@ void open_info(void)
232225 static pid_t pid;
233226 int pfd[2];
234227
235− if (info.cmd == NULL || info.open || win.bar.h == 0)
228+ if (info.f.err != 0 || info.open || win.bar.h == 0)
236229 return;
237230 if (info.fd != -1) {
238231 close(info.fd);
@@ -246,9 +239,8 @@ void open_info(void)
246239 if ((pid = fork()) == 0) {
247240 close(pfd[0]);
248241 dup2(pfd[1], 1);
249− execl(info.cmd, info.cmd, files[fileidx].name, NULL);
250− warn("could not exec: %s", info.cmd);
251− exit(EXIT_FAILURE);
242+ execl(info.f.cmd, info.f.cmd, files[fileidx].name, NULL);
243+ error(EXIT_FAILURE, errno, "exec: %s", info.f.cmd);
252244 }
253245 close(pfd[1]);
254246 if (pid < 0) {
@@ -386,7 +378,7 @@ void update_info(void)
386378 bar_put(r, "%0*d/%d | ", fn, img.multi.sel + 1, img.multi.cnt);
387379 }
388380 bar_put(r, "%0*d/%d", fw, fileidx + 1, filecnt);
389− ow_info = info.cmd == NULL;
381+ ow_info = info.f.err != 0;
390382 }
391383 if (ow_info) {
392384 fn = strlen(files[fileidx].name);
@@ -469,14 +461,14 @@ void run_key_handler(const char *key, unsigned int mask)
469461 FILE *pfs;
470462 bool marked = mode == MODE_THUMB && markcnt > 0;
471463 bool changed = false;
472− int f, i, pfd[2], retval, status;
464+ int f, i, pfd[2], status;
473465 int fcnt = marked ? markcnt : 1;
474466 char kstr[32];
475467 struct stat *oldst, st;
476468
477− if (keyhandler.cmd == NULL) {
469+ if (keyhandler.f.err != 0) {
478470 if (!keyhandler.warned) {
479− warn("key handler not installed");
471+ error(0, keyhandler.f.err, "%s", keyhandler.f.cmd);
480472 keyhandler.warned = true;
481473 }
482474 return;
@@ -485,12 +477,12 @@ void run_key_handler(const char *key, unsigned int mask)
485477 return;
486478
487479 if (pipe(pfd) < 0) {
488− warn("could not create pipe for key handler");
480+ error(0, errno, "pipe");
489481 return;
490482 }
491483 if ((pfs = fdopen(pfd[1], "w")) == NULL) {
484+ error(0, errno, "open pipe");
492485 close(pfd[0]), close(pfd[1]);
493− warn("could not open pipe for key handler");
494486 return;
495487 }
496488 oldst = emalloc(fcnt * sizeof(*oldst));
@@ -507,14 +499,13 @@ void run_key_handler(const char *key, unsigned int mask)
507499 if ((pid = fork()) == 0) {
508500 close(pfd[1]);
509501 dup2(pfd[0], 0);
510− execl(keyhandler.cmd, keyhandler.cmd, kstr, NULL);
511− warn("could not exec key handler");
512− exit(EXIT_FAILURE);
502+ execl(keyhandler.f.cmd, keyhandler.f.cmd, kstr, NULL);
503+ error(EXIT_FAILURE, errno, "exec: %s", keyhandler.f.cmd);
513504 }
514505 close(pfd[0]);
515506 if (pid < 0) {
507+ error(0, errno, "fork");
516508 fclose(pfs);
517− warn("could not fork key handler");
518509 goto end;
519510 }
520511
@@ -527,9 +518,8 @@ void run_key_handler(const char *key, unsigned int mask)
527518 }
528519 fclose(pfs);
529520 waitpid(pid, &status, 0);
530− retval = WEXITSTATUS(status);
531− if (WIFEXITED(status) == 0 || retval != 0)
532− warn("key handler exited with non-zero return value: %d", retval);
521+ if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
522+ error(0, 0, "%s: Exited abnormally", keyhandler.f.cmd);
533523
534524 for (f = i = 0; f < fcnt; i++) {
535525 if ((marked && (files[i].flags & FF_MARK)) || (!marked && i == fileidx)) {
@@ -550,7 +540,7 @@ end:
550540 if (changed) {
551541 img_close(&img, true);
552542 load_image(fileidx);
553− } else if (info.cmd != NULL) {
543+ } else if (info.f.err == 0) {
554544 info.open = false;
555545 open_info();
556546 }
@@ -819,18 +809,18 @@ int main(int argc, char **argv)
819809 filename = options->filenames[i];
820810
821811 if (stat(filename, &fstats) < 0) {
822− warn("could not stat file: %s", filename);
812+ error(0, errno, "%s", filename);
823813 continue;
824814 }
825815 if (!S_ISDIR(fstats.st_mode)) {
826816 check_add_file(filename, true);
827817 } else {
828818 if (!options->recursive) {
829− warn("ignoring directory: %s", filename);
819+ error(0, 0, "%s: Is a directory", filename);
830820 continue;
831821 }
832822 if (r_opendir(&dir, filename) < 0) {
833− warn("could not open directory: %s", filename);
823+ error(0, errno, "%s", filename);
834824 continue;
835825 }
836826 start = fileidx;
@@ -844,10 +834,8 @@ int main(int argc, char **argv)
844834 }
845835 }
846836
847− if (fileidx == 0) {
848− fprintf(stderr, "sxiv: no valid image file given, aborting\n");
849− exit(EXIT_FAILURE);
850− }
837+ if (fileidx == 0)
838+ error(EXIT_FAILURE, 0, "No valid image file given, aborting");
851839
852840 filecnt = fileidx;
853841 fileidx = options->startnum < filecnt ? options->startnum : 0;
@@ -860,20 +848,18 @@ int main(int argc, char **argv)
860848 dsuffix = "/.config";
861849 }
862850 if (homedir != NULL) {
863− char **cmd[] = { &info.cmd, &keyhandler.cmd };
851+ extcmd_t *cmd[] = { &info.f, &keyhandler.f };
864852 const char *name[] = { "image-info", "key-handler" };
865853
866854 for (i = 0; i < ARRLEN(cmd); i++) {
867855 n = strlen(homedir) + strlen(dsuffix) + strlen(name[i]) + 12;
868− *cmd[i] = (char*) emalloc(n);
869− snprintf(*cmd[i], n, "%s%s/sxiv/exec/%s", homedir, dsuffix, name[i]);
870− if (access(*cmd[i], X_OK) != 0) {
871− free(*cmd[i]);
872− *cmd[i] = NULL;
873− }
856+ cmd[i]->cmd = (char*) emalloc(n);
857+ snprintf(cmd[i]->cmd, n, "%s%s/sxiv/exec/%s", homedir, dsuffix, name[i]);
858+ if (access(cmd[i]->cmd, X_OK) != 0)
859+ cmd[i]->err = errno;
874860 }
875861 } else {
876− warn("could not locate exec directory");
862+ error(0, 0, "Exec directory not found");
877863 }
878864 info.fd = -1;
879865
@@ -890,10 +876,11 @@ int main(int argc, char **argv)
890876 win_open(&win);
891877 win_set_cursor(&win, CURSOR_WATCH);
892878
879+ atexit(cleanup);
880+
893881 set_timeout(redraw, 25, false);
894882
895883 run();
896− cleanup();
897884
898885 return 0;
899886 }
M options.c View
@@ -47,6 +47,9 @@ void parse_options(int argc, char **argv)
4747 char *end, *s;
4848 const char *scalemodes = "dfwh";
4949
50+ progname = strrchr(argv[0], '/');
51+ progname = progname ? progname + 1 : argv[0];
52+
5053 _options.from_stdin = false;
5154 _options.to_stdout = false;
5255 _options.recursive = false;
@@ -86,10 +89,8 @@ void parse_options(int argc, char **argv)
8689 break;
8790 case 'G':
8891 n = strtol(optarg, &end, 0);
89− if (*end != '\0') {
90− fprintf(stderr, "sxiv: invalid argument for option -G: %s\n", optarg);
91− exit(EXIT_FAILURE);
92− }
92+ if (*end != '\0')
93+ error(EXIT_FAILURE, 0, "Invalid argument for option -G: %s", optarg);
9394 _options.gamma = n;
9495 break;
9596 case 'g':
@@ -103,10 +104,8 @@ void parse_options(int argc, char **argv)
103104 break;
104105 case 'n':
105106 n = strtol(optarg, &end, 0);
106− if (*end != '\0' || n <= 0) {
107− fprintf(stderr, "sxiv: invalid argument for option -n: %s\n", optarg);
108− exit(EXIT_FAILURE);
109− }
107+ if (*end != '\0' || n <= 0)
108+ error(EXIT_FAILURE, 0, "Invalid argument for option -n: %s", optarg);
110109 _options.startnum = n - 1;
111110 break;
112111 case 'N':
@@ -123,18 +122,14 @@ void parse_options(int argc, char **argv)
123122 break;
124123 case 'S':
125124 n = strtol(optarg, &end, 0);
126− if (*end != '\0' || n <= 0) {
127− fprintf(stderr, "sxiv: invalid argument for option -S: %s\n", optarg);
128− exit(EXIT_FAILURE);
129− }
125+ if (*end != '\0' || n <= 0)
126+ error(EXIT_FAILURE, 0, "Invalid argument for option -S: %s", optarg);
130127 _options.slideshow = n;
131128 break;
132129 case 's':
133130 s = strchr(scalemodes, optarg[0]);
134− if (s == NULL || *s == '\0' || strlen(optarg) != 1) {
135− fprintf(stderr, "sxiv: invalid argument for option -s: %s\n", optarg);
136− exit(EXIT_FAILURE);
137− }
131+ if (s == NULL || *s == '\0' || strlen(optarg) != 1)
132+ error(EXIT_FAILURE, 0, "Invalid argument for option -s: %s", optarg);
138133 _options.scalemode = s - scalemodes;
139134 break;
140135 case 't':
@@ -149,10 +144,8 @@ void parse_options(int argc, char **argv)
149144 break;
150145 case 'z':
151146 n = strtol(optarg, &end, 0);
152− if (*end != '\0' || n <= 0) {
153− fprintf(stderr, "sxiv: invalid argument for option -z: %s\n", optarg);
154− exit(EXIT_FAILURE);
155− }
147+ if (*end != '\0' || n <= 0)
148+ error(EXIT_FAILURE, 0, "Invalid argument for option -z: %s", optarg);
156149 _options.scalemode = SCALE_ZOOM;
157150 _options.zoom = (float) n / 100.0;
158151 break;
M thumbs.c View
@@ -16,6 +16,7 @@
1616 * along with sxiv. If not, see <http://www.gnu.org/licenses/>.
1717 */
1818
19+#include <errno.h>
1920 #include <stdio.h>
2021 #include <stdlib.h>
2122 #include <string.h>
@@ -122,7 +123,7 @@ void tns_clean_cache(tns_t *tns)
122123 r_dir_t dir;
123124
124125 if (r_opendir(&dir, cache_dir) < 0) {
125− warn("could not open thumbnail cache directory: %s", cache_dir);
126+ error(0, errno, "%s", cache_dir);
126127 return;
127128 }
128129
@@ -140,7 +141,7 @@ void tns_clean_cache(tns_t *tns)
140141 }
141142 if (delete) {
142143 if (unlink(cfile) < 0)
143− warn("could not delete cache file: %s", cfile);
144+ error(0, errno, "%s", cfile);
144145 }
145146 free(cfile);
146147 }
@@ -181,11 +182,11 @@ void tns_init(tns_t *tns, fileinfo_t *files, const int *cnt, int *sel,
181182 cache_dir = (char*) emalloc(len);
182183 snprintf(cache_dir, len, "%s%s/sxiv", homedir, dsuffix);
183184 } else {
184− warn("could not locate thumbnail cache directory");
185+ error(0, 0, "Cache directory not found");
185186 }
186187 }
187188
188−void tns_free(tns_t *tns)
189+CLEANUP void tns_free(tns_t *tns)
189190 {
190191 int i;
191192
@@ -222,7 +223,7 @@ Imlib_Image tns_scale_down(Imlib_Image im, int dim)
222223 im = imlib_create_cropped_scaled_image(0, 0, w, h,
223224 MAX(z * w, 1), MAX(z * h, 1));
224225 if (im == NULL)
225− die("could not allocate memory");
226+ error(EXIT_FAILURE, ENOMEM, NULL);
226227 imlib_free_image_and_decache();
227228 }
228229 return im;
@@ -316,7 +317,7 @@ bool tns_load(tns_t *tns, int n, bool force, bool cache_only)
316317 }
317318 if (w >= maxwh || h >= maxwh) {
318319 if ((im = imlib_create_cropped_image(x, y, w, h)) == NULL)
319− die("could not allocate memory");
320+ error(EXIT_FAILURE, ENOMEM, NULL);
320321 }
321322 imlib_free_image_and_decache();
322323 }
@@ -332,7 +333,7 @@ bool tns_load(tns_t *tns, int n, bool force, bool cache_only)
332333 (im = imlib_load_image(file->path)) == NULL))
333334 {
334335 if (file->flags & FF_WARN)
335− warn("could not open image: %s", file->name);
336+ error(0, 0, "%s: Error opening image", file->name);
336337 return false;
337338 }
338339 imlib_context_set_image(im);
M thumbs.h View
@@ -58,7 +58,7 @@ typedef struct {
5858 void tns_clean_cache(tns_t*);
5959
6060 void tns_init(tns_t*, fileinfo_t*, const int*, int*, win_t*);
61−void tns_free(tns_t*);
61+CLEANUP void tns_free(tns_t*);
6262
6363 bool tns_load(tns_t*, int, bool, bool);
6464 void tns_unload(tns_t*, int);
M types.h View
@@ -21,6 +21,8 @@
2121
2222 #include <stdbool.h>
2323
24+#define CLEANUP
25+
2426 typedef enum {
2527 BO_BIG_ENDIAN,
2628 BO_LITTLE_ENDIAN
M util.c View
@@ -26,7 +26,7 @@
2626 #include "options.h"
2727 #include "util.h"
2828
29−void cleanup(void);
29+const char *progname;
3030
3131 void* emalloc(size_t size)
3232 {
@@ -34,7 +34,7 @@ void* emalloc(size_t size)
3434
3535 ptr = malloc(size);
3636 if (ptr == NULL)
37− die("could not allocate memory");
37+ error(EXIT_FAILURE, errno, NULL);
3838 return ptr;
3939 }
4040
@@ -42,7 +42,7 @@ void* erealloc(void *ptr, size_t size)
4242 {
4343 ptr = realloc(ptr, size);
4444 if (ptr == NULL)
45− die("could not allocate memory");
45+ error(EXIT_FAILURE, errno, NULL);
4646 return ptr;
4747 }
4848
@@ -53,40 +53,27 @@ char* estrdup(const char *s)
5353
5454 d = malloc(n);
5555 if (d == NULL)
56− die("could not allocate memory");
56+ error(EXIT_FAILURE, errno, NULL);
5757 memcpy(d, s, n);
5858 return d;
5959 }
6060
61−void warn(const char* fmt, ...)
61+void error(int eval, int err, const char* fmt, ...)
6262 {
63− va_list args;
64−
65− if (fmt == NULL || options->quiet)
66− return;
67−
68− va_start(args, fmt);
69− fprintf(stderr, "sxiv: warning: ");
70− vfprintf(stderr, fmt, args);
71− fprintf(stderr, "\n");
72− va_end(args);
73−}
74−
75−void die(const char* fmt, ...)
76−{
77− va_list args;
78−
79− if (fmt == NULL)
80− return;
81−
82− va_start(args, fmt);
83− fprintf(stderr, "sxiv: error: ");
84− vfprintf(stderr, fmt, args);
85− fprintf(stderr, "\n");
86− va_end(args);
87−
88− cleanup();
89− exit(EXIT_FAILURE);
63+ va_list ap;
64+
65+ fflush(stdout);
66+ fprintf(stderr, "%s: ", progname);
67+ va_start(ap, fmt);
68+ if (fmt != NULL)
69+ vfprintf(stderr, fmt, ap);
70+ va_end(ap);
71+ if (err != 0)
72+ fprintf(stderr, "%s%s", fmt != NULL ? ": " : "", strerror(err));
73+ fputc('\n', stderr);
74+
75+ if (eval != 0)
76+ exit(eval);
9077 }
9178
9279 void size_readable(float *size, const char **unit)
@@ -185,7 +172,7 @@ char* r_readdir(r_dir_t *rdir)
185172 rdir->name = rdir->stack[--rdir->stlen];
186173 rdir->d = 1;
187174 if ((rdir->dir = opendir(rdir->name)) == NULL)
188− warn("could not open directory: %s", rdir->name);
175+ error(0, errno, "%s", rdir->name);
189176 continue;
190177 }
191178 /* no more entries */
@@ -215,7 +202,7 @@ int r_mkdir(const char *path)
215202 *d = '\0';
216203 if (access(dir, F_OK) < 0 && errno == ENOENT) {
217204 if (mkdir(dir, 0755) < 0) {
218− warn("could not create directory: %s", dir);
205+ error(0, errno, "%s", dir);
219206 err = -1;
220207 }
221208 } else if (stat(dir, &stats) < 0 || !S_ISDIR(stats.st_mode)) {
M util.h View
@@ -61,12 +61,13 @@ typedef struct {
6161 int stlen;
6262 } r_dir_t;
6363
64+extern const char *progname;
65+
6466 void* emalloc(size_t);
6567 void* erealloc(void*, size_t);
6668 char* estrdup(const char*);
6769
68−void warn(const char*, ...);
69−void die(const char*, ...);
70+void error(int, int, const char*, ...);
7071
7172 void size_readable(float*, const char**);
7273
M window.c View
@@ -80,7 +80,7 @@ void win_init_font(Display *dpy, const char *fontstr)
8080 if ((font.xfont = XLoadQueryFont(dpy, fontstr)) == NULL &&
8181 (font.xfont = XLoadQueryFont(dpy, "fixed")) == NULL)
8282 {
83− die("could not load font: %s", fontstr);
83+ error(EXIT_FAILURE, 0, "Error loading font '%s'", fontstr);
8484 }
8585 font.ascent = font.xfont->ascent;
8686 font.descent = font.xfont->descent;
@@ -97,7 +97,7 @@ unsigned long win_alloc_color(win_t *win, const char *name)
9797 DefaultColormap(win->env.dpy, win->env.scr),
9898 name, &col, &col) == 0)
9999 {
100− die("could not allocate color: %s", name);
100+ error(EXIT_FAILURE, 0, "Error allocating color '%s'", name);
101101 }
102102 return col.pixel;
103103 }
@@ -143,7 +143,7 @@ void win_init(win_t *win)
143143
144144 e = &win->env;
145145 if ((e->dpy = XOpenDisplay(NULL)) == NULL)
146− die("could not open display");
146+ error(EXIT_FAILURE, 0, "Error opening X display");
147147
148148 e->scr = DefaultScreen(e->dpy);
149149 e->scrw = DisplayWidth(e->dpy, e->scr);
@@ -153,7 +153,7 @@ void win_init(win_t *win)
153153 e->depth = DefaultDepth(e->dpy, e->scr);
154154
155155 if (setlocale(LC_CTYPE, "") == NULL || XSupportsLocale() == 0)
156− warn("no locale support");
156+ error(0, 0, "No locale support");
157157
158158 win_init_font(e->dpy, BAR_FONT);
159159
@@ -236,7 +236,7 @@ void win_open(win_t *win)
236236 win->x, win->y, win->w, win->h, 0,
237237 e->depth, InputOutput, e->vis, 0, NULL);
238238 if (win->xwin == None)
239− die("could not create window");
239+ error(EXIT_FAILURE, 0, "Error creating X window");
240240
241241 XSelectInput(e->dpy, win->xwin,
242242 ButtonReleaseMask | ButtonPressMask | KeyPressMask |
@@ -249,7 +249,7 @@ void win_open(win_t *win)
249249 if (XAllocNamedColor(e->dpy, DefaultColormap(e->dpy, e->scr), "black",
250250 &col, &col) == 0)
251251 {
252− die("could not allocate color: black");
252+ error(EXIT_FAILURE, 0, "Error allocating color 'black'");
253253 }
254254 none = XCreateBitmapFromData(e->dpy, win->xwin, none_data, 8, 8);
255255 cnone = XCreatePixmapCursor(e->dpy, none, none, &col, &col, 0, 0);
@@ -306,7 +306,7 @@ void win_open(win_t *win)
306306 win_toggle_fullscreen(win);
307307 }
308308
309−void win_close(win_t *win)
309+CLEANUP void win_close(win_t *win)
310310 {
311311 XFreeCursor(win->env.dpy, carrow);
312312 XFreeCursor(win->env.dpy, cnone);
@@ -341,7 +341,7 @@ void win_toggle_fullscreen(win_t *win)
341341
342342 if (!fs_support) {
343343 if (!fs_warned) {
344− warn("window manager does not support fullscreen");
344+ error(0, 0, "No fullscreen support");
345345 fs_warned = True;
346346 }
347347 return;
M window.h View
@@ -90,7 +90,7 @@ extern Atom atoms[ATOM_COUNT];
9090
9191 void win_init(win_t*);
9292 void win_open(win_t*);
93−void win_close(win_t*);
93+CLEANUP void win_close(win_t*);
9494
9595 bool win_configure(win_t*, XConfigureEvent*);
9696