diff options
Diffstat (limited to 'util/libreboot-utils/lib/file.c')
| -rw-r--r-- | util/libreboot-utils/lib/file.c | 174 |
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] == '/') |
