1 /*! \file
2  * \brief
3  * ftruncate - set file size, BSD Style
4  *
5  * shortens or enlarges the file as neeeded
6  * uses some undocumented locking call. It is known to work on SCO unix,
7  * other vendors should try.
8  * The #error directive prevents unsupported OSes
9  */
10 
11 #include "port_before.h"
12 
13 #if defined(M_UNIX)
14 #define OWN_FTRUNCATE
15 #include <stdio.h>
16 #ifdef _XOPEN_SOURCE
17 #undef _XOPEN_SOURCE
18 #endif
19 #ifdef _POSIX_SOURCE
20 #undef _POSIX_SOURCE
21 #endif
22 
23 #include <fcntl.h>
24 
25 #include "port_after.h"
26 
27 int
__ftruncate(int fd,long wantsize)28 __ftruncate(int fd, long wantsize) {
29 	long cursize;
30 
31 	/* determine current file size */
32 	if ((cursize = lseek(fd, 0L, 2)) == -1)
33 		return (-1);
34 
35 	/* maybe lengthen... */
36 	if (cursize < wantsize) {
37 		if (lseek(fd, wantsize - 1, 0) == -1 ||
38 		    write(fd, "", 1) == -1) {
39 			return (-1);
40 		}
41 		return (0);
42 	}
43 
44 	/* maybe shorten... */
45 	if (wantsize < cursize) {
46 		struct flock fl;
47 
48 		fl.l_whence = 0;
49 		fl.l_len = 0;
50 		fl.l_start = wantsize;
51 		fl.l_type = F_WRLCK;
52 		return (fcntl(fd, F_FREESP, &fl));
53 	}
54 	return (0);
55 }
56 #endif
57 
58 #ifndef OWN_FTRUNCATE
59 int __bindcompat_ftruncate;
60 #endif
61