117721Speter/* ftruncate emulations that work on some System V's.
217721Speter   This file is in the public domain. */
317721Speter
417721Speter#ifdef HAVE_CONFIG_H
517721Speter#include "config.h"
617721Speter#endif
717721Speter
817721Speter#include <sys/types.h>
917721Speter#include <fcntl.h>
1017721Speter
1117721Speter#ifdef F_CHSIZE
1217721Speterint
1317721Speterftruncate (fd, length)
1417721Speter     int fd;
1517721Speter     off_t length;
1617721Speter{
1717721Speter  return fcntl (fd, F_CHSIZE, length);
1817721Speter}
1917721Speter#else
2017721Speter#ifdef F_FREESP
2117721Speter/* The following function was written by
2217721Speter   kucharsk@Solbourne.com (William Kucharski) */
2317721Speter
2417721Speter#include <sys/stat.h>
2517721Speter#include <errno.h>
2617721Speter#include <unistd.h>
2717721Speter
2817721Speterint
2917721Speterftruncate (fd, length)
3017721Speter     int fd;
3117721Speter     off_t length;
3217721Speter{
3317721Speter  struct flock fl;
3417721Speter  struct stat filebuf;
3517721Speter
3617721Speter  if (fstat (fd, &filebuf) < 0)
3717721Speter    return -1;
3817721Speter
3917721Speter  if (filebuf.st_size < length)
4017721Speter    {
4117721Speter      /* Extend file length. */
4217721Speter      if (lseek (fd, (length - 1), SEEK_SET) < 0)
4317721Speter	return -1;
4417721Speter
4517721Speter      /* Write a "0" byte. */
4617721Speter      if (write (fd, "", 1) != 1)
4717721Speter	return -1;
4817721Speter    }
4917721Speter  else
5017721Speter    {
5117721Speter      /* Truncate length. */
5217721Speter      fl.l_whence = 0;
5317721Speter      fl.l_len = 0;
5417721Speter      fl.l_start = length;
5517721Speter      fl.l_type = F_WRLCK;	/* Write lock on file space. */
5617721Speter
5717721Speter      /* This relies on the UNDOCUMENTED F_FREESP argument to
5817721Speter	 fcntl, which truncates the file so that it ends at the
5917721Speter	 position indicated by fl.l_start.
6017721Speter	 Will minor miracles never cease? */
6117721Speter      if (fcntl (fd, F_FREESP, &fl) < 0)
6217721Speter	return -1;
6317721Speter    }
6417721Speter
6517721Speter  return 0;
6617721Speter}
6717721Speter#else
6817721Speterint
6917721Speterftruncate (fd, length)
7017721Speter     int fd;
7117721Speter     off_t length;
7217721Speter{
7317721Speter  return chsize (fd, length);
7417721Speter}
7517721Speter#endif
7617721Speter#endif
77