summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@tavianator.com>2022-01-18 11:27:54 -0500
committerTavian Barnes <tavianator@tavianator.com>2022-01-18 12:27:29 -0500
commit03563b1407e436b2863509ebf09d412e79cbd1dd (patch)
treed2e5b735c8be3078b7b76c31c9168330a7f2557b
parentabbb00766a8d10f63bbafb60bb13eb4672d7f44a (diff)
downloadbfs-03563b1407e436b2863509ebf09d412e79cbd1dd.tar.xz
util: New close() wrappers to check for EBADF and preserve errno
-rw-r--r--bar.c15
-rw-r--r--bftw.c4
-rw-r--r--dir.c6
-rw-r--r--exec.c10
-rw-r--r--main.c7
-rw-r--r--parse.c8
-rw-r--r--spawn.c21
-rw-r--r--util.c28
-rw-r--r--util.h20
9 files changed, 66 insertions, 53 deletions
diff --git a/bar.c b/bar.c
index 31734ac..b0e595e 100644
--- a/bar.c
+++ b/bar.c
@@ -1,6 +1,6 @@
/****************************************************************************
* bfs *
- * Copyright (C) 2020 Tavian Barnes <tavianator@tavianator.com> *
+ * Copyright (C) 2020-2022 Tavian Barnes <tavianator@tavianator.com> *
* *
* Permission to use, copy, modify, and/or distribute this software for any *
* purpose with or without fee is hereby granted. *
@@ -155,28 +155,24 @@ static int bfs_bar_printf(struct bfs_bar *bar, const char *format, ...) {
}
struct bfs_bar *bfs_bar_show(void) {
- int error;
-
if (the_bar.fd >= 0) {
- error = EBUSY;
+ errno = EBUSY;
goto fail;
}
char term[L_ctermid];
ctermid(term);
if (strlen(term) == 0) {
- error = ENOTTY;
+ errno = ENOTTY;
goto fail;
}
the_bar.fd = open(term, O_RDWR | O_CLOEXEC);
if (the_bar.fd < 0) {
- error = errno;
goto fail;
}
if (bfs_bar_getsize(&the_bar) != 0) {
- error = errno;
goto fail_close;
}
@@ -207,10 +203,9 @@ struct bfs_bar *bfs_bar_show(void) {
return &the_bar;
fail_close:
- close(the_bar.fd);
+ close_quietly(the_bar.fd);
the_bar.fd = -1;
fail:
- errno = error;
return NULL;
}
@@ -248,6 +243,6 @@ void bfs_bar_hide(struct bfs_bar *bar) {
bfs_bar_reset(bar);
- close(bar->fd);
+ xclose(bar->fd);
bar->fd = -1;
}
diff --git a/bftw.c b/bftw.c
index 64b1120..5f5afff 100644
--- a/bftw.c
+++ b/bftw.c
@@ -1,6 +1,6 @@
/****************************************************************************
* bfs *
- * Copyright (C) 2015-2021 Tavian Barnes <tavianator@tavianator.com> *
+ * Copyright (C) 2015-2022 Tavian Barnes <tavianator@tavianator.com> *
* *
* Permission to use, copy, modify, and/or distribute this software for any *
* purpose with or without fee is hereby granted. *
@@ -244,7 +244,7 @@ static void bftw_file_close(struct bftw_cache *cache, struct bftw_file *file) {
bftw_cache_remove(cache, file);
- close(file->fd);
+ xclose(file->fd);
file->fd = -1;
}
diff --git a/dir.c b/dir.c
index 90c2e3e..024e767 100644
--- a/dir.c
+++ b/dir.c
@@ -138,12 +138,10 @@ struct bfs_dir *bfs_opendir(int at_fd, const char *at_path) {
#else
dir->dir = fdopendir(fd);
if (!dir->dir) {
- int error = errno;
if (at_path) {
- close(fd);
+ close_quietly(fd);
}
free(dir);
- errno = error;
return NULL;
}
@@ -280,7 +278,7 @@ int bfs_readdir(struct bfs_dir *dir, struct bfs_dirent *de) {
int bfs_closedir(struct bfs_dir *dir) {
#if __linux__
- int ret = close(dir->fd);
+ int ret = xclose(dir->fd);
#else
int ret = closedir(dir->dir);
#endif
diff --git a/exec.c b/exec.c
index 45233e1..310756b 100644
--- a/exec.c
+++ b/exec.c
@@ -1,6 +1,6 @@
/****************************************************************************
* bfs *
- * Copyright (C) 2017-2018 Tavian Barnes <tavianator@tavianator.com> *
+ * Copyright (C) 2017-2022 Tavian Barnes <tavianator@tavianator.com> *
* *
* Permission to use, copy, modify, and/or distribute this software for any *
* purpose with or without fee is hereby granted. *
@@ -308,12 +308,10 @@ static int bfs_exec_openwd(struct bfs_exec *execbuf, const struct BFTW *ftwbuf)
}
/** Close the working directory. */
-static int bfs_exec_closewd(struct bfs_exec *execbuf, const struct BFTW *ftwbuf) {
- int ret = 0;
-
+static void bfs_exec_closewd(struct bfs_exec *execbuf, const struct BFTW *ftwbuf) {
if (execbuf->wd_fd >= 0) {
if (!ftwbuf || execbuf->wd_fd != ftwbuf->at_fd) {
- ret = close(execbuf->wd_fd);
+ xclose(execbuf->wd_fd);
}
execbuf->wd_fd = -1;
}
@@ -323,8 +321,6 @@ static int bfs_exec_closewd(struct bfs_exec *execbuf, const struct BFTW *ftwbuf)
execbuf->wd_path = NULL;
execbuf->wd_len = 0;
}
-
- return ret;
}
/** Actually spawn the process. */
diff --git a/main.c b/main.c
index 7ceb0a2..ade5358 100644
--- a/main.c
+++ b/main.c
@@ -1,6 +1,6 @@
/****************************************************************************
* bfs *
- * Copyright (C) 2015-2021 Tavian Barnes <tavianator@tavianator.com> *
+ * Copyright (C) 2015-2022 Tavian Barnes <tavianator@tavianator.com> *
* *
* Permission to use, copy, modify, and/or distribute this software for any *
* purpose with or without fee is hereby granted. *
@@ -54,6 +54,7 @@
#include "ctx.h"
#include "eval.h"
#include "parse.h"
+#include "util.h"
#include <errno.h>
#include <fcntl.h>
#include <locale.h>
@@ -79,9 +80,7 @@ static int redirect(int fd, const char *path, int flags) {
}
int ret = dup2(newfd, fd);
- int err = errno;
- close(newfd);
- errno = err;
+ close_quietly(newfd);
return ret;
}
diff --git a/parse.c b/parse.c
index aea7b4f..8ff47c2 100644
--- a/parse.c
+++ b/parse.c
@@ -1,6 +1,6 @@
/****************************************************************************
* bfs *
- * Copyright (C) 2015-2021 Tavian Barnes <tavianator@tavianator.com> *
+ * Copyright (C) 2015-2022 Tavian Barnes <tavianator@tavianator.com> *
* *
* Permission to use, copy, modify, and/or distribute this software for any *
* purpose with or without fee is hereby granted. *
@@ -2743,7 +2743,7 @@ static CFILE *launch_pager(pid_t *pid, CFILE *cout) {
goto fail_ctx;
}
- close(pipefd[0]);
+ xclose(pipefd[0]);
bfs_spawn_destroy(&ctx);
free(exe);
return ret;
@@ -2758,10 +2758,10 @@ fail_file:
}
fail_pipe:
if (pipefd[1] >= 0) {
- close(pipefd[1]);
+ xclose(pipefd[1]);
}
if (pipefd[0] >= 0) {
- close(pipefd[0]);
+ xclose(pipefd[0]);
}
fail_exe:
free(exe);
diff --git a/spawn.c b/spawn.c
index d4ff4fd..31f9897 100644
--- a/spawn.c
+++ b/spawn.c
@@ -1,6 +1,6 @@
/****************************************************************************
* bfs *
- * Copyright (C) 2018-2019 Tavian Barnes <tavianator@tavianator.com> *
+ * Copyright (C) 2018-2022 Tavian Barnes <tavianator@tavianator.com> *
* *
* Permission to use, copy, modify, and/or distribute this software for any *
* purpose with or without fee is hereby granted. *
@@ -146,7 +146,7 @@ static void bfs_spawn_exec(const char *exe, const struct bfs_spawn *ctx, char **
int error;
const struct bfs_spawn_action *actions = ctx ? ctx->actions : NULL;
- close(pipefd[0]);
+ xclose(pipefd[0]);
for (const struct bfs_spawn_action *action = actions; action; action = action->next) {
// Move the error-reporting pipe out of the way if necessary...
@@ -155,7 +155,7 @@ static void bfs_spawn_exec(const char *exe, const struct bfs_spawn *ctx, char **
if (fd < 0) {
goto fail;
}
- close(pipefd[1]);
+ xclose(pipefd[1]);
pipefd[1] = fd;
}
@@ -198,7 +198,7 @@ fail:
// unsuccessfully, but won't know why
(void) xwrite(pipefd[1], &error, sizeof(error));
- close(pipefd[1]);
+ xclose(pipefd[1]);
_Exit(127);
}
@@ -224,15 +224,11 @@ pid_t bfs_spawn(const char *exe, const struct bfs_spawn *ctx, char **argv, char
return -1;
}
- int error;
pid_t pid = fork();
-
if (pid < 0) {
- error = errno;
- close(pipefd[1]);
- close(pipefd[0]);
+ close_quietly(pipefd[1]);
+ close_quietly(pipefd[0]);
free(resolved);
- errno = error;
return -1;
} else if (pid == 0) {
// Child
@@ -240,11 +236,12 @@ pid_t bfs_spawn(const char *exe, const struct bfs_spawn *ctx, char **argv, char
}
// Parent
- close(pipefd[1]);
+ xclose(pipefd[1]);
free(resolved);
+ int error;
ssize_t nbytes = xread(pipefd[0], &error, sizeof(error));
- close(pipefd[0]);
+ xclose(pipefd[0]);
if (nbytes == sizeof(error)) {
int wstatus;
waitpid(pid, &wstatus, 0);
diff --git a/util.c b/util.c
index fa7a5b6..71b3c53 100644
--- a/util.c
+++ b/util.c
@@ -1,6 +1,6 @@
/****************************************************************************
* bfs *
- * Copyright (C) 2016-2021 Tavian Barnes <tavianator@tavianator.com> *
+ * Copyright (C) 2016-2022 Tavian Barnes <tavianator@tavianator.com> *
* *
* Permission to use, copy, modify, and/or distribute this software for any *
* purpose with or without fee is hereby granted. *
@@ -89,7 +89,7 @@ int dup_cloexec(int fd) {
}
if (fcntl(ret, F_SETFD, FD_CLOEXEC) == -1) {
- close(ret);
+ close_quietly(ret);
return -1;
}
@@ -106,10 +106,8 @@ int pipe_cloexec(int pipefd[2]) {
}
if (fcntl(pipefd[0], F_SETFD, FD_CLOEXEC) == -1 || fcntl(pipefd[1], F_SETFD, FD_CLOEXEC) == -1) {
- int error = errno;
- close(pipefd[1]);
- close(pipefd[0]);
- errno = error;
+ close_quietly(pipefd[1]);
+ close_quietly(pipefd[0]);
return -1;
}
@@ -464,11 +462,23 @@ FILE *xfopen(const char *path, int flags) {
FILE *ret = fdopen(fd, mode);
if (!ret) {
- int error = errno;
- close(fd);
- errno = error;
+ close_quietly(fd);
return NULL;
}
return ret;
}
+
+int xclose(int fd) {
+ int ret = close(fd);
+ if (ret != 0) {
+ assert(errno != EBADF);
+ }
+ return ret;
+}
+
+void close_quietly(int fd) {
+ int error = errno;
+ xclose(fd);
+ errno = error;
+}
diff --git a/util.h b/util.h
index ccac549..37c03fa 100644
--- a/util.h
+++ b/util.h
@@ -1,6 +1,6 @@
/****************************************************************************
* bfs *
- * Copyright (C) 2016-2021 Tavian Barnes <tavianator@tavianator.com> *
+ * Copyright (C) 2016-2022 Tavian Barnes <tavianator@tavianator.com> *
* *
* Permission to use, copy, modify, and/or distribute this software for any *
* purpose with or without fee is hereby granted. *
@@ -298,4 +298,22 @@ char *xgetdelim(FILE *file, char delim);
*/
FILE *xfopen(const char *path, int flags);
+/**
+ * close() wrapper that asserts the file descriptor is valid.
+ *
+ * @param fd
+ * The file descriptor to close.
+ * @return
+ * 0 on success, or -1 on error.
+ */
+int xclose(int fd);
+
+/**
+ * close() variant that preserves errno.
+ *
+ * @param fd
+ * The file descriptor to close.
+ */
+void close_quietly(int fd);
+
#endif // BFS_UTIL_H