Set file size in SYSV

William Kucharski kucharsk at uts.amdahl.com
Sun Aug 13 11:20:07 AEST 1989


In article <708 at msa3b.UUCP>, kevin at msa3b.UUCP (Kevin P. Kleinfelter) writes:
> O.K. I give up.  How do you set the size of a file in SYSV.
> In particular, I want to take a file which is 1000 bytes, and truncate
> it to 500 bytes WITHOUT COPYING IT.

What you're looking for is a SYSV version of the BSD (f)truncate(3) call.

If you're lucky enough to be running a version of SVR3 which implements the
undocumented F_FREESP fcntl, the code below should do nicely...

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

#ifndef NULL
#define NULL	0
#endif

int
ftruncate(fd, length)
int	fd;	/* file descriptor */
off_t	length;	/* length to set file to */
{
	extern	long	lseek();

	struct	flock	fl;
	struct	stat	filebuf;

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

	if (filebuf.st_size < length) {
		/* extend file length */

		if ((lseek(fd, (length - 1), SEEK_SET)) < 0)
			return(-1);	

		/* write a "0" byte */

		if ((write(fd, "", 1)) != 1)
			return(-1);
	} else {
		/* truncate length */

		fl.l_whence = 0;
		fl.l_len = (off_t) 0;
		fl.l_start = length;
		fl.l_type = F_WRLCK;	/* write lock on file space */

		/* 
		 * This relies on the UNDOCUMENTED F_FREESP argument to 
		 * fcntl(2), which truncates the file so that it ends at the
		 * position indicated by fl.l_start.
		 *
		 * If you can't find it listed in your <fcntl.h> or 
		 * <sys/fcntl.h>, chances are it isn't implemented in
		 * your kernel.
		 */

		if (fcntl(fd, F_FREESP, &fl) < 0)
			return(-1);
	}

	return(0);
}


int
truncate(path, length)
char	*path;
off_t	length;
{
	int	fd;	/* file descriptor */

	if ((path == NULL) || (*path == NULL)) {
		errno = EINVAL;
		return(-1);
	}

	if ((fd = open(path, O_WRONLY)) < 0)
		return(-1);

	if (ftruncate(fd, length) < 0) {
		(void) close(fd);
		return(-1);
	}

	(void) close(fd);
	return(0);
}
-- 
					William Kucharski

ARPA: kucharsk at uts.amdahl.com
UUCP: ...!{ames,apple,decwrl,sun,uunet}!amdahl!kucharsk

Disclaimer:  The opinions expressed above are my own, and may not agree with
	     those of any other sentient being, not to mention those of my 
	     employer.  So there.



More information about the Comp.unix.questions mailing list