brintos

brintos / llvm-project-archived public Read only

0
0
Text · 1.9 KiB · c0e475d Raw
67 lines · cpp
1//===-- Linux implementation of getcwd ------------------------------------===//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-exception6//7//===----------------------------------------------------------------------===//8 9#include "src/unistd/getcwd.h"10 11#include "src/__support/OSUtil/syscall.h" // For internal syscall function.12#include "src/__support/common.h"13#include "src/__support/macros/config.h"14#include "src/string/allocating_string_utils.h" // For strdup.15 16#include "src/__support/libc_errno.h"17#include <linux/limits.h> // This is safe to include without any name pollution.18#include <sys/syscall.h> // For syscall numbers.19 20namespace LIBC_NAMESPACE_DECL {21 22namespace {23 24bool getcwd_syscall(char *buf, size_t size) {25  int ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_getcwd, buf, size);26  if (ret < 0) {27    libc_errno = -ret;28    return false;29  } else if (ret == 0 || buf[0] != '/') {30    libc_errno = ENOENT;31    return false;32  }33  return true;34}35 36} // anonymous namespace37 38LLVM_LIBC_FUNCTION(char *, getcwd, (char *buf, size_t size)) {39  if (buf == nullptr) {40    // We match glibc's behavior here and return the cwd in a malloc-ed buffer.41    // We will allocate a static buffer of size PATH_MAX first and fetch the cwd42    // into it. This way, if the syscall fails, we avoid unnecessary malloc43    // and free.44    char pathbuf[PATH_MAX];45    if (!getcwd_syscall(pathbuf, PATH_MAX))46      return nullptr;47    auto cwd = internal::strdup(pathbuf);48    if (!cwd) {49      libc_errno = ENOMEM;50      return nullptr;51    }52    return *cwd;53  } else if (size == 0) {54    libc_errno = EINVAL;55    return nullptr;56  }57 58  // TODO: When buf is not sufficient, evaluate the full cwd path using59  // alternate approaches.60 61  if (!getcwd_syscall(buf, size))62    return nullptr;63  return buf;64}65 66} // namespace LIBC_NAMESPACE_DECL67