summaryrefslogtreecommitdiff
path: root/util/libreboot-utils/lib/file.c
diff options
context:
space:
mode:
Diffstat (limited to 'util/libreboot-utils/lib/file.c')
-rw-r--r--util/libreboot-utils/lib/file.c174
1 files changed, 71 insertions, 103 deletions
diff --git a/util/libreboot-utils/lib/file.c b/util/libreboot-utils/lib/file.c
index 3ca50889..4623748c 100644
--- a/util/libreboot-utils/lib/file.c
+++ b/util/libreboot-utils/lib/file.c
@@ -62,27 +62,7 @@ same_file(int fd, struct stat *st_old,
return 0;
err_same_file:
-
- if (errno == saved_errno)
- errno = ESTALE;
-
- return -1;
-}
-
-void
-xopen(int *fd_ptr, const char *path, int flags, struct stat *st)
-{
- if ((*fd_ptr = open(path, flags)) < 0)
- err_no_cleanup(0, errno, "%s", path);
-
- if (fstat(*fd_ptr, st) < 0)
- err_no_cleanup(0, errno, "%s: stat", path);
-
- if (!S_ISREG(st->st_mode))
- err_no_cleanup(0, errno, "%s: not a regular file", path);
-
- if (lseek_on_eintr(*fd_ptr, 0, SEEK_CUR, 1, 1) == (off_t)-1)
- err_no_cleanup(0, errno, "%s: file not seekable", path);
+ return set_errno(saved_errno, ESTALE);
}
int
@@ -111,12 +91,11 @@ fsync_dir(const char *path)
if (if_err(path == NULL, EFAULT) ||
if_err_sys(slen(path, maxlen, &pathlen) < 0) ||
if_err(pathlen >= maxlen || pathlen < 0, EMSGSIZE) ||
- if_err(pathlen == 0, EINVAL)
- ||
- if_err_sys((dirbuf = malloc(pathlen + 1)) == NULL))
+ if_err(pathlen == 0, EINVAL))
goto err_fsync_dir;
- memcpy(dirbuf, path, pathlen + 1);
+ memcpy(smalloc(&dirbuf, pathlen + 1),
+ path, pathlen + 1);
slash = strrchr(dirbuf, '/');
if (slash != NULL) {
@@ -147,11 +126,7 @@ fsync_dir(const char *path)
if_err_sys(fsync_on_eintr(dirfd) == -1))
goto err_fsync_dir;
- if (close_on_eintr(dirfd) == -1) {
-
- dirfd = -1;
- goto err_fsync_dir;
- }
+ close_on_eintr(&dirfd);
free_and_set_null(&dirbuf);
@@ -160,13 +135,11 @@ fsync_dir(const char *path)
err_fsync_dir:
- if (errno == saved_errno)
- errno = EIO;
free_and_set_null(&dirbuf);
- close_no_err(&dirfd);
+ close_on_eintr(&dirfd);
- return -1;
+ return set_errno(saved_errno, EIO);
}
/* rw_file_exact() - Read perfectly or die
@@ -269,10 +242,7 @@ rw_file_exact(int fd, unsigned char *mem, size_t nrw,
err_rw_file_exact:
- if (errno == saved_errno)
- errno = EIO;
-
- return -1;
+ return set_errno(saved_errno, EIO);
}
/* prw() - portable read-write with more
@@ -451,11 +421,7 @@ real_pread_pwrite:
#endif
err_prw:
-
- if (errno == saved_errno)
- errno = EIO;
-
- return -1;
+ return set_errno(saved_errno, EIO);
}
int
@@ -477,10 +443,7 @@ io_args(int fd, void *mem, size_t nrw,
return 0;
err_io_args:
- if (errno == saved_errno)
- errno = EINVAL;
-
- return -1;
+ return set_errno(saved_errno, EINVAL);
}
int
@@ -498,10 +461,7 @@ check_file(int fd, struct stat *st)
return 0;
err_is_file:
- if (errno == saved_errno)
- errno = EINVAL;
-
- return -1;
+ return set_errno(saved_errno, EINVAL);
}
/* POSIX can say whatever it wants.
@@ -523,10 +483,7 @@ rw_over_nrw(ssize_t r, size_t nrw)
return r;
err_rw_over_nrw:
- if (errno == saved_errno)
- errno = EIO;
-
- return -1;
+ return set_errno(saved_errno, EIO);
}
off_t
@@ -583,73 +540,83 @@ try_err(int loop_err, int errval)
void
free_and_set_null(char **buf)
{
- if (buf == NULL || *buf == NULL)
+ if (buf == NULL)
+ err_exit(EFAULT,
+ "null ptr (to ptr for freeing) in free_and_set_null");
+
+ if (*buf == NULL)
return;
free(*buf);
*buf = NULL;
}
-/* also returns error code */
-int
-close_warn(int *fd, char *s)
+void
+open_on_eintr(const char *path,
+ int *fd, int flags, mode_t mode,
+ struct stat *st)
{
+ int r = -1;
int saved_errno = errno;
- if (fd == NULL) {
- if (s != NULL)
- fprintf(stderr, "FAIL: %s: bad fd ptr\n", s);
- return -1;
- }
+ if (path == NULL)
+ err_exit(EINVAL, "open_on_eintr: null path");
- if (*fd < 0 && s != NULL) {
- fprintf(stderr, "WARN: %s: already closed\n", s);
- } else if (close(*fd) < 0) {
- if (s != NULL)
- fprintf(stderr, "FAIL: %s: close\n", s);
- return -1;
- }
+ if (fd == NULL)
+ err_exit(EFAULT, "%s: open_on_eintr: null fd ptr", path);
- *fd = -1;
- errno = saved_errno;
+ if (*fd >= 0)
+ err_exit(EBADF, "%s: open_on_eintr: file already open", path);
- return 0;
-}
+ do {
+ r = open(path, flags, mode);
+ } while (r == -1 && (
+ errno == EINTR || errno == EAGAIN ||
+ errno == EWOULDBLOCK || errno == ETXTBSY));
-/* TODO: remove this, and just check
- * err on every close. */
-void
-close_no_err(int *fd)
-{
- int saved_errno = errno;
+ if (r < 0)
+ err_exit(errno, "%s: open_on_eintr: could not close", path);
- if (fd == NULL || *fd < 0)
- return;
+ *fd = r;
- (void) close_on_eintr(*fd);
- *fd = -1;
+ if (st != NULL) {
+ if (fstat(*fd, st) < 0)
+ err_exit(errno, "%s: stat", path);
+
+ if (!S_ISREG(st->st_mode))
+ err_exit(errno, "%s: not a regular file", path);
+ }
+
+ if (lseek_on_eintr(*fd, 0, SEEK_CUR, 1, 1) == (off_t)-1)
+ err_exit(errno, "%s: file not seekable", path);
errno = saved_errno;
}
-/* TODO: make fd a pointer insttead
- and automatically reset -1 here */
-int
-close_on_eintr(int fd)
+void
+close_on_eintr(int *fd)
{
int r;
int saved_errno = errno;
+ if (fd == NULL)
+ err_exit(EINVAL, "close_on_eintr: null pointer");
+
+ if (*fd < 0)
+ return;
+
do {
- r = close(fd);
+ r = close(*fd);
} while (r == -1 && (
errno == EINTR || errno == EAGAIN ||
errno == EWOULDBLOCK || errno == ETXTBSY));
- if (r >= 0)
- errno = saved_errno;
+ if (r < 0)
+ err_exit(errno, "close_on_eintr: could not close");
- return r;
+ *fd = -1;
+
+ errno = saved_errno;
}
int
@@ -709,8 +676,10 @@ rootfs(void)
if (!fs_initialised) {
- global_fs.rootfd =
- open("/", O_RDONLY | O_DIRECTORY | O_CLOEXEC);
+ global_fs.rootfd = -1;
+
+ open_on_eintr("/", &global_fs.rootfd,
+ O_RDONLY | O_DIRECTORY | O_CLOEXEC, 0400, NULL);
if (global_fs.rootfd < 0)
return NULL;
@@ -762,7 +731,7 @@ fs_resolve_at(int dirfd, const char *path, int flags)
/* close previous fd if not the original input */
if (curfd != dirfd)
- (void) close_on_eintr(curfd);
+ close_on_eintr(&curfd);
curfd = nextfd;
nextfd = -1;
@@ -775,11 +744,11 @@ err:
saved_errno = errno;
if (nextfd >= 0)
- (void) close_on_eintr(nextfd);
+ close_on_eintr(&nextfd);
/* close curfd only if it's not the original */
if (curfd != dirfd && curfd >= 0)
- (void) close_on_eintr(curfd);
+ close_on_eintr(&curfd);
errno = saved_errno;
return -1;
@@ -848,7 +817,7 @@ fs_open_component(int dirfd, const char *name,
if (!S_ISDIR(st.st_mode)) {
- (void) close_on_eintr(fd);
+ close_on_eintr(&fd);
errno = ENOTDIR;
return -1;
}
@@ -862,7 +831,7 @@ fs_dirname_basename(const char *path,
char **dir, char **base,
int allow_relative)
{
- char *buf;
+ char *buf = NULL;
char *slash;
size_t len;
int rval;
@@ -874,11 +843,10 @@ fs_dirname_basename(const char *path,
#endif
if (path == NULL || dir == NULL || base == NULL ||
- if_err_sys(slen(path, maxlen, &len) < 0) ||
- if_err_sys((buf = malloc(len + 1)) == NULL))
+ if_err_sys(slen(path, maxlen, &len) < 0))
return -1;
- memcpy(buf, path, len + 1);
+ memcpy(smalloc(&buf, len + 1), path, len + 1);
/* strip trailing slashes */
while (len > 1 && buf[len - 1] == '/')