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)
This commit is contained in:
parent
851e4288c1
commit
d3a70a285d
|
@ -30,7 +30,6 @@
|
||||||
#define _IMAGE_CONFIG
|
#define _IMAGE_CONFIG
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
void cleanup(void);
|
|
||||||
void remove_file(int, bool);
|
void remove_file(int, bool);
|
||||||
void load_image(int);
|
void load_image(int);
|
||||||
void open_info(void);
|
void open_info(void);
|
||||||
|
@ -64,7 +63,6 @@ bool cg_quit(arg_t _)
|
||||||
printf("%s\n", files[i].name);
|
printf("%s\n", files[i].name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cleanup();
|
|
||||||
exit(EXIT_SUCCESS);
|
exit(EXIT_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
11
image.c
11
image.c
|
@ -16,6 +16,7 @@
|
||||||
* along with sxiv. If not, see <http://www.gnu.org/licenses/>.
|
* along with sxiv. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
@ -149,7 +150,7 @@ bool img_load_gif(img_t *img, const fileinfo_t *file)
|
||||||
gif = DGifOpenFileName(file->path);
|
gif = DGifOpenFileName(file->path);
|
||||||
#endif
|
#endif
|
||||||
if (gif == NULL) {
|
if (gif == NULL) {
|
||||||
warn("could not open gif file: %s", file->name);
|
error(0, 0, "%s: Error opening gif image", file->name);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
bg = gif->SBackGroundColor;
|
bg = gif->SBackGroundColor;
|
||||||
|
@ -274,7 +275,7 @@ bool img_load_gif(img_t *img, const fileinfo_t *file)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (err && (file->flags & FF_WARN))
|
if (err && (file->flags & FF_WARN))
|
||||||
warn("corrupted gif file: %s", file->name);
|
error(0, 0, "%s: Corrupted gif file", file->name);
|
||||||
|
|
||||||
if (img->multi.cnt > 1) {
|
if (img->multi.cnt > 1) {
|
||||||
imlib_context_set_image(img->im);
|
imlib_context_set_image(img->im);
|
||||||
|
@ -300,7 +301,7 @@ bool img_load(img_t *img, const fileinfo_t *file)
|
||||||
(img->im = imlib_load_image(file->path)) == NULL)
|
(img->im = imlib_load_image(file->path)) == NULL)
|
||||||
{
|
{
|
||||||
if (file->flags & FF_WARN)
|
if (file->flags & FF_WARN)
|
||||||
warn("could not open image: %s", file->name);
|
error(0, 0, "%s: Error opening image", file->name);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -325,7 +326,7 @@ bool img_load(img_t *img, const fileinfo_t *file)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void img_close(img_t *img, bool decache)
|
CLEANUP void img_close(img_t *img, bool decache)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
@ -464,7 +465,7 @@ void img_render(img_t *img)
|
||||||
|
|
||||||
if (imlib_image_has_alpha()) {
|
if (imlib_image_has_alpha()) {
|
||||||
if ((bg = imlib_create_image(dw, dh)) == NULL)
|
if ((bg = imlib_create_image(dw, dh)) == NULL)
|
||||||
die("could not allocate memory");
|
error(EXIT_FAILURE, ENOMEM, NULL);
|
||||||
imlib_context_set_image(bg);
|
imlib_context_set_image(bg);
|
||||||
imlib_image_set_has_alpha(0);
|
imlib_image_set_has_alpha(0);
|
||||||
|
|
||||||
|
|
2
image.h
2
image.h
|
@ -69,7 +69,7 @@ typedef struct {
|
||||||
void img_init(img_t*, win_t*);
|
void img_init(img_t*, win_t*);
|
||||||
|
|
||||||
bool img_load(img_t*, const fileinfo_t*);
|
bool img_load(img_t*, const fileinfo_t*);
|
||||||
void img_close(img_t*, bool);
|
CLEANUP void img_close(img_t*, bool);
|
||||||
|
|
||||||
void img_render(img_t*);
|
void img_render(img_t*);
|
||||||
|
|
||||||
|
|
101
main.c
101
main.c
|
@ -42,11 +42,6 @@
|
||||||
#define _MAPPINGS_CONFIG
|
#define _MAPPINGS_CONFIG
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
const char *name;
|
|
||||||
char *cmd;
|
|
||||||
} exec_t;
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
struct timeval when;
|
struct timeval when;
|
||||||
bool active;
|
bool active;
|
||||||
|
@ -75,15 +70,20 @@ bool extprefix;
|
||||||
|
|
||||||
bool resized = false;
|
bool resized = false;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int err;
|
||||||
|
char *cmd;
|
||||||
|
} extcmd_t;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
char *cmd;
|
extcmd_t f;
|
||||||
int fd;
|
int fd;
|
||||||
unsigned int i, lastsep;
|
unsigned int i, lastsep;
|
||||||
bool open;
|
bool open;
|
||||||
} info;
|
} info;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
char *cmd;
|
extcmd_t f;
|
||||||
bool warned;
|
bool warned;
|
||||||
} keyhandler;
|
} keyhandler;
|
||||||
|
|
||||||
|
@ -97,26 +97,24 @@ timeout_t timeouts[] = {
|
||||||
|
|
||||||
void cleanup(void)
|
void cleanup(void)
|
||||||
{
|
{
|
||||||
static bool in = false;
|
img_close(&img, false);
|
||||||
|
tns_free(&tns);
|
||||||
if (!in) {
|
win_close(&win);
|
||||||
in = true;
|
|
||||||
img_close(&img, false);
|
|
||||||
tns_free(&tns);
|
|
||||||
win_close(&win);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void check_add_file(char *filename, bool given)
|
void check_add_file(char *filename, bool given)
|
||||||
{
|
{
|
||||||
|
char *path;
|
||||||
const char *bn;
|
const char *bn;
|
||||||
|
|
||||||
if (*filename == '\0')
|
if (*filename == '\0')
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (access(filename, R_OK) < 0) {
|
if (access(filename, R_OK) < 0 ||
|
||||||
|
(path = realpath(filename, NULL)) == NULL)
|
||||||
|
{
|
||||||
if (given)
|
if (given)
|
||||||
warn("could not open file: %s", filename);
|
error(0, errno, "%s", filename);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,12 +124,8 @@ void check_add_file(char *filename, bool given)
|
||||||
memset(&files[filecnt/2], 0, filecnt/2 * sizeof(*files));
|
memset(&files[filecnt/2], 0, filecnt/2 * sizeof(*files));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((files[fileidx].path = realpath(filename, NULL)) == NULL) {
|
|
||||||
warn("could not get real path of file: %s\n", filename);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
files[fileidx].name = estrdup(filename);
|
files[fileidx].name = estrdup(filename);
|
||||||
|
files[fileidx].path = path;
|
||||||
if ((bn = strrchr(files[fileidx].name , '/')) != NULL && bn[1] != '\0')
|
if ((bn = strrchr(files[fileidx].name , '/')) != NULL && bn[1] != '\0')
|
||||||
files[fileidx].base = ++bn;
|
files[fileidx].base = ++bn;
|
||||||
else
|
else
|
||||||
|
@ -149,7 +143,6 @@ void remove_file(int n, bool manual)
|
||||||
if (filecnt == 1) {
|
if (filecnt == 1) {
|
||||||
if (!manual)
|
if (!manual)
|
||||||
fprintf(stderr, "sxiv: no more files to display, aborting\n");
|
fprintf(stderr, "sxiv: no more files to display, aborting\n");
|
||||||
cleanup();
|
|
||||||
exit(manual ? EXIT_SUCCESS : EXIT_FAILURE);
|
exit(manual ? EXIT_SUCCESS : EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
if (files[n].flags & FF_MARK)
|
if (files[n].flags & FF_MARK)
|
||||||
|
@ -232,7 +225,7 @@ void open_info(void)
|
||||||
static pid_t pid;
|
static pid_t pid;
|
||||||
int pfd[2];
|
int pfd[2];
|
||||||
|
|
||||||
if (info.cmd == NULL || info.open || win.bar.h == 0)
|
if (info.f.err != 0 || info.open || win.bar.h == 0)
|
||||||
return;
|
return;
|
||||||
if (info.fd != -1) {
|
if (info.fd != -1) {
|
||||||
close(info.fd);
|
close(info.fd);
|
||||||
|
@ -246,9 +239,8 @@ void open_info(void)
|
||||||
if ((pid = fork()) == 0) {
|
if ((pid = fork()) == 0) {
|
||||||
close(pfd[0]);
|
close(pfd[0]);
|
||||||
dup2(pfd[1], 1);
|
dup2(pfd[1], 1);
|
||||||
execl(info.cmd, info.cmd, files[fileidx].name, NULL);
|
execl(info.f.cmd, info.f.cmd, files[fileidx].name, NULL);
|
||||||
warn("could not exec: %s", info.cmd);
|
error(EXIT_FAILURE, errno, "exec: %s", info.f.cmd);
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
}
|
||||||
close(pfd[1]);
|
close(pfd[1]);
|
||||||
if (pid < 0) {
|
if (pid < 0) {
|
||||||
|
@ -386,7 +378,7 @@ void update_info(void)
|
||||||
bar_put(r, "%0*d/%d | ", fn, img.multi.sel + 1, img.multi.cnt);
|
bar_put(r, "%0*d/%d | ", fn, img.multi.sel + 1, img.multi.cnt);
|
||||||
}
|
}
|
||||||
bar_put(r, "%0*d/%d", fw, fileidx + 1, filecnt);
|
bar_put(r, "%0*d/%d", fw, fileidx + 1, filecnt);
|
||||||
ow_info = info.cmd == NULL;
|
ow_info = info.f.err != 0;
|
||||||
}
|
}
|
||||||
if (ow_info) {
|
if (ow_info) {
|
||||||
fn = strlen(files[fileidx].name);
|
fn = strlen(files[fileidx].name);
|
||||||
|
@ -469,14 +461,14 @@ void run_key_handler(const char *key, unsigned int mask)
|
||||||
FILE *pfs;
|
FILE *pfs;
|
||||||
bool marked = mode == MODE_THUMB && markcnt > 0;
|
bool marked = mode == MODE_THUMB && markcnt > 0;
|
||||||
bool changed = false;
|
bool changed = false;
|
||||||
int f, i, pfd[2], retval, status;
|
int f, i, pfd[2], status;
|
||||||
int fcnt = marked ? markcnt : 1;
|
int fcnt = marked ? markcnt : 1;
|
||||||
char kstr[32];
|
char kstr[32];
|
||||||
struct stat *oldst, st;
|
struct stat *oldst, st;
|
||||||
|
|
||||||
if (keyhandler.cmd == NULL) {
|
if (keyhandler.f.err != 0) {
|
||||||
if (!keyhandler.warned) {
|
if (!keyhandler.warned) {
|
||||||
warn("key handler not installed");
|
error(0, keyhandler.f.err, "%s", keyhandler.f.cmd);
|
||||||
keyhandler.warned = true;
|
keyhandler.warned = true;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
@ -485,12 +477,12 @@ void run_key_handler(const char *key, unsigned int mask)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (pipe(pfd) < 0) {
|
if (pipe(pfd) < 0) {
|
||||||
warn("could not create pipe for key handler");
|
error(0, errno, "pipe");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if ((pfs = fdopen(pfd[1], "w")) == NULL) {
|
if ((pfs = fdopen(pfd[1], "w")) == NULL) {
|
||||||
|
error(0, errno, "open pipe");
|
||||||
close(pfd[0]), close(pfd[1]);
|
close(pfd[0]), close(pfd[1]);
|
||||||
warn("could not open pipe for key handler");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
oldst = emalloc(fcnt * sizeof(*oldst));
|
oldst = emalloc(fcnt * sizeof(*oldst));
|
||||||
|
@ -507,14 +499,13 @@ void run_key_handler(const char *key, unsigned int mask)
|
||||||
if ((pid = fork()) == 0) {
|
if ((pid = fork()) == 0) {
|
||||||
close(pfd[1]);
|
close(pfd[1]);
|
||||||
dup2(pfd[0], 0);
|
dup2(pfd[0], 0);
|
||||||
execl(keyhandler.cmd, keyhandler.cmd, kstr, NULL);
|
execl(keyhandler.f.cmd, keyhandler.f.cmd, kstr, NULL);
|
||||||
warn("could not exec key handler");
|
error(EXIT_FAILURE, errno, "exec: %s", keyhandler.f.cmd);
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
}
|
||||||
close(pfd[0]);
|
close(pfd[0]);
|
||||||
if (pid < 0) {
|
if (pid < 0) {
|
||||||
|
error(0, errno, "fork");
|
||||||
fclose(pfs);
|
fclose(pfs);
|
||||||
warn("could not fork key handler");
|
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -527,9 +518,8 @@ void run_key_handler(const char *key, unsigned int mask)
|
||||||
}
|
}
|
||||||
fclose(pfs);
|
fclose(pfs);
|
||||||
waitpid(pid, &status, 0);
|
waitpid(pid, &status, 0);
|
||||||
retval = WEXITSTATUS(status);
|
if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
|
||||||
if (WIFEXITED(status) == 0 || retval != 0)
|
error(0, 0, "%s: Exited abnormally", keyhandler.f.cmd);
|
||||||
warn("key handler exited with non-zero return value: %d", retval);
|
|
||||||
|
|
||||||
for (f = i = 0; f < fcnt; i++) {
|
for (f = i = 0; f < fcnt; i++) {
|
||||||
if ((marked && (files[i].flags & FF_MARK)) || (!marked && i == fileidx)) {
|
if ((marked && (files[i].flags & FF_MARK)) || (!marked && i == fileidx)) {
|
||||||
|
@ -550,7 +540,7 @@ end:
|
||||||
if (changed) {
|
if (changed) {
|
||||||
img_close(&img, true);
|
img_close(&img, true);
|
||||||
load_image(fileidx);
|
load_image(fileidx);
|
||||||
} else if (info.cmd != NULL) {
|
} else if (info.f.err == 0) {
|
||||||
info.open = false;
|
info.open = false;
|
||||||
open_info();
|
open_info();
|
||||||
}
|
}
|
||||||
|
@ -819,18 +809,18 @@ int main(int argc, char **argv)
|
||||||
filename = options->filenames[i];
|
filename = options->filenames[i];
|
||||||
|
|
||||||
if (stat(filename, &fstats) < 0) {
|
if (stat(filename, &fstats) < 0) {
|
||||||
warn("could not stat file: %s", filename);
|
error(0, errno, "%s", filename);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!S_ISDIR(fstats.st_mode)) {
|
if (!S_ISDIR(fstats.st_mode)) {
|
||||||
check_add_file(filename, true);
|
check_add_file(filename, true);
|
||||||
} else {
|
} else {
|
||||||
if (!options->recursive) {
|
if (!options->recursive) {
|
||||||
warn("ignoring directory: %s", filename);
|
error(0, 0, "%s: Is a directory", filename);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (r_opendir(&dir, filename) < 0) {
|
if (r_opendir(&dir, filename) < 0) {
|
||||||
warn("could not open directory: %s", filename);
|
error(0, errno, "%s", filename);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
start = fileidx;
|
start = fileidx;
|
||||||
|
@ -844,10 +834,8 @@ int main(int argc, char **argv)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fileidx == 0) {
|
if (fileidx == 0)
|
||||||
fprintf(stderr, "sxiv: no valid image file given, aborting\n");
|
error(EXIT_FAILURE, 0, "No valid image file given, aborting");
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
filecnt = fileidx;
|
filecnt = fileidx;
|
||||||
fileidx = options->startnum < filecnt ? options->startnum : 0;
|
fileidx = options->startnum < filecnt ? options->startnum : 0;
|
||||||
|
@ -860,20 +848,18 @@ int main(int argc, char **argv)
|
||||||
dsuffix = "/.config";
|
dsuffix = "/.config";
|
||||||
}
|
}
|
||||||
if (homedir != NULL) {
|
if (homedir != NULL) {
|
||||||
char **cmd[] = { &info.cmd, &keyhandler.cmd };
|
extcmd_t *cmd[] = { &info.f, &keyhandler.f };
|
||||||
const char *name[] = { "image-info", "key-handler" };
|
const char *name[] = { "image-info", "key-handler" };
|
||||||
|
|
||||||
for (i = 0; i < ARRLEN(cmd); i++) {
|
for (i = 0; i < ARRLEN(cmd); i++) {
|
||||||
n = strlen(homedir) + strlen(dsuffix) + strlen(name[i]) + 12;
|
n = strlen(homedir) + strlen(dsuffix) + strlen(name[i]) + 12;
|
||||||
*cmd[i] = (char*) emalloc(n);
|
cmd[i]->cmd = (char*) emalloc(n);
|
||||||
snprintf(*cmd[i], n, "%s%s/sxiv/exec/%s", homedir, dsuffix, name[i]);
|
snprintf(cmd[i]->cmd, n, "%s%s/sxiv/exec/%s", homedir, dsuffix, name[i]);
|
||||||
if (access(*cmd[i], X_OK) != 0) {
|
if (access(cmd[i]->cmd, X_OK) != 0)
|
||||||
free(*cmd[i]);
|
cmd[i]->err = errno;
|
||||||
*cmd[i] = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
warn("could not locate exec directory");
|
error(0, 0, "Exec directory not found");
|
||||||
}
|
}
|
||||||
info.fd = -1;
|
info.fd = -1;
|
||||||
|
|
||||||
|
@ -890,10 +876,11 @@ int main(int argc, char **argv)
|
||||||
win_open(&win);
|
win_open(&win);
|
||||||
win_set_cursor(&win, CURSOR_WATCH);
|
win_set_cursor(&win, CURSOR_WATCH);
|
||||||
|
|
||||||
|
atexit(cleanup);
|
||||||
|
|
||||||
set_timeout(redraw, 25, false);
|
set_timeout(redraw, 25, false);
|
||||||
|
|
||||||
run();
|
run();
|
||||||
cleanup();
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
33
options.c
33
options.c
|
@ -47,6 +47,9 @@ void parse_options(int argc, char **argv)
|
||||||
char *end, *s;
|
char *end, *s;
|
||||||
const char *scalemodes = "dfwh";
|
const char *scalemodes = "dfwh";
|
||||||
|
|
||||||
|
progname = strrchr(argv[0], '/');
|
||||||
|
progname = progname ? progname + 1 : argv[0];
|
||||||
|
|
||||||
_options.from_stdin = false;
|
_options.from_stdin = false;
|
||||||
_options.to_stdout = false;
|
_options.to_stdout = false;
|
||||||
_options.recursive = false;
|
_options.recursive = false;
|
||||||
|
@ -86,10 +89,8 @@ void parse_options(int argc, char **argv)
|
||||||
break;
|
break;
|
||||||
case 'G':
|
case 'G':
|
||||||
n = strtol(optarg, &end, 0);
|
n = strtol(optarg, &end, 0);
|
||||||
if (*end != '\0') {
|
if (*end != '\0')
|
||||||
fprintf(stderr, "sxiv: invalid argument for option -G: %s\n", optarg);
|
error(EXIT_FAILURE, 0, "Invalid argument for option -G: %s", optarg);
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
_options.gamma = n;
|
_options.gamma = n;
|
||||||
break;
|
break;
|
||||||
case 'g':
|
case 'g':
|
||||||
|
@ -103,10 +104,8 @@ void parse_options(int argc, char **argv)
|
||||||
break;
|
break;
|
||||||
case 'n':
|
case 'n':
|
||||||
n = strtol(optarg, &end, 0);
|
n = strtol(optarg, &end, 0);
|
||||||
if (*end != '\0' || n <= 0) {
|
if (*end != '\0' || n <= 0)
|
||||||
fprintf(stderr, "sxiv: invalid argument for option -n: %s\n", optarg);
|
error(EXIT_FAILURE, 0, "Invalid argument for option -n: %s", optarg);
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
_options.startnum = n - 1;
|
_options.startnum = n - 1;
|
||||||
break;
|
break;
|
||||||
case 'N':
|
case 'N':
|
||||||
|
@ -123,18 +122,14 @@ void parse_options(int argc, char **argv)
|
||||||
break;
|
break;
|
||||||
case 'S':
|
case 'S':
|
||||||
n = strtol(optarg, &end, 0);
|
n = strtol(optarg, &end, 0);
|
||||||
if (*end != '\0' || n <= 0) {
|
if (*end != '\0' || n <= 0)
|
||||||
fprintf(stderr, "sxiv: invalid argument for option -S: %s\n", optarg);
|
error(EXIT_FAILURE, 0, "Invalid argument for option -S: %s", optarg);
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
_options.slideshow = n;
|
_options.slideshow = n;
|
||||||
break;
|
break;
|
||||||
case 's':
|
case 's':
|
||||||
s = strchr(scalemodes, optarg[0]);
|
s = strchr(scalemodes, optarg[0]);
|
||||||
if (s == NULL || *s == '\0' || strlen(optarg) != 1) {
|
if (s == NULL || *s == '\0' || strlen(optarg) != 1)
|
||||||
fprintf(stderr, "sxiv: invalid argument for option -s: %s\n", optarg);
|
error(EXIT_FAILURE, 0, "Invalid argument for option -s: %s", optarg);
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
_options.scalemode = s - scalemodes;
|
_options.scalemode = s - scalemodes;
|
||||||
break;
|
break;
|
||||||
case 't':
|
case 't':
|
||||||
|
@ -149,10 +144,8 @@ void parse_options(int argc, char **argv)
|
||||||
break;
|
break;
|
||||||
case 'z':
|
case 'z':
|
||||||
n = strtol(optarg, &end, 0);
|
n = strtol(optarg, &end, 0);
|
||||||
if (*end != '\0' || n <= 0) {
|
if (*end != '\0' || n <= 0)
|
||||||
fprintf(stderr, "sxiv: invalid argument for option -z: %s\n", optarg);
|
error(EXIT_FAILURE, 0, "Invalid argument for option -z: %s", optarg);
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
_options.scalemode = SCALE_ZOOM;
|
_options.scalemode = SCALE_ZOOM;
|
||||||
_options.zoom = (float) n / 100.0;
|
_options.zoom = (float) n / 100.0;
|
||||||
break;
|
break;
|
||||||
|
|
15
thumbs.c
15
thumbs.c
|
@ -16,6 +16,7 @@
|
||||||
* along with sxiv. If not, see <http://www.gnu.org/licenses/>.
|
* along with sxiv. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
@ -122,7 +123,7 @@ void tns_clean_cache(tns_t *tns)
|
||||||
r_dir_t dir;
|
r_dir_t dir;
|
||||||
|
|
||||||
if (r_opendir(&dir, cache_dir) < 0) {
|
if (r_opendir(&dir, cache_dir) < 0) {
|
||||||
warn("could not open thumbnail cache directory: %s", cache_dir);
|
error(0, errno, "%s", cache_dir);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -140,7 +141,7 @@ void tns_clean_cache(tns_t *tns)
|
||||||
}
|
}
|
||||||
if (delete) {
|
if (delete) {
|
||||||
if (unlink(cfile) < 0)
|
if (unlink(cfile) < 0)
|
||||||
warn("could not delete cache file: %s", cfile);
|
error(0, errno, "%s", cfile);
|
||||||
}
|
}
|
||||||
free(cfile);
|
free(cfile);
|
||||||
}
|
}
|
||||||
|
@ -181,11 +182,11 @@ void tns_init(tns_t *tns, fileinfo_t *files, const int *cnt, int *sel,
|
||||||
cache_dir = (char*) emalloc(len);
|
cache_dir = (char*) emalloc(len);
|
||||||
snprintf(cache_dir, len, "%s%s/sxiv", homedir, dsuffix);
|
snprintf(cache_dir, len, "%s%s/sxiv", homedir, dsuffix);
|
||||||
} else {
|
} else {
|
||||||
warn("could not locate thumbnail cache directory");
|
error(0, 0, "Cache directory not found");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void tns_free(tns_t *tns)
|
CLEANUP void tns_free(tns_t *tns)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
@ -222,7 +223,7 @@ Imlib_Image tns_scale_down(Imlib_Image im, int dim)
|
||||||
im = imlib_create_cropped_scaled_image(0, 0, w, h,
|
im = imlib_create_cropped_scaled_image(0, 0, w, h,
|
||||||
MAX(z * w, 1), MAX(z * h, 1));
|
MAX(z * w, 1), MAX(z * h, 1));
|
||||||
if (im == NULL)
|
if (im == NULL)
|
||||||
die("could not allocate memory");
|
error(EXIT_FAILURE, ENOMEM, NULL);
|
||||||
imlib_free_image_and_decache();
|
imlib_free_image_and_decache();
|
||||||
}
|
}
|
||||||
return im;
|
return im;
|
||||||
|
@ -316,7 +317,7 @@ bool tns_load(tns_t *tns, int n, bool force, bool cache_only)
|
||||||
}
|
}
|
||||||
if (w >= maxwh || h >= maxwh) {
|
if (w >= maxwh || h >= maxwh) {
|
||||||
if ((im = imlib_create_cropped_image(x, y, w, h)) == NULL)
|
if ((im = imlib_create_cropped_image(x, y, w, h)) == NULL)
|
||||||
die("could not allocate memory");
|
error(EXIT_FAILURE, ENOMEM, NULL);
|
||||||
}
|
}
|
||||||
imlib_free_image_and_decache();
|
imlib_free_image_and_decache();
|
||||||
}
|
}
|
||||||
|
@ -332,7 +333,7 @@ bool tns_load(tns_t *tns, int n, bool force, bool cache_only)
|
||||||
(im = imlib_load_image(file->path)) == NULL))
|
(im = imlib_load_image(file->path)) == NULL))
|
||||||
{
|
{
|
||||||
if (file->flags & FF_WARN)
|
if (file->flags & FF_WARN)
|
||||||
warn("could not open image: %s", file->name);
|
error(0, 0, "%s: Error opening image", file->name);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
imlib_context_set_image(im);
|
imlib_context_set_image(im);
|
||||||
|
|
2
thumbs.h
2
thumbs.h
|
@ -58,7 +58,7 @@ typedef struct {
|
||||||
void tns_clean_cache(tns_t*);
|
void tns_clean_cache(tns_t*);
|
||||||
|
|
||||||
void tns_init(tns_t*, fileinfo_t*, const int*, int*, win_t*);
|
void tns_init(tns_t*, fileinfo_t*, const int*, int*, win_t*);
|
||||||
void tns_free(tns_t*);
|
CLEANUP void tns_free(tns_t*);
|
||||||
|
|
||||||
bool tns_load(tns_t*, int, bool, bool);
|
bool tns_load(tns_t*, int, bool, bool);
|
||||||
void tns_unload(tns_t*, int);
|
void tns_unload(tns_t*, int);
|
||||||
|
|
2
types.h
2
types.h
|
@ -21,6 +21,8 @@
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#define CLEANUP
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
BO_BIG_ENDIAN,
|
BO_BIG_ENDIAN,
|
||||||
BO_LITTLE_ENDIAN
|
BO_LITTLE_ENDIAN
|
||||||
|
|
51
util.c
51
util.c
|
@ -26,7 +26,7 @@
|
||||||
#include "options.h"
|
#include "options.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
void cleanup(void);
|
const char *progname;
|
||||||
|
|
||||||
void* emalloc(size_t size)
|
void* emalloc(size_t size)
|
||||||
{
|
{
|
||||||
|
@ -34,7 +34,7 @@ void* emalloc(size_t size)
|
||||||
|
|
||||||
ptr = malloc(size);
|
ptr = malloc(size);
|
||||||
if (ptr == NULL)
|
if (ptr == NULL)
|
||||||
die("could not allocate memory");
|
error(EXIT_FAILURE, errno, NULL);
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ void* erealloc(void *ptr, size_t size)
|
||||||
{
|
{
|
||||||
ptr = realloc(ptr, size);
|
ptr = realloc(ptr, size);
|
||||||
if (ptr == NULL)
|
if (ptr == NULL)
|
||||||
die("could not allocate memory");
|
error(EXIT_FAILURE, errno, NULL);
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,40 +53,27 @@ char* estrdup(const char *s)
|
||||||
|
|
||||||
d = malloc(n);
|
d = malloc(n);
|
||||||
if (d == NULL)
|
if (d == NULL)
|
||||||
die("could not allocate memory");
|
error(EXIT_FAILURE, errno, NULL);
|
||||||
memcpy(d, s, n);
|
memcpy(d, s, n);
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
void warn(const char* fmt, ...)
|
void error(int eval, int err, const char* fmt, ...)
|
||||||
{
|
{
|
||||||
va_list args;
|
va_list ap;
|
||||||
|
|
||||||
if (fmt == NULL || options->quiet)
|
fflush(stdout);
|
||||||
return;
|
fprintf(stderr, "%s: ", progname);
|
||||||
|
va_start(ap, fmt);
|
||||||
|
if (fmt != NULL)
|
||||||
|
vfprintf(stderr, fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
if (err != 0)
|
||||||
|
fprintf(stderr, "%s%s", fmt != NULL ? ": " : "", strerror(err));
|
||||||
|
fputc('\n', stderr);
|
||||||
|
|
||||||
va_start(args, fmt);
|
if (eval != 0)
|
||||||
fprintf(stderr, "sxiv: warning: ");
|
exit(eval);
|
||||||
vfprintf(stderr, fmt, args);
|
|
||||||
fprintf(stderr, "\n");
|
|
||||||
va_end(args);
|
|
||||||
}
|
|
||||||
|
|
||||||
void die(const char* fmt, ...)
|
|
||||||
{
|
|
||||||
va_list args;
|
|
||||||
|
|
||||||
if (fmt == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
va_start(args, fmt);
|
|
||||||
fprintf(stderr, "sxiv: error: ");
|
|
||||||
vfprintf(stderr, fmt, args);
|
|
||||||
fprintf(stderr, "\n");
|
|
||||||
va_end(args);
|
|
||||||
|
|
||||||
cleanup();
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void size_readable(float *size, const char **unit)
|
void size_readable(float *size, const char **unit)
|
||||||
|
@ -185,7 +172,7 @@ char* r_readdir(r_dir_t *rdir)
|
||||||
rdir->name = rdir->stack[--rdir->stlen];
|
rdir->name = rdir->stack[--rdir->stlen];
|
||||||
rdir->d = 1;
|
rdir->d = 1;
|
||||||
if ((rdir->dir = opendir(rdir->name)) == NULL)
|
if ((rdir->dir = opendir(rdir->name)) == NULL)
|
||||||
warn("could not open directory: %s", rdir->name);
|
error(0, errno, "%s", rdir->name);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
/* no more entries */
|
/* no more entries */
|
||||||
|
@ -215,7 +202,7 @@ int r_mkdir(const char *path)
|
||||||
*d = '\0';
|
*d = '\0';
|
||||||
if (access(dir, F_OK) < 0 && errno == ENOENT) {
|
if (access(dir, F_OK) < 0 && errno == ENOENT) {
|
||||||
if (mkdir(dir, 0755) < 0) {
|
if (mkdir(dir, 0755) < 0) {
|
||||||
warn("could not create directory: %s", dir);
|
error(0, errno, "%s", dir);
|
||||||
err = -1;
|
err = -1;
|
||||||
}
|
}
|
||||||
} else if (stat(dir, &stats) < 0 || !S_ISDIR(stats.st_mode)) {
|
} else if (stat(dir, &stats) < 0 || !S_ISDIR(stats.st_mode)) {
|
||||||
|
|
5
util.h
5
util.h
|
@ -61,12 +61,13 @@ typedef struct {
|
||||||
int stlen;
|
int stlen;
|
||||||
} r_dir_t;
|
} r_dir_t;
|
||||||
|
|
||||||
|
extern const char *progname;
|
||||||
|
|
||||||
void* emalloc(size_t);
|
void* emalloc(size_t);
|
||||||
void* erealloc(void*, size_t);
|
void* erealloc(void*, size_t);
|
||||||
char* estrdup(const char*);
|
char* estrdup(const char*);
|
||||||
|
|
||||||
void warn(const char*, ...);
|
void error(int, int, const char*, ...);
|
||||||
void die(const char*, ...);
|
|
||||||
|
|
||||||
void size_readable(float*, const char**);
|
void size_readable(float*, const char**);
|
||||||
|
|
||||||
|
|
16
window.c
16
window.c
|
@ -80,7 +80,7 @@ void win_init_font(Display *dpy, const char *fontstr)
|
||||||
if ((font.xfont = XLoadQueryFont(dpy, fontstr)) == NULL &&
|
if ((font.xfont = XLoadQueryFont(dpy, fontstr)) == NULL &&
|
||||||
(font.xfont = XLoadQueryFont(dpy, "fixed")) == NULL)
|
(font.xfont = XLoadQueryFont(dpy, "fixed")) == NULL)
|
||||||
{
|
{
|
||||||
die("could not load font: %s", fontstr);
|
error(EXIT_FAILURE, 0, "Error loading font '%s'", fontstr);
|
||||||
}
|
}
|
||||||
font.ascent = font.xfont->ascent;
|
font.ascent = font.xfont->ascent;
|
||||||
font.descent = font.xfont->descent;
|
font.descent = font.xfont->descent;
|
||||||
|
@ -97,7 +97,7 @@ unsigned long win_alloc_color(win_t *win, const char *name)
|
||||||
DefaultColormap(win->env.dpy, win->env.scr),
|
DefaultColormap(win->env.dpy, win->env.scr),
|
||||||
name, &col, &col) == 0)
|
name, &col, &col) == 0)
|
||||||
{
|
{
|
||||||
die("could not allocate color: %s", name);
|
error(EXIT_FAILURE, 0, "Error allocating color '%s'", name);
|
||||||
}
|
}
|
||||||
return col.pixel;
|
return col.pixel;
|
||||||
}
|
}
|
||||||
|
@ -143,7 +143,7 @@ void win_init(win_t *win)
|
||||||
|
|
||||||
e = &win->env;
|
e = &win->env;
|
||||||
if ((e->dpy = XOpenDisplay(NULL)) == NULL)
|
if ((e->dpy = XOpenDisplay(NULL)) == NULL)
|
||||||
die("could not open display");
|
error(EXIT_FAILURE, 0, "Error opening X display");
|
||||||
|
|
||||||
e->scr = DefaultScreen(e->dpy);
|
e->scr = DefaultScreen(e->dpy);
|
||||||
e->scrw = DisplayWidth(e->dpy, e->scr);
|
e->scrw = DisplayWidth(e->dpy, e->scr);
|
||||||
|
@ -153,7 +153,7 @@ void win_init(win_t *win)
|
||||||
e->depth = DefaultDepth(e->dpy, e->scr);
|
e->depth = DefaultDepth(e->dpy, e->scr);
|
||||||
|
|
||||||
if (setlocale(LC_CTYPE, "") == NULL || XSupportsLocale() == 0)
|
if (setlocale(LC_CTYPE, "") == NULL || XSupportsLocale() == 0)
|
||||||
warn("no locale support");
|
error(0, 0, "No locale support");
|
||||||
|
|
||||||
win_init_font(e->dpy, BAR_FONT);
|
win_init_font(e->dpy, BAR_FONT);
|
||||||
|
|
||||||
|
@ -236,7 +236,7 @@ void win_open(win_t *win)
|
||||||
win->x, win->y, win->w, win->h, 0,
|
win->x, win->y, win->w, win->h, 0,
|
||||||
e->depth, InputOutput, e->vis, 0, NULL);
|
e->depth, InputOutput, e->vis, 0, NULL);
|
||||||
if (win->xwin == None)
|
if (win->xwin == None)
|
||||||
die("could not create window");
|
error(EXIT_FAILURE, 0, "Error creating X window");
|
||||||
|
|
||||||
XSelectInput(e->dpy, win->xwin,
|
XSelectInput(e->dpy, win->xwin,
|
||||||
ButtonReleaseMask | ButtonPressMask | KeyPressMask |
|
ButtonReleaseMask | ButtonPressMask | KeyPressMask |
|
||||||
|
@ -249,7 +249,7 @@ void win_open(win_t *win)
|
||||||
if (XAllocNamedColor(e->dpy, DefaultColormap(e->dpy, e->scr), "black",
|
if (XAllocNamedColor(e->dpy, DefaultColormap(e->dpy, e->scr), "black",
|
||||||
&col, &col) == 0)
|
&col, &col) == 0)
|
||||||
{
|
{
|
||||||
die("could not allocate color: black");
|
error(EXIT_FAILURE, 0, "Error allocating color 'black'");
|
||||||
}
|
}
|
||||||
none = XCreateBitmapFromData(e->dpy, win->xwin, none_data, 8, 8);
|
none = XCreateBitmapFromData(e->dpy, win->xwin, none_data, 8, 8);
|
||||||
cnone = XCreatePixmapCursor(e->dpy, none, none, &col, &col, 0, 0);
|
cnone = XCreatePixmapCursor(e->dpy, none, none, &col, &col, 0, 0);
|
||||||
|
@ -306,7 +306,7 @@ void win_open(win_t *win)
|
||||||
win_toggle_fullscreen(win);
|
win_toggle_fullscreen(win);
|
||||||
}
|
}
|
||||||
|
|
||||||
void win_close(win_t *win)
|
CLEANUP void win_close(win_t *win)
|
||||||
{
|
{
|
||||||
XFreeCursor(win->env.dpy, carrow);
|
XFreeCursor(win->env.dpy, carrow);
|
||||||
XFreeCursor(win->env.dpy, cnone);
|
XFreeCursor(win->env.dpy, cnone);
|
||||||
|
@ -341,7 +341,7 @@ void win_toggle_fullscreen(win_t *win)
|
||||||
|
|
||||||
if (!fs_support) {
|
if (!fs_support) {
|
||||||
if (!fs_warned) {
|
if (!fs_warned) {
|
||||||
warn("window manager does not support fullscreen");
|
error(0, 0, "No fullscreen support");
|
||||||
fs_warned = True;
|
fs_warned = True;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|
2
window.h
2
window.h
|
@ -90,7 +90,7 @@ extern Atom atoms[ATOM_COUNT];
|
||||||
|
|
||||||
void win_init(win_t*);
|
void win_init(win_t*);
|
||||||
void win_open(win_t*);
|
void win_open(win_t*);
|
||||||
void win_close(win_t*);
|
CLEANUP void win_close(win_t*);
|
||||||
|
|
||||||
bool win_configure(win_t*, XConfigureEvent*);
|
bool win_configure(win_t*, XConfigureEvent*);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue