1 //===-- Linux implementation of lseek -------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef LLVM_LIBC_SRC___SUPPORT_FILE_LINUX_LSEEKIMPL_H 10 #define LLVM_LIBC_SRC___SUPPORT_FILE_LINUX_LSEEKIMPL_H 11 12 #include "hdr/types/off_t.h" 13 #include "src/__support/OSUtil/syscall.h" // For internal syscall function. 14 #include "src/__support/common.h" 15 #include "src/__support/error_or.h" 16 #include "src/__support/macros/config.h" 17 #include "src/errno/libc_errno.h" 18 19 #include <stdint.h> // For uint64_t. 20 #include <sys/syscall.h> // For syscall numbers. 21 22 namespace LIBC_NAMESPACE_DECL { 23 namespace internal { 24 25 LIBC_INLINE ErrorOr<off_t> lseekimpl(int fd, off_t offset, int whence) { 26 off_t result; 27 #ifdef SYS_lseek 28 int ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_lseek, fd, offset, whence); 29 result = ret; 30 #elif defined(SYS_llseek) || defined(SYS__llseek) 31 static_assert(sizeof(size_t) == 4, "size_t must be 32 bits."); 32 #ifdef SYS_llseek 33 constexpr long LLSEEK_SYSCALL_NO = SYS_llseek; 34 #elif defined(SYS__llseek) 35 constexpr long LLSEEK_SYSCALL_NO = SYS__llseek; 36 #endif 37 off_t offset_64 = offset; 38 int ret = LIBC_NAMESPACE::syscall_impl<int>( 39 LLSEEK_SYSCALL_NO, fd, offset_64 >> 32, offset_64, &result, whence); 40 #else 41 #error "lseek, llseek and _llseek syscalls not available." 42 #endif 43 if (ret < 0) 44 return Error(-ret); 45 return result; 46 } 47 48 } // namespace internal 49 } // namespace LIBC_NAMESPACE_DECL 50 51 #endif // LLVM_LIBC_SRC___SUPPORT_FILE_LINUX_LSEEKIMPL_H 52