start service tasks separately in-case platforms need to perform additional set-up...
[AROS.git] / compiler / posixc / ftruncate.c
blob5018936f21cb71714883a36974a48d5a75342d7e
1 /*
2 Copyright © 1995-2012, The AROS Development Team. All rights reserved.
3 $Id$
5 POSIX.1-2008 function ftruncate().
6 */
8 #include <dos/dos.h>
9 #include <proto/dos.h>
10 #include <fcntl.h>
11 #include <errno.h>
12 #include "__fdesc.h"
14 /*****************************************************************************
16 NAME */
17 #include <unistd.h>
19 int ftruncate (
21 /* SYNOPSIS */
22 int fd,
23 off_t length)
25 /* FUNCTION
26 Truncate a file to a specified length
28 INPUTS
29 fd - the descriptor of the file being truncated.
30 The file must be open for writing
31 lenght - The file will have at most this size
33 RESULT
34 0 on success or -1 on errorr.
36 NOTES
37 If the file previously was larger than this size, the extra data
38 is lost. If the file previously was shorter, it is
39 unspecified whether the file is left unchanged or is
40 extended. In the latter case the extended part reads as
41 zero bytes.
44 EXAMPLE
46 BUGS
48 SEE ALSO
49 open(), truncate()
51 INTERNALS
53 ******************************************************************************/
55 ULONG oldpos;
56 size_t size;
58 fdesc *fdesc = __getfdesc(fd);
60 if (!fdesc)
62 errno = EBADF;
63 return -1;
66 if(fdesc->fcb->privflags & _FCB_ISDIR)
68 errno = EISDIR;
69 return -1;
72 if (!(fdesc->fcb->flags & (O_WRONLY|O_RDWR)))
74 errno = EINVAL;
75 return -1;
78 oldpos = Seek(fdesc->fcb->handle, 0, OFFSET_END);
79 size = Seek(fdesc->fcb->handle, 0, OFFSET_CURRENT);
80 Seek(fdesc->fcb->handle, oldpos, OFFSET_BEGINNING);
82 if ((length = SetFileSize(fdesc->fcb->handle, length, OFFSET_BEGINNING)) == -1)
84 errno = __stdc_ioerr2errno(IoErr());
85 return -1;
87 else
88 if (size < length)
90 char buf[16]={0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
92 length -= size;
94 oldpos = Seek(fdesc->fcb->handle, size, OFFSET_BEGINNING);
96 while (length >= 16)
98 FWrite(fdesc->fcb->handle, buf, 16, 1);
99 length -= 16;
101 if (length)
102 FWrite(fdesc->fcb->handle, buf, length, 1);
104 Flush(fdesc->fcb->handle);
105 Seek(fdesc->fcb->handle, oldpos, OFFSET_BEGINNING);
108 return 0;