From rick@softport.nyc.ny.us  Wed Mar 12 12:01:33 1997
Received: from news2.panix.com (news2.panix.com [166.84.0.221])
          by freefall.freebsd.org (8.8.5/8.8.5) with SMTP id MAA08192
          for <FreeBSD-gnats-submit@freebsd.org>; Wed, 12 Mar 1997 12:01:15 -0800 (PST)
Received: (from uucp@localhost) by news2.panix.com (8.6.10/8.6.12+PanixU1.1) with UUCP id PAA27479 for FreeBSD-gnats-submit@freebsd.org; Wed, 12 Mar 1997 15:01:08 -0500
Received: (from rick@localhost)
	by softport.nyc.ny.us (8.8.5/8.8.5) id OAA16037;
	Wed, 12 Mar 1997 14:58:08 -0500 (EST)
Message-Id: <199703121958.OAA16037@softport.nyc.ny.us>
Date: Wed, 12 Mar 1997 14:58:08 -0500 (EST)
From: Rick Ace <rick@softport.nyc.ny.us>
To: FreeBSD-gnats-submit@freebsd.org
Subject: ftruncate() problem in FreeBSD 2.1.7-RELEASE i386

>Number:         2966
>Category:       kern
>Synopsis:       ftruncate() fails unexpectedly
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          closed
>Quarter:
>Keywords:
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed Mar 12 12:10:01 PST 1997
>Closed-Date:    Thu Mar 13 00:13:00 MET 1997
>Last-Modified:  Wed Mar 12 21:10:01 PST 1997
>Originator:     Rick Ace
>Release:        FreeBSD 2.1.7-RELEASE i386
>Organization:
Softport Systems Inc.  New York, NY  10016
>Environment:

	486/50
	nonprivileged user application

>Description:

	ftruncate() fails with error (EINVAL) when called to truncate
	a file whose descriptor is open for read and write.
	It should succeed.

>How-To-Repeat:

/*
 * demonstrate ftruncate() bug in freebsd
 * (this same code runs without problems on both Solaris 2.5 and HP-UX 10)
 */

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

static char tmp_path[] = "/tmp/tbug";

static void try_truncate();

int main()
{
	int fd;

	(void) unlink(tmp_path);

	/* create new, empty file open for read/write */
	if ((fd = open(tmp_path, O_RDWR | O_CREAT, 0600)) < 0) {
		perror("open");
		return 1;
	}

	try_truncate(fd);	/* try on empty file */

	printf("write() returns %d\n", write(fd, "xxx", 3));
	try_truncate(fd);	/* try on non-empty file */

	(void) unlink(tmp_path);
	return 0;
}

static void try_truncate(fd)
	int fd;
{
	int e;

	e = ftruncate(fd, 0);
	if (e < 0) {
		fprintf(stderr, "[errno=%d] ", errno);
		perror("ftruncate");
	}
	else {
		fprintf(stderr, "ok\n");
	}
}

>Fix:
	
	None reported.

>Release-Note:
>Audit-Trail:
State-Changed-From-To: open->closed 
State-Changed-By: joerg 
State-Changed-When: Thu Mar 13 00:13:00 MET 1997 
State-Changed-Why:  
ftruncate() fails expectedly. :-)  Pilot error.  Thou shalt declare functions, 
and/or cast arguments if they are of other size than int. 


From: j@uriah.heep.sax.de (J Wunsch)
To: rick@softport.nyc.ny.us (Rick Ace)
Cc: FreeBSD-gnats-submit@FreeBSD.ORG
Subject: Re: kern/2966: ftruncate() problem in FreeBSD 2.1.7-RELEASE i386
Date: Wed, 12 Mar 1997 23:58:26 +0100

 As Rick Ace wrote:
 
 > 	ftruncate() fails with error (EINVAL) when called to truncate
 > 	a file whose descriptor is open for read and write.
 > 	It should succeed.
 
 j@uriah 589% cc foo.c 
 j@uriah 590% ./a.out 
 ok
 write() returns 3
 ok
 
 Rule #1: Thou shalt declare all your functions.
 
 ftruncate() takes an argument of type off_t.  If you fail to declare
 this function (and fail to cast the argument), you get what you
 deserve.
 
 #include <unistd.h>
 
 -- 
 cheers, J"org
 
 joerg_wunsch@uriah.heep.sax.de -- http://www.sax.de/~joerg/ -- NIC: JW11-RIPE
 Never trust an operating system you don't have sources for. ;-)

From: Stephen McKay <syssgm@devetir.qld.gov.au>
To: j@uriah.heep.sax.de (J Wunsch)
Cc: freebsd-gnats-submit@freebsd.org, syssgm@devetir.qld.gov.au
Subject: Re: kern/2966: ftruncate() problem in FreeBSD 2.1.7-RELEASE i386
Date: Thu, 13 Mar 1997 14:56:45 +1000 (EST)

 j@uriah.heep.sax.de (J Wunsch) wrote:
 
 > [Rick Ace misuses ftruncate()]
 >
 > Rule #1: Thou shalt declare all your functions.
 > 
 > ftruncate() takes an argument of type off_t.  If you fail to declare
 > this function (and fail to cast the argument), you get what you
 > deserve.
 > 
 > #include <unistd.h>
 
 Is it time to special-case truncate() and ftruncate() in <sys/types.h>
 like lseek()?  Ugly or not, it should reduce surprises.  These 3 should
 be the only special ones.  mmap() uses off_t, but you can't get by without
 <sys/mman.h>, and that declares mmap() correctly.
 
 An other option is to include clever macro stuff in <sys/types.h> so that
 use of lseek, truncate, and ftruncate is impossible unless <unistd.h> is
 also included.  Actually, I'm just being silly here :-) though it can be
 done this way:
 
 In <sys/types.h>
 
     #ifndef _UNISTD_H_
     #define truncate read_thine_C_book_novice
     #endif
 
 In <unistd.h>
 
     #undef truncate
     int truncate __P((const char *, off_t));
 
 :-) :-)
 
 Stephen.
>Unformatted:
