13ce311afSJiri Olsa // SPDX-License-Identifier: GPL-2.0
23ce311afSJiri Olsa #include <unistd.h>
33ce311afSJiri Olsa #include <stdbool.h>
43ce311afSJiri Olsa #include <errno.h>
53ce311afSJiri Olsa #include <linux/kernel.h>
63ce311afSJiri Olsa #include <internal/lib.h>
73ce311afSJiri Olsa
83ce311afSJiri Olsa unsigned int page_size;
93ce311afSJiri Olsa
ion(bool is_read,int fd,void * buf,size_t n)103ce311afSJiri Olsa static ssize_t ion(bool is_read, int fd, void *buf, size_t n)
113ce311afSJiri Olsa {
123ce311afSJiri Olsa void *buf_start = buf;
133ce311afSJiri Olsa size_t left = n;
143ce311afSJiri Olsa
153ce311afSJiri Olsa while (left) {
163ce311afSJiri Olsa /* buf must be treated as const if !is_read. */
173ce311afSJiri Olsa ssize_t ret = is_read ? read(fd, buf, left) :
183ce311afSJiri Olsa write(fd, buf, left);
193ce311afSJiri Olsa
203ce311afSJiri Olsa if (ret < 0 && errno == EINTR)
213ce311afSJiri Olsa continue;
223ce311afSJiri Olsa if (ret <= 0)
233ce311afSJiri Olsa return ret;
243ce311afSJiri Olsa
253ce311afSJiri Olsa left -= ret;
263ce311afSJiri Olsa buf += ret;
273ce311afSJiri Olsa }
283ce311afSJiri Olsa
293ce311afSJiri Olsa BUG_ON((size_t)(buf - buf_start) != n);
303ce311afSJiri Olsa return n;
313ce311afSJiri Olsa }
323ce311afSJiri Olsa
333ce311afSJiri Olsa /*
343ce311afSJiri Olsa * Read exactly 'n' bytes or return an error.
353ce311afSJiri Olsa */
readn(int fd,void * buf,size_t n)363ce311afSJiri Olsa ssize_t readn(int fd, void *buf, size_t n)
373ce311afSJiri Olsa {
383ce311afSJiri Olsa return ion(true, fd, buf, n);
393ce311afSJiri Olsa }
403ce311afSJiri Olsa
preadn(int fd,void * buf,size_t n,off_t offs)41*618ee783SAdrian Hunter ssize_t preadn(int fd, void *buf, size_t n, off_t offs)
42*618ee783SAdrian Hunter {
43*618ee783SAdrian Hunter size_t left = n;
44*618ee783SAdrian Hunter
45*618ee783SAdrian Hunter while (left) {
46*618ee783SAdrian Hunter ssize_t ret = pread(fd, buf, left, offs);
47*618ee783SAdrian Hunter
48*618ee783SAdrian Hunter if (ret < 0 && errno == EINTR)
49*618ee783SAdrian Hunter continue;
50*618ee783SAdrian Hunter if (ret <= 0)
51*618ee783SAdrian Hunter return ret;
52*618ee783SAdrian Hunter
53*618ee783SAdrian Hunter left -= ret;
54*618ee783SAdrian Hunter buf += ret;
55*618ee783SAdrian Hunter offs += ret;
56*618ee783SAdrian Hunter }
57*618ee783SAdrian Hunter
58*618ee783SAdrian Hunter return n;
59*618ee783SAdrian Hunter }
60*618ee783SAdrian Hunter
613ce311afSJiri Olsa /*
623ce311afSJiri Olsa * Write exactly 'n' bytes or return an error.
633ce311afSJiri Olsa */
writen(int fd,const void * buf,size_t n)643ce311afSJiri Olsa ssize_t writen(int fd, const void *buf, size_t n)
653ce311afSJiri Olsa {
663ce311afSJiri Olsa /* ion does not modify buf. */
673ce311afSJiri Olsa return ion(false, fd, (void *)buf, n);
683ce311afSJiri Olsa }
69