16e675fbaSSiva Chandra Reddy //===-- Linux implementation of pwrite ------------------------------------===// 26e675fbaSSiva Chandra Reddy // 36e675fbaSSiva Chandra Reddy // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 46e675fbaSSiva Chandra Reddy // See https://llvm.org/LICENSE.txt for license information. 56e675fbaSSiva Chandra Reddy // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 66e675fbaSSiva Chandra Reddy // 76e675fbaSSiva Chandra Reddy //===----------------------------------------------------------------------===// 86e675fbaSSiva Chandra Reddy 96e675fbaSSiva Chandra Reddy #include "src/unistd/pwrite.h" 106e675fbaSSiva Chandra Reddy 116e675fbaSSiva Chandra Reddy #include "src/__support/OSUtil/syscall.h" // For internal syscall function. 126e675fbaSSiva Chandra Reddy #include "src/__support/common.h" 136e675fbaSSiva Chandra Reddy 14*5ff3ff33SPetr Hosek #include "src/__support/macros/config.h" 15803437dbSMichael Jones #include "src/errno/libc_errno.h" 16c9783d2bSMikhail R. Gadelha #include <stdint.h> // For uint64_t. 176e675fbaSSiva Chandra Reddy #include <sys/syscall.h> // For syscall numbers. 186e675fbaSSiva Chandra Reddy 19*5ff3ff33SPetr Hosek namespace LIBC_NAMESPACE_DECL { 206e675fbaSSiva Chandra Reddy 216e675fbaSSiva Chandra Reddy LLVM_LIBC_FUNCTION(ssize_t, pwrite, 226e675fbaSSiva Chandra Reddy (int fd, const void *buf, size_t count, off_t offset)) { 237776fba4SMikhail R. Gadelha 247776fba4SMikhail R. Gadelha ssize_t ret; 257776fba4SMikhail R. Gadelha if constexpr (sizeof(long) == sizeof(uint32_t) && 267776fba4SMikhail R. Gadelha sizeof(off_t) == sizeof(uint64_t)) { 277776fba4SMikhail R. Gadelha // This is a 32-bit system with a 64-bit offset, offset must be split. 287776fba4SMikhail R. Gadelha const uint64_t bits = cpp::bit_cast<uint64_t>(offset); 297776fba4SMikhail R. Gadelha const uint32_t lo = bits & UINT32_MAX; 307776fba4SMikhail R. Gadelha const uint32_t hi = bits >> 32; 317776fba4SMikhail R. Gadelha const long offset_low = cpp::bit_cast<long>(static_cast<long>(lo)); 327776fba4SMikhail R. Gadelha const long offset_high = cpp::bit_cast<long>(static_cast<long>(hi)); 337776fba4SMikhail R. Gadelha ret = LIBC_NAMESPACE::syscall_impl<ssize_t>(SYS_pwrite64, fd, buf, count, 347776fba4SMikhail R. Gadelha offset_low, offset_high); 357776fba4SMikhail R. Gadelha } else { 367776fba4SMikhail R. Gadelha ret = LIBC_NAMESPACE::syscall_impl<ssize_t>(SYS_pwrite64, fd, buf, count, 377776fba4SMikhail R. Gadelha offset); 387776fba4SMikhail R. Gadelha } 397776fba4SMikhail R. Gadelha 406e675fbaSSiva Chandra Reddy if (ret < 0) { 41f0a3954eSMichael Jones libc_errno = static_cast<int>(-ret); 426e675fbaSSiva Chandra Reddy return -1; 436e675fbaSSiva Chandra Reddy } 446e675fbaSSiva Chandra Reddy return ret; 456e675fbaSSiva Chandra Reddy } 466e675fbaSSiva Chandra Reddy 47*5ff3ff33SPetr Hosek } // namespace LIBC_NAMESPACE_DECL 48