diff options
Diffstat (limited to 'util/libreboot-utils/lib/file.c')
| -rw-r--r-- | util/libreboot-utils/lib/file.c | 131 |
1 files changed, 117 insertions, 14 deletions
diff --git a/util/libreboot-utils/lib/file.c b/util/libreboot-utils/lib/file.c index 48eb37ed..b9d31ad7 100644 --- a/util/libreboot-utils/lib/file.c +++ b/util/libreboot-utils/lib/file.c @@ -88,10 +88,7 @@ fsync_dir(const char *path) maxlen = 4096; #endif - 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 (if_err(slen(path, maxlen, &pathlen) == 0, EINVAL)) goto err_fsync_dir; memcpy(smalloc(&dirbuf, pathlen + 1), @@ -323,15 +320,15 @@ try_rw_again: real_pread_pwrite: #endif if (rw_type == IO_WRITE) - r = write(fd, mem, nrw); + r = write_on_eintr(fd, mem, nrw); else if (rw_type == IO_READ) - r = read(fd, mem, nrw); + r = read_on_eintr(fd, mem, nrw); #if defined(REAL_POS_IO) && \ REAL_POS_IO > 0 else if (rw_type == IO_PWRITE) - r = pwrite(fd, mem, nrw, off); + r = pwrite_on_eintr(fd, mem, nrw, off); else if (rw_type == IO_PREAD) - r = pread(fd, mem, nrw, off); + r = pread_on_eintr(fd, mem, nrw, off); #endif if (r == -1 && (errno == try_err(loop_eintr, EINTR) @@ -386,9 +383,9 @@ real_pread_pwrite: } if (rw_type == IO_PREAD) - r = read(fd, mem, nrw); + r = read_on_eintr(fd, mem, nrw); else if (rw_type == IO_PWRITE) - r = write(fd, mem, nrw); + r = write_on_eintr(fd, mem, nrw); if (rw_over_nrw(r, nrw) == -1) break; @@ -841,11 +838,12 @@ fs_dirname_basename(const char *path, size_t maxlen = 4096; #endif - if (path == NULL || dir == NULL || base == NULL || - if_err_sys(slen(path, maxlen, &len) < 0)) + if (if_err(path == NULL || dir == NULL || base == NULL, EFAULT)) return -1; - memcpy(smalloc(&buf, len + 1), path, len + 1); + slen(path, maxlen, &len); + memcpy(smalloc(&buf, len + 1), + path, len + 1); /* strip trailing slashes */ while (len > 1 && buf[len - 1] == '/') @@ -865,7 +863,7 @@ fs_dirname_basename(const char *path, } } else if (allow_relative) { - *dir = strdup("."); + sdup(".", maxlen, dir); *base = buf; } else { errno = EINVAL; @@ -955,13 +953,118 @@ retry: return rval; } +ssize_t +read_on_eintr(int fd, + void *buf, size_t count) +{ + int saved_errno = errno; + int rval; + + if (if_err(buf == NULL, EFAULT) || + if_err(fd < 0, EBADF) || + if_err(count == 0, EINVAL)) + goto err; + +retry: + errno = 0; + + if ((rval = read(fd, buf, count)) == -1 && ( + errno == EINTR || + errno == EAGAIN || + errno == EWOULDBLOCK || + errno == ETXTBSY)) + goto retry; + + errno = saved_errno; + return rval; +err: + return set_errno(saved_errno, EIO); +} + +ssize_t +pread_on_eintr(int fd, + void *buf, size_t count, + off_t off) +{ + int saved_errno = errno; + int rval; + + if (if_err(buf == NULL, EFAULT) || + if_err(fd < 0, EBADF) || + if_err(off < 0, EFAULT) || + if_err(count == 0, EINVAL)) + goto err; + +retry: + errno = 0; + + if ((rval = pread(fd, buf, count, off)) == -1 && ( + errno == EINTR || + errno == EAGAIN || + errno == EWOULDBLOCK || + errno == ETXTBSY)) + goto retry; + + errno = saved_errno; + return rval; +err: + return set_errno(saved_errno, EIO); +} +ssize_t +write_on_eintr(int fd, + void *buf, size_t count) +{ + int saved_errno = errno; + int rval; + if (if_err(buf == NULL, EFAULT) || + if_err(fd < 0, EBADF) || + if_err(count == 0, EINVAL)) + goto err; +retry: + errno = 0; + if ((rval = write(fd, buf, count)) == -1 && ( + errno == EINTR || + errno == EAGAIN || + errno == EWOULDBLOCK || + errno == ETXTBSY)) + goto retry; + errno = saved_errno; + return rval; +err: + return set_errno(saved_errno, EIO); +} +ssize_t +pwrite_on_eintr(int fd, + void *buf, size_t count, + off_t off) +{ + int saved_errno = errno; + int rval; + if (if_err(buf == NULL, EFAULT) || + if_err(fd < 0, EBADF) || + if_err(off < 0, EFAULT) || + if_err(count == 0, EINVAL)) + goto err; +retry: + errno = 0; + if ((rval = pwrite(fd, buf, count, off)) == -1 && ( + errno == EINTR || + errno == EAGAIN || + errno == EWOULDBLOCK || + errno == ETXTBSY)) + goto retry; + errno = saved_errno; + return rval; +err: + return set_errno(saved_errno, EIO); +} |
