1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 * Ceph - scalable distributed file system
6 * Copyright (C) 2011 New Dream Network
8 * This is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License version 2.1, as published by the Free Software
11 * Foundation. See file COPYING.
15 #include "common/safe_io.h"
16 #include "include/compat.h"
25 ssize_t safe_read(int fd, void *buf, size_t count)
30 ssize_t r = read(fd, buf, count - cnt);
41 buf = (char *)buf + r;
46 ssize_t safe_read_exact(int fd, void *buf, size_t count)
48 ssize_t ret = safe_read(fd, buf, count);
51 if ((size_t)ret != count)
56 ssize_t safe_write(int fd, const void *buf, size_t count)
59 ssize_t r = write(fd, buf, count);
66 buf = (char *)buf + r;
71 ssize_t safe_pread(int fd, void *buf, size_t count, off_t offset)
77 ssize_t r = pread(fd, b + cnt, count - cnt, offset + cnt);
93 ssize_t safe_pread_exact(int fd, void *buf, size_t count, off_t offset)
95 ssize_t ret = safe_pread(fd, buf, count, offset);
98 if ((size_t)ret != count)
103 ssize_t safe_pwrite(int fd, const void *buf, size_t count, off_t offset)
106 ssize_t r = pwrite(fd, buf, count, offset);
113 buf = (char *)buf + r;
119 #ifdef CEPH_HAVE_SPLICE
120 ssize_t safe_splice(int fd_in, off_t *off_in, int fd_out, off_t *off_out,
121 size_t len, unsigned int flags)
126 ssize_t r = splice(fd_in, off_in, fd_out, off_out, len - cnt, flags);
143 ssize_t safe_splice_exact(int fd_in, off_t *off_in, int fd_out,
144 off_t *off_out, size_t len, unsigned int flags)
146 ssize_t ret = safe_splice(fd_in, off_in, fd_out, off_out, len, flags);
149 if ((size_t)ret != len)
155 int safe_write_file(const char *base, const char *file,
156 const char *val, size_t vallen)
163 // does the file already have correct content?
165 ret = safe_read_file(base, file, oldval, sizeof(oldval));
166 if (ret == (int)vallen && memcmp(oldval, val, vallen) == 0)
169 snprintf(fn, sizeof(fn), "%s/%s", base, file);
170 snprintf(tmp, sizeof(tmp), "%s/%s.tmp", base, file);
171 fd = open(tmp, O_WRONLY|O_CREAT|O_TRUNC, 0644);
176 ret = safe_write(fd, val, vallen);
178 VOID_TEMP_FAILURE_RETRY(close(fd));
183 if (ret < 0) ret = -errno;
184 VOID_TEMP_FAILURE_RETRY(close(fd));
189 ret = rename(tmp, fn);
196 fd = open(base, O_RDONLY);
202 if (ret < 0) ret = -errno;
203 VOID_TEMP_FAILURE_RETRY(close(fd));
208 int safe_read_file(const char *base, const char *file,
209 char *val, size_t vallen)
214 snprintf(fn, sizeof(fn), "%s/%s", base, file);
215 fd = open(fn, O_RDONLY);
219 len = safe_read(fd, val, vallen);
221 VOID_TEMP_FAILURE_RETRY(close(fd));
224 // close sometimes returns errors, but only after write()
225 VOID_TEMP_FAILURE_RETRY(close(fd));