Subject: truncate/ftruncate broken
To: None <amiga@NetBSD.ORG>
From: Alexander Elkins <aoe@swttools.fc.hp.com>
List: amiga
Date: 10/08/1994 15:01:11
I was about to post this as a defect against truncate()/ftruncate().  Now I'm
doing so just to warn everyone about this behavior.
I got a "File too large" error when I tried to use truncate() or ftruncate()
and didn't #include <unistd.h>.  Until I used the gcc -Warn option gcc didn't
hint at the problem (missing prototypes).
The target file length was changed to a multiple of 8192 bytes in length rather
than the specified length as well.  Stats and example program follow.

 - Alexander Elkins [aoe@fc.hp.com]
===============================================================================
-> uname -a
NetBSD myname.my.domain 1.0_BETA NetBSD 1.0_BETA (GENERIC) #0: Sat Aug 13 05:39:41 EDT 1994     chopps@coffee.gnu.ai.mit.edu:/local/src/sys/arch/amiga/compile/GENERIC amiga
-> gcc -v
gcc version 2.4.5
-> gcc -DBROKEN -DDEBUG -Wall -o ~/bin/truncate -O2 ~/src/truncate.c
/tmp/truncate.c: In function `main':
/tmp/truncate.c:24: warning: implicit declaration of function `truncate'
/tmp/truncate.c:35: warning: implicit declaration of function `ftruncate'
/tmp/truncate.c:39: warning: implicit declaration of function `close'
-> grep truncate /usr/include/unistd.h
int      ftruncate __P((int, off_t));
int      truncate __P((const char *, off_t));
---------------------------->8----- cut here -----8<-------------------------
#include <stdlib.h>
#include <stdio.h>
#ifndef BROKEN
#include <unistd.h>
#endif /* BROKEN */
#ifdef DEBUG
#include <fcntl.h>
#endif /* DEBUG */

int main(int argc, char **argv, char **envp)
{
	unsigned long length;
	char *ptr;

	if (argc != 3 || ((length = strtoul(argv[1], &ptr, 0)), *ptr != '\0') ||
		ptr == argv[1])
	{
		(void) fprintf(stderr, "Usage: %s length file\n", argv[0]);
		return 1;
	}
#ifdef DEBUG
	printf("length = %lu\n", length);
#endif /* DEBUG */
	if (truncate(argv[2], length) != 0)
	{
#ifdef DEBUG
		int fildes;
#endif /* DEBUG */
		(void) fprintf(stderr, "%s: %s", argv[0], argv[2]);
		perror(": Cannot truncate");
#ifdef DEBUG
		if ((fildes = open(argv[2], O_RDWR)) >= 0)
		{
			if (ftruncate(fildes, length) != 0)
			{
				perror("Cannot ftruncate");
			}       
			close(fildes);
		}
		else
		{
			perror("Cannot open");
		}
#endif /* DEBUG */
		return 2;
	}
    return 0;
} /* main */