merge with 1.8.1d
[coreutils.git] / lib / ftruncate.c
blob17d263d512144e9df9d97ae8aa497134f4551690
1 /* ftruncate emulations that work on some System V's.
2 This file is in the public domain. */
4 #include <sys/types.h>
5 #include <fcntl.h>
7 #ifdef F_CHSIZE
8 int
9 ftruncate (fd, length)
10 int fd;
11 off_t length;
13 return fcntl (fd, F_CHSIZE, length);
15 #else
16 #ifdef F_FREESP
17 /* The following function was written by
18 kucharsk@Solbourne.com (William Kucharski) */
20 #include <sys/stat.h>
21 #include <errno.h>
22 #include <unistd.h>
24 int
25 ftruncate (fd, length)
26 int fd;
27 off_t length;
29 struct flock fl;
30 struct stat filebuf;
32 if (fstat (fd, &filebuf) < 0)
33 return -1;
35 if (filebuf.st_size < length)
37 /* Extend file length. */
38 if (lseek (fd, (length - 1), SEEK_SET) < 0)
39 return -1;
41 /* Write a "0" byte. */
42 if (write (fd, "", 1) != 1)
43 return -1;
45 else
47 /* Truncate length. */
48 fl.l_whence = 0;
49 fl.l_len = 0;
50 fl.l_start = length;
51 fl.l_type = F_WRLCK; /* Write lock on file space. */
53 /* This relies on the UNDOCUMENTED F_FREESP argument to
54 fcntl, which truncates the file so that it ends at the
55 position indicated by fl.l_start.
56 Will minor miracles never cease? */
57 if (fcntl (fd, F_FREESP, &fl) < 0)
58 return -1;
61 return 0;
63 #else
64 int
65 ftruncate (fd, length)
66 int fd;
67 off_t length;
69 return chsize (fd, length);
71 #endif
72 #endif