write-full.c revision c9bf63e9094761767a63ac6b189bcf60bcffdc44
89a126810703c666309310d0f3189e9834d70b5bTimo Sirainen/* Copyright (c) 2002-2007 Dovecot authors, see the included COPYING file */
c27c55fe2c083c7573cde51e366ef689c1a69708Timo Sirainen
d2f5aacd3d549c3d39dae41b6522d585244b016dTimo Sirainen#include "lib.h"
ca8863af6ce6b695a369dfb7b50e909420dc45dfTimo Sirainen#include "write-full.h"
d2f5aacd3d549c3d39dae41b6522d585244b016dTimo Sirainen
c27c55fe2c083c7573cde51e366ef689c1a69708Timo Sirainen#include <unistd.h>
c27c55fe2c083c7573cde51e366ef689c1a69708Timo Sirainen
c27c55fe2c083c7573cde51e366ef689c1a69708Timo Sirainenint write_full(int fd, const void *data, size_t size)
c27c55fe2c083c7573cde51e366ef689c1a69708Timo Sirainen{
c27c55fe2c083c7573cde51e366ef689c1a69708Timo Sirainen ssize_t ret;
c27c55fe2c083c7573cde51e366ef689c1a69708Timo Sirainen
279184dd3ab877f8f08c05f81a5570b20c6c215eTimo Sirainen while (size > 0) {
d2f5aacd3d549c3d39dae41b6522d585244b016dTimo Sirainen ret = write(fd, data, size < SSIZE_T_MAX ? size : SSIZE_T_MAX);
c9bf63e9094761767a63ac6b189bcf60bcffdc44Timo Sirainen if (unlikely(ret < 0))
c27c55fe2c083c7573cde51e366ef689c1a69708Timo Sirainen return -1;
c27c55fe2c083c7573cde51e366ef689c1a69708Timo Sirainen
c9bf63e9094761767a63ac6b189bcf60bcffdc44Timo Sirainen if (unlikely(ret == 0)) {
c27c55fe2c083c7573cde51e366ef689c1a69708Timo Sirainen /* nothing was written, only reason for this should
c27c55fe2c083c7573cde51e366ef689c1a69708Timo Sirainen be out of disk space */
c27c55fe2c083c7573cde51e366ef689c1a69708Timo Sirainen errno = ENOSPC;
c27c55fe2c083c7573cde51e366ef689c1a69708Timo Sirainen return -1;
c27c55fe2c083c7573cde51e366ef689c1a69708Timo Sirainen }
2d566ba9c304ffa14cd1f8f39e1d9fd432be9db5Timo Sirainen
8d6cb44a0161d88743756733f83c4fb278485987Timo Sirainen data = CONST_PTR_OFFSET(data, ret);
c27c55fe2c083c7573cde51e366ef689c1a69708Timo Sirainen size -= ret;
279184dd3ab877f8f08c05f81a5570b20c6c215eTimo Sirainen }
c27c55fe2c083c7573cde51e366ef689c1a69708Timo Sirainen
c27c55fe2c083c7573cde51e366ef689c1a69708Timo Sirainen return 0;
c27c55fe2c083c7573cde51e366ef689c1a69708Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenint pwrite_full(int fd, const void *data, size_t size, off_t offset)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ssize_t ret;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen while (size > 0) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ret = pwrite(fd, data, size < SSIZE_T_MAX ?
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen size : SSIZE_T_MAX, offset);
c9bf63e9094761767a63ac6b189bcf60bcffdc44Timo Sirainen if (unlikely(ret < 0))
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return -1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
c9bf63e9094761767a63ac6b189bcf60bcffdc44Timo Sirainen if (unlikely(ret == 0)) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* nothing was written, only reason for this should
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen be out of disk space */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen errno = ENOSPC;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return -1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
2d566ba9c304ffa14cd1f8f39e1d9fd432be9db5Timo Sirainen
8d6cb44a0161d88743756733f83c4fb278485987Timo Sirainen data = CONST_PTR_OFFSET(data, ret);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen size -= ret;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen offset += ret;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return 0;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}