.
[coreutils.git] / lib / ftruncate.c
blob1272ee74f6dd928170e08261c96e17c70cfdc69c
1 /* ftruncate emulations that work on some System V's.
2 This file is in the public domain. */
4 #ifdef HAVE_CONFIG_H
5 #include <config.h>
6 #endif
8 #include <sys/types.h>
9 #include <fcntl.h>
11 #ifdef F_CHSIZE
13 int
14 ftruncate (fd, length)
15 int fd;
16 off_t length;
18 return fcntl (fd, F_CHSIZE, length);
21 #else /* not F_CHSIZE */
22 #ifdef F_FREESP
24 /* By William Kucharski <kucharsk@netcom.com>. */
26 #include <sys/stat.h>
27 #include <errno.h>
28 #ifdef HAVE_UNISTD_H
29 #include <unistd.h>
30 #endif
32 int
33 ftruncate (fd, length)
34 int fd;
35 off_t length;
37 struct flock fl;
38 struct stat filebuf;
40 if (fstat (fd, &filebuf) < 0)
41 return -1;
43 if (filebuf.st_size < length)
45 /* Extend file length. */
46 if (lseek (fd, (length - 1), SEEK_SET) < 0)
47 return -1;
49 /* Write a "0" byte. */
50 if (write (fd, "", 1) != 1)
51 return -1;
53 else
56 /* Truncate length. */
58 fl.l_whence = 0;
59 fl.l_len = 0;
60 fl.l_start = length;
61 fl.l_type = F_WRLCK; /* write lock on file space */
63 /* This relies on the *undocumented* F_FREESP argument to fcntl,
64 which truncates the file so that it ends at the position
65 indicated by fl.l_start. Will minor miracles never cease? */
67 if (fcntl (fd, F_FREESP, &fl) < 0)
68 return -1;
71 return 0;
74 #else /* not F_CHSIZE nor F_FREESP */
75 #ifdef HAVE_CHSIZE
77 int
78 ftruncate (fd, length)
79 int fd;
80 off_t length;
82 return chsize (fd, length);
85 #else /* not F_CHSIZE nor F_FREESP nor HAVE_CHSIZE */
87 #include <errno.h>
88 #ifndef errno
89 extern int errno;
90 #endif
92 int
93 ftruncate (fd, length)
94 int fd;
95 off_t length;
97 errno = EIO;
98 return -1;
101 #endif /* not HAVE_CHSIZE */
102 #endif /* not F_FREESP */
103 #endif /* not F_CHSIZE */