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