blob: c5a616007c1b1cfbef587779b86dd0a0b13f323b [file] [log] [blame]
yuezonghe824eb0c2024-06-27 02:32:26 -07001/*
2 * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
3 *
4 * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
5 *
6 * ftruncate64 syscall. Copes with 64 bit and 32 bit machines
7 * and on 32 bit machines this sends things into the kernel as
8 * two 32-bit arguments (high and low 32 bits of length) that
9 * are ordered based on endianess. It turns out endian.h has
10 * just the macro we need to order things, __LONG_LONG_PAIR.
11 */
12
13#include <features.h>
14
15#ifdef __UCLIBC_HAS_LFS__
16
17# include <unistd.h>
18# include <errno.h>
19# include <endian.h>
20# include <stdint.h>
21# include <sys/types.h>
22# include <sys/syscall.h>
23
24
25# ifdef __NR_ftruncate64
26
27# if __WORDSIZE == 64
28
29/* For a 64 bit machine, life is simple... */
30_syscall2(int, ftruncate64, int, fd, __off64_t, length)
31
32# elif __WORDSIZE == 32
33
34/* The exported ftruncate64 function. */
35int ftruncate64 (int fd, __off64_t length)
36{
37 uint32_t low = length & 0xffffffff;
38 uint32_t high = length >> 32;
39# if defined(__UCLIBC_TRUNCATE64_HAS_4_ARGS__)
40 return INLINE_SYSCALL(ftruncate64,
41 4, fd, 0, __LONG_LONG_PAIR (high, low));
42# else
43 return INLINE_SYSCALL(ftruncate64, 3, fd,
44 __LONG_LONG_PAIR (high, low));
45# endif
46}
47
48# else /* __WORDSIZE */
49# error Your machine is not 64 bit or 32 bit, I am dazed and confused.
50# endif /* __WORDSIZE */
51
52# else /* __NR_ftruncate64 */
53
54
55int ftruncate64 (int fd, __off64_t length)
56{
57 __off_t x = (__off_t) length;
58
59 if (x == length) {
60 return ftruncate(fd, x);
61 }
62
63 __set_errno((x < 0) ? EINVAL : EFBIG);
64
65 return -1;
66}
67
68# endif /* __NR_ftruncate64 */
69libc_hidden_def(ftruncate64)
70
71#endif /* __UCLIBC_HAS_LFS__ */