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