Like the other functions, these don't handle non-blocking I/O.
Signed-off-by: Josh Durgin <josh.durgin@inktank.com>
[])
+# splice/tee
+AC_CHECK_FUNC([splice],
+ [AC_DEFINE([CEPH_HAVE_SPLICE], [], [splice(2) is supported])],
+ [])
+
+AC_CHECK_HEADERS([arpa/nameser_compat.h])
AC_CHECK_HEADERS([sys/prctl.h])
AC_CHECK_FUNCS([prctl])
return 0;
}
+#ifdef CEPH_HAVE_SPLICE
+ssize_t safe_splice(int fd_in, loff_t *off_in, int fd_out, loff_t *off_out,
+ size_t len, unsigned int flags)
+{
+ size_t cnt = 0;
+
+ while (cnt < len) {
+ ssize_t r = splice(fd_in, off_in, fd_out, off_out, len - cnt, flags);
+ if (r <= 0) {
+ if (r == 0) {
+ // EOF
+ return cnt;
+ }
+ if (errno == EINTR)
+ continue;
+ return -errno;
+ }
+ cnt += r;
+ }
+ return cnt;
+}
+
+ssize_t safe_splice_exact(int fd_in, loff_t *off_in, int fd_out,
+ loff_t *off_out, size_t len, unsigned int flags)
+{
+ ssize_t ret = safe_splice(fd_in, off_in, fd_out, off_out, len, flags);
+ if (ret < 0)
+ return ret;
+ if ((size_t)ret != len)
+ return -EDOM;
+ return 0;
+}
+#endif
+
int safe_write_file(const char *base, const char *file,
const char *val, size_t vallen)
{
#ifndef CEPH_SAFE_IO
#define CEPH_SAFE_IO
+#include "acconfig.h"
#include "common/compiler_extensions.h"
#include <sys/types.h>
WARN_UNUSED_RESULT;
ssize_t safe_pwrite(int fd, const void *buf, size_t count, off_t offset)
WARN_UNUSED_RESULT;
+#ifdef CEPH_HAVE_SPLICE
+ /*
+ * Similar to the above (non-exact version) and below (exact version).
+ * See splice(2) for parameter descriptions.
+ */
+ ssize_t safe_splice(int fd_in, loff_t *off_in, int fd_out, loff_t *off_out,
+ size_t len, unsigned int flags)
+ WARN_UNUSED_RESULT;
+ ssize_t safe_splice_exact(int fd_in, loff_t *off_in, int fd_out,
+ loff_t *off_out, size_t len, unsigned int flags)
+ WARN_UNUSED_RESULT;
+#endif
/*
* Same as the above functions, but return -EDOM unless exactly the requested