Currently I have a wrapper function for the read
/write
system calls, the purpose of which is to eliminate partial transfer scenarios, by retrying until either all data is transferred or the system call fails in trying to do so.
Includes:
#include <errno.h>
#include <unistd.h>
Code:
int force(ssize_t(*const func)(int, void *, size_t), const int file, void *ptr, size_t size) {
for (ssize_t r;; ptr = (char *)ptr+r) {
if ((r = func(file, ptr, size)) == -1) {
if (errno == EINTR)
continue;
return -1;
}
if (size -= r)
continue;
return 0;
}
}
This function would be used as such:
extern struct Conf conf;
int file = open("file", O_RDONLY);
if (force(read, file, &conf, sizeof(struct Conf)))
handle_error();
If write
is passed, ptr
may point to const
data because write
does not modify the data pointed to. But const
casts are considered improper. Should I keep this wrapper, or should I write separate and mostly duplicated, but 'proper' wrappers?
int force_read(const int file, void *ptr, size_t size) {
for (ssize_t r;; ptr = (char *)ptr+r) {
if ((r = read(file, ptr, size)) == -1) {
if (errno == EINTR)
continue;
return -1;
}
if (size -= r)
continue;
return 0;
}
}
int force_write(const int file, const void *ptr, size_t size) {
for (ssize_t r;; ptr = (const char *)ptr+r) {
if ((r = write(file, ptr, size)) == -1) {
if (errno == EINTR)
continue;
return -1;
}
if (size -= r)
continue;
return 0;
}
}
read, write, EINTR
you identified as non-standard,ssize_t, O_RDONLY, handle_error()
are also non-standard C. Recommend that you add the Posix tag (and since the limit is 5, drop one). Further, even with a tag change, posted code does not compile. \$\endgroup\$