view src/lib/file-set-size.c @ 6410:e4eb71ae8e96 HEAD

Changed .h ifdef/defines to use <NAME>_H format.
author Timo Sirainen <tss@iki.fi>
date Sun, 16 Sep 2007 11:31:27 +0300
parents 052f000ad273
children 65c69a53a7be
line wrap: on
line source

/* Copyright (c) 2002-2003 Timo Sirainen */

#define _XOPEN_SOURCE 600 /* Required by glibc */
#include "lib.h"
#include "file-set-size.h"

#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>

int file_set_size(int fd, off_t size)
{
#ifndef HAVE_POSIX_FALLOCATE
	char block[4096];
	off_t offset;
	ssize_t ret;
#endif
	struct stat st;

	i_assert(size >= 0);

	if (fstat(fd, &st) < 0)
		return -1;

	if (size < st.st_size)
		return ftruncate(fd, size);
	if (size == st.st_size)
		return 0;

#ifdef HAVE_POSIX_FALLOCATE
	return posix_fallocate(fd, st.st_size, size - st.st_size);
#else
	/* start growing the file */
	offset = st.st_size;
	memset(block, 0, I_MIN((ssize_t)sizeof(block), size - offset));

	while (offset < size) {
		ret = pwrite(fd, block,
			     I_MIN((ssize_t)sizeof(block), size - offset),
			     offset);
		if (ret < 0)
			return -1;
		offset += size;
	}
	return 0;
#endif
}