[comp.sources.wanted] ftruncate

jos@idca.tds.PHILIPS.nl (Jos Vos) (07/07/89)

I need the ftruncate(2) function from BSD4.3 UNIX on System V.3.2.
For non-BSD-manual-owners, here's the description of ftruncate(2):

*	ftruncate (fd, length)
*	int fd;
*	long length;
*
*   Ftruncate causes the file referenced by fd (a file descriptor of an
*   file open for writing) to be truncated to at most length bytes in size.
*   If the file previously was larger than the size, the extra data is lost.

Hint: I do *not* know the filename of the open file, of course :-)

Because I don't even know if there exists a solution, also a *proof* :-)
that no solution exists will be very helpfull to me (than I can start
rewriting the code around ftruncate() in my application :-( ).

-- 
-- ######   Jos Vos   ######   Internet   jos@idca.tds.philips.nl   ######
-- ######             ######   UUCP         ...!mcvax!philapd!jos   ######

kucharsk@uts.amdahl.com (William Kucharski) (07/08/89)

In article <1132@ssp15.idca.tds.philips.nl> jos@idca.tds.PHILIPS.nl (Jos Vos) writes:
 >I need the ftruncate(2) function from BSD4.3 UNIX on System V.3.2.
 >For non-BSD-manual-owners, here's the description of ftruncate(2)...

I can see that this one is going to make it into the "frequently asked
question" section...

========[Cut Here]========

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

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 = 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.
                 *
                 * Will minor miracles never cease?
                 */

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

        }

        return(0);
}

-- 
					William Kucharski

ARPA: kucharsk@uts.amdahl.com
UUCP: ...!{ames,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.

chip@ateng.com (Chip Salzenberg) (07/11/89)

According to jos@idca.tds.PHILIPS.nl (Jos Vos):
>I need the ftruncate(2) function from BSD4.3 UNIX on System V.3.2.

Use the Xenix-derived chsize() function; it does the same thing.
-- 
You may redistribute this article only to those who may freely do likewise.
Chip Salzenberg         |       <chip@ateng.com> or <uunet!ateng!chip>
A T Engineering         |       Me?  Speak for my company?  Surely you jest!

pat@rwing.UUCP (Pat Myrto) (07/14/89)

In article <02KJ02SJ3cms01@amdahl.uts.amdahl.com>, kucharsk@uts.amdahl.com (William Kucharski) writes:
< 
<  ... [ Most of posted source deleted ] ...
<                 /*
<                  * 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.
<                  *
<                  * Will minor miracles never cease?
<                  */
< 
< 		if (fcntl(fd, F_FREESP, &fl) < 0)
< 			return(-1);

This ioctl() call looks like something that would be interesting to
try, however, the value of F_FREESP is not to be found in *ANY* of the
includes on my site - could someome perhaps indicate what numerical
value F_FREESP is supposed to be on USG type systems?
Thanks...

-- 
pat@rwing     ...!nwnexus!mltco!camco!happym!\      (Pat Myrto),  Seattle, WA
                          ...!uunet!pilchuck!rwing!pat
                  ...!uw-beaver!sumax!polari!/
WISDOM:    "Travelling unarmed is like boating without a life jacket" 

guy@auspex.auspex.com (Guy Harris) (07/18/89)

>This ioctl() call looks like something that would be interesting to
>try, however, the value of F_FREESP is not to be found in *ANY* of the
>includes on my site - could someome perhaps indicate what numerical
>value F_FREESP is supposed to be on USG type systems?

The value that's defined in <fcntl.h>.  If it's not defined there, your
system may not *have* such an "fcntl()" call (not "ioctl()") - it first
appeared in some flavor of S5R3.1, isn't in S5R3 (or S5R2 or earlier),
and in S5R3.1 the code that implements it has the comments:

/*
 * This is an experimental facility for SVR3.1 and WILL be changed
 * in the next release.  ...
 *

	...

 * Bug:  unused bytes in the last retained block are not cleared.
 * This may result in a "hole" in the file that does not read as zeroes.
 */

so beware - if it's not documented, it may be because it's not
considered "done" and may not be supported or even work correctly in all
cases....