1 | /* ftruncate emulations that work on some System V's.
|
---|
2 | This file is in the public domain. */
|
---|
3 |
|
---|
4 | #ifdef HAVE_CONFIG_H
|
---|
5 | # ifdef __WIN32__ /* [RPAP - Feb 97: WIN32 Port] */
|
---|
6 | # include <win32cfg.h>
|
---|
7 | # else
|
---|
8 | # include <sysfuncs.h>
|
---|
9 | # endif
|
---|
10 | #endif
|
---|
11 |
|
---|
12 | #include <sys/types.h>
|
---|
13 | #include <fcntl.h>
|
---|
14 |
|
---|
15 | #ifdef F_CHSIZE
|
---|
16 |
|
---|
17 | int
|
---|
18 | ftruncate (int fd, off_t length)
|
---|
19 | {
|
---|
20 | return fcntl (fd, F_CHSIZE, length);
|
---|
21 | }
|
---|
22 |
|
---|
23 | #else /* not F_CHSIZE */
|
---|
24 | #ifdef F_FREESP
|
---|
25 |
|
---|
26 | /* By William Kucharski <[email protected]>. */
|
---|
27 |
|
---|
28 | #include <sys/stat.h>
|
---|
29 | #include <errno.h>
|
---|
30 | #ifdef HAVE_UNISTD_H
|
---|
31 | #include <unistd.h>
|
---|
32 | #endif
|
---|
33 |
|
---|
34 | int
|
---|
35 | ftruncate (int fd, off_t length)
|
---|
36 | {
|
---|
37 | struct flock fl;
|
---|
38 | struct stat filebuf;
|
---|
39 |
|
---|
40 | if (fstat (fd, &filebuf) < 0)
|
---|
41 | return -1;
|
---|
42 |
|
---|
43 | if (filebuf.st_size < length)
|
---|
44 | {
|
---|
45 | /* Extend file length. */
|
---|
46 | if (lseek (fd, (length - 1), SEEK_SET) < 0)
|
---|
47 | return -1;
|
---|
48 |
|
---|
49 | /* Write a "0" byte. */
|
---|
50 | if (write (fd, "", 1) != 1)
|
---|
51 | return -1;
|
---|
52 | }
|
---|
53 | else
|
---|
54 | {
|
---|
55 |
|
---|
56 | /* Truncate length. */
|
---|
57 |
|
---|
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 */
|
---|
62 |
|
---|
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? */
|
---|
66 |
|
---|
67 | if (fcntl (fd, F_FREESP, &fl) < 0)
|
---|
68 | return -1;
|
---|
69 | }
|
---|
70 |
|
---|
71 | return 0;
|
---|
72 | }
|
---|
73 |
|
---|
74 | #else /* not F_CHSIZE nor F_FREESP */
|
---|
75 | #ifdef HAVE_CHSIZE
|
---|
76 |
|
---|
77 | int
|
---|
78 | ftruncate (int fd, off_t length)
|
---|
79 | {
|
---|
80 | return chsize (fd, length);
|
---|
81 | }
|
---|
82 |
|
---|
83 | #else /* not F_CHSIZE nor F_FREESP nor HAVE_CHSIZE */
|
---|
84 |
|
---|
85 | #include <errno.h>
|
---|
86 | #ifndef errno
|
---|
87 | extern int errno;
|
---|
88 | #endif
|
---|
89 |
|
---|
90 | int
|
---|
91 | ftruncate (int fd, off_t length)
|
---|
92 | {
|
---|
93 | errno = EIO;
|
---|
94 | return -1;
|
---|
95 | }
|
---|
96 |
|
---|
97 | #endif /* not HAVE_CHSIZE */
|
---|
98 | #endif /* not F_FREESP */
|
---|
99 | #endif /* not F_CHSIZE */
|
---|