Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP
Posting-Version: notesnews 0.1 (unido 12/05/84); site unido.UUCP
Path: utzoo!watmath!clyde!burl!ulysses!allegra!mit-eddie!think!harvard!seismo!mcvax!unido!georg
From: georg@unido.UUCP
Newsgroups: net.sources
Subject: Re: ftruncate library routine for non 4.
Message-ID: 
Date: Tue, 2-Jul-85 21:21:00 EDT
Article-I.D.: unido.nf11800002
Posted: Tue Jul  2 21:21:00 1985
Date-Received: Sat, 6-Jul-85 10:13:14 EDT
References: <53@axiom.UUCP>
Sender: notes@unido.UUCP
Lines: 121
Nf-ID: #R:axiom:-5300:unido:11800002:000:2553
Nf-From: unido!georg    Jul  2 23:21:00 1985

I tried to translate the routine ftruncate. The compiler said `name'
is undeclared. I took `name' as third parameter renamed the routine
to ftruncateName and now it works.

Georg Heeg, Informatik V, Univ. Dortmund, West-Germany

georg@unido.uucp

/***** unido:net.sources / axiom!smk /  2:24 am  Jun 23, 1985*/
/*Subject: ftruncate library routine for non 4.2bsd sites*/

#include 
#include 
#include 

/*
 * 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.
 *
 * Third Parameter added by Georg Heeg, Univ. Dortmund 85-07-02
 *
 */
ftruncateName(fr, size, name)
	int fr;
	long size;
	char *name;
{
	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);
}