[net.sources] ftruncate library routine for non 4.2bsd sites

smk@axiom.UUCP (Steven M. Kramer) (06/22/85)

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>

/*
 * This mimicks a 4.2BSD system call.  Here, we just make it
 * a lil ol' routine.  It expects a file descriptor, the NEW
 * size to truncate to, and the file name (which we use but 4.2
 * doesn't).  What we do simply is copy size bytes to a temporary
 * file, truncate the original file to zero (which we CAN do), and
 * then copy the second file back to the first.
 *
 * Steve Kramer    Copyright 1/18/84
 * Not to be used for profit without author's permission.
 * May be otherwise redistributed.
 */
ftruncate(fr, size)
	int fr;
	long size;
{
	extern char	*mktemp();
	struct stat stat_buf;
	char 	*tname;
	register int	tf;
	register int s, n;
	long int new_size;
	char buf[BUFSIZ];

	/*
	 * Get a temporary file to copy to.
	 */
	tname = mktemp("/tmp/sXXXXXX");
	close(creat(tname, 0600));
	tf = open(tname, 2);
	if(tf < 0) {
		unlink(tname);
		return (-1);
	}

	/*
	 * Copy the original to the temporary file.  Do it in increments
	 * of BUFSIZ for efficiency.
	 */
	new_size = size;
	lseek(fr, (long)0, 0);
	while(new_size != 0) {
		s = BUFSIZ;
		if(new_size < BUFSIZ)
			s = new_size;
		n = read(fr, buf, s);
		if(n != s) {
			close(tf);
			unlink(tname);
			return(-1);
		}
		n = write(tf, buf, s);
		if(n != s) {
			close(tf);
			unlink(tname);
			return(-1);
		}
		new_size -= s;
	}

	/*
	 * Truncate the original file no that the information is
	 * stuck tightly away in the temporary.
	 */
	lseek(fr, (long)0, 0);
	lseek(tf, (long)0, 0);
	if (fstat (fr, &stat_buf) == 0)
		close(creat(name, stat_buf.st_mode & 0777));
	else
		close(creat(name, 0755));

	/*
	 * Now, copy back.
	 */
	new_size = size;
	while(new_size != 0) {
		s = BUFSIZ;
		if(new_size < BUFSIZ)
			s = new_size;
		n = read(tf, buf, s);
		if(n != s) {
			close (tf);
			unlink(tname);
			return(-1);
		}
		n = write(fr, buf, s);
		if(n != s) {
			close (tf);
			unlink(tname);
			return(-1);
		}
		new_size -= s;
	}

	/*
	 * Close and remove the temporary file.  It's no longer needed.
	 */
	close(tf);
	unlink(tname);
	return(0);
}
-- 
	--steve kramer
	{allegra,genrad,ihnp4,utzoo,philabs,uw-beaver}!linus!axiom!smk	(UUCP)
	linus!axiom!smk@mitre-bedford					(MIL)