1*1e72d8d2Sderaadt /* ftruncate emulations that work on some System V's.
2*1e72d8d2Sderaadt This file is in the public domain. */
3*1e72d8d2Sderaadt
4*1e72d8d2Sderaadt #ifdef HAVE_CONFIG_H
5*1e72d8d2Sderaadt #include "config.h"
6*1e72d8d2Sderaadt #endif
7*1e72d8d2Sderaadt
8*1e72d8d2Sderaadt #include <sys/types.h>
9*1e72d8d2Sderaadt #include <fcntl.h>
10*1e72d8d2Sderaadt
11*1e72d8d2Sderaadt #ifdef F_CHSIZE
12*1e72d8d2Sderaadt int
ftruncate(fd,length)13*1e72d8d2Sderaadt ftruncate (fd, length)
14*1e72d8d2Sderaadt int fd;
15*1e72d8d2Sderaadt off_t length;
16*1e72d8d2Sderaadt {
17*1e72d8d2Sderaadt return fcntl (fd, F_CHSIZE, length);
18*1e72d8d2Sderaadt }
19*1e72d8d2Sderaadt #else
20*1e72d8d2Sderaadt #ifdef F_FREESP
21*1e72d8d2Sderaadt /* The following function was written by
22*1e72d8d2Sderaadt kucharsk@Solbourne.com (William Kucharski) */
23*1e72d8d2Sderaadt
24*1e72d8d2Sderaadt #include <sys/stat.h>
25*1e72d8d2Sderaadt #include <errno.h>
26*1e72d8d2Sderaadt #include <unistd.h>
27*1e72d8d2Sderaadt
28*1e72d8d2Sderaadt int
ftruncate(fd,length)29*1e72d8d2Sderaadt ftruncate (fd, length)
30*1e72d8d2Sderaadt int fd;
31*1e72d8d2Sderaadt off_t length;
32*1e72d8d2Sderaadt {
33*1e72d8d2Sderaadt struct flock fl;
34*1e72d8d2Sderaadt struct stat filebuf;
35*1e72d8d2Sderaadt
36*1e72d8d2Sderaadt if (fstat (fd, &filebuf) < 0)
37*1e72d8d2Sderaadt return -1;
38*1e72d8d2Sderaadt
39*1e72d8d2Sderaadt if (filebuf.st_size < length)
40*1e72d8d2Sderaadt {
41*1e72d8d2Sderaadt /* Extend file length. */
42*1e72d8d2Sderaadt if (lseek (fd, (length - 1), SEEK_SET) < 0)
43*1e72d8d2Sderaadt return -1;
44*1e72d8d2Sderaadt
45*1e72d8d2Sderaadt /* Write a "0" byte. */
46*1e72d8d2Sderaadt if (write (fd, "", 1) != 1)
47*1e72d8d2Sderaadt return -1;
48*1e72d8d2Sderaadt }
49*1e72d8d2Sderaadt else
50*1e72d8d2Sderaadt {
51*1e72d8d2Sderaadt /* Truncate length. */
52*1e72d8d2Sderaadt fl.l_whence = 0;
53*1e72d8d2Sderaadt fl.l_len = 0;
54*1e72d8d2Sderaadt fl.l_start = length;
55*1e72d8d2Sderaadt fl.l_type = F_WRLCK; /* Write lock on file space. */
56*1e72d8d2Sderaadt
57*1e72d8d2Sderaadt /* This relies on the UNDOCUMENTED F_FREESP argument to
58*1e72d8d2Sderaadt fcntl, which truncates the file so that it ends at the
59*1e72d8d2Sderaadt position indicated by fl.l_start.
60*1e72d8d2Sderaadt Will minor miracles never cease? */
61*1e72d8d2Sderaadt if (fcntl (fd, F_FREESP, &fl) < 0)
62*1e72d8d2Sderaadt return -1;
63*1e72d8d2Sderaadt }
64*1e72d8d2Sderaadt
65*1e72d8d2Sderaadt return 0;
66*1e72d8d2Sderaadt }
67*1e72d8d2Sderaadt #else
68*1e72d8d2Sderaadt int
ftruncate(fd,length)69*1e72d8d2Sderaadt ftruncate (fd, length)
70*1e72d8d2Sderaadt int fd;
71*1e72d8d2Sderaadt off_t length;
72*1e72d8d2Sderaadt {
73*1e72d8d2Sderaadt return chsize (fd, length);
74*1e72d8d2Sderaadt }
75*1e72d8d2Sderaadt #endif
76*1e72d8d2Sderaadt #endif
77