100e51f04SSiva Chandra Reddy //===-- Linux implementation of readlink ----------------------------------===// 200e51f04SSiva Chandra Reddy // 300e51f04SSiva Chandra Reddy // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 400e51f04SSiva Chandra Reddy // See https://llvm.org/LICENSE.txt for license information. 500e51f04SSiva Chandra Reddy // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 600e51f04SSiva Chandra Reddy // 700e51f04SSiva Chandra Reddy //===----------------------------------------------------------------------===// 800e51f04SSiva Chandra Reddy 900e51f04SSiva Chandra Reddy #include "src/unistd/readlink.h" 1000e51f04SSiva Chandra Reddy 1100e51f04SSiva Chandra Reddy #include "src/__support/OSUtil/syscall.h" // For internal syscall function. 1200e51f04SSiva Chandra Reddy #include "src/__support/common.h" 1300e51f04SSiva Chandra Reddy 14*abc49cc1SJob Henandez Lara #include "hdr/fcntl_macros.h" 155ff3ff33SPetr Hosek #include "src/__support/macros/config.h" 16803437dbSMichael Jones #include "src/errno/libc_errno.h" 1700e51f04SSiva Chandra Reddy #include <sys/syscall.h> // For syscall numbers. 1800e51f04SSiva Chandra Reddy 195ff3ff33SPetr Hosek namespace LIBC_NAMESPACE_DECL { 2000e51f04SSiva Chandra Reddy 2100e51f04SSiva Chandra Reddy LLVM_LIBC_FUNCTION(ssize_t, readlink, 2200e51f04SSiva Chandra Reddy (const char *__restrict path, char *__restrict buf, 2300e51f04SSiva Chandra Reddy size_t bufsize)) { 2400e51f04SSiva Chandra Reddy #ifdef SYS_readlink 2500e51f04SSiva Chandra Reddy ssize_t ret = 26b6bc9d72SGuillaume Chatelet LIBC_NAMESPACE::syscall_impl<ssize_t>(SYS_readlink, path, buf, bufsize); 27f0a3954eSMichael Jones #elif defined(SYS_readlinkat) 28b6bc9d72SGuillaume Chatelet ssize_t ret = LIBC_NAMESPACE::syscall_impl<ssize_t>(SYS_readlinkat, AT_FDCWD, 29f0a3954eSMichael Jones path, buf, bufsize); 3000e51f04SSiva Chandra Reddy #else 315b22df99SMikhail R. Gadelha #error "readlink or readlinkat syscalls not available." 3200e51f04SSiva Chandra Reddy #endif 3300e51f04SSiva Chandra Reddy if (ret < 0) { 34f0a3954eSMichael Jones libc_errno = static_cast<int>(-ret); 3500e51f04SSiva Chandra Reddy return -1; 3600e51f04SSiva Chandra Reddy } 3700e51f04SSiva Chandra Reddy return ret; 3800e51f04SSiva Chandra Reddy } 3900e51f04SSiva Chandra Reddy 405ff3ff33SPetr Hosek } // namespace LIBC_NAMESPACE_DECL 41