xref: /llvm-project/libc/src/fcntl/linux/openat.cpp (revision abc49cc19463970d5523d7d3332e4c1f83bc2ef7)
14abfe47eSSiva Chandra Reddy //===-- Implementation of openat ------------------------------------------===//
24abfe47eSSiva Chandra Reddy //
34abfe47eSSiva Chandra Reddy // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
44abfe47eSSiva Chandra Reddy // See https://llvm.org/LICENSE.txt for license information.
54abfe47eSSiva Chandra Reddy // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
64abfe47eSSiva Chandra Reddy //
74abfe47eSSiva Chandra Reddy //===----------------------------------------------------------------------===//
84abfe47eSSiva Chandra Reddy 
94abfe47eSSiva Chandra Reddy #include "src/fcntl/openat.h"
104abfe47eSSiva Chandra Reddy 
114abfe47eSSiva Chandra Reddy #include "src/__support/OSUtil/syscall.h" // For internal syscall function.
124abfe47eSSiva Chandra Reddy #include "src/__support/common.h"
135ff3ff33SPetr Hosek #include "src/__support/macros/config.h"
14d49b993fSSiva Chandra Reddy #include "src/errno/libc_errno.h"
154abfe47eSSiva Chandra Reddy 
16*abc49cc1SJob Henandez Lara #include "hdr/types/mode_t.h"
174abfe47eSSiva Chandra Reddy #include <stdarg.h>
184abfe47eSSiva Chandra Reddy #include <sys/syscall.h> // For syscall numbers.
194abfe47eSSiva Chandra Reddy 
205ff3ff33SPetr Hosek namespace LIBC_NAMESPACE_DECL {
214abfe47eSSiva Chandra Reddy 
224abfe47eSSiva Chandra Reddy LLVM_LIBC_FUNCTION(int, openat, (int dfd, const char *path, int flags, ...)) {
234abfe47eSSiva Chandra Reddy   mode_t mode_flags = 0;
244abfe47eSSiva Chandra Reddy   // O_TMPFILE is a multi-bit flag so we test all bits by checking for equality
254abfe47eSSiva Chandra Reddy   // with O_TMPFILE
264abfe47eSSiva Chandra Reddy   if ((flags & O_CREAT) || (flags & O_TMPFILE) == O_TMPFILE) {
274abfe47eSSiva Chandra Reddy     va_list varargs;
284abfe47eSSiva Chandra Reddy     va_start(varargs, flags);
294abfe47eSSiva Chandra Reddy     mode_flags = va_arg(varargs, mode_t);
304abfe47eSSiva Chandra Reddy     va_end(varargs);
314abfe47eSSiva Chandra Reddy   }
324abfe47eSSiva Chandra Reddy 
33b6bc9d72SGuillaume Chatelet   int fd = LIBC_NAMESPACE::syscall_impl<int>(SYS_openat, dfd, path, flags,
34b6bc9d72SGuillaume Chatelet                                              mode_flags);
354abfe47eSSiva Chandra Reddy   if (fd > 0)
364abfe47eSSiva Chandra Reddy     return fd;
374abfe47eSSiva Chandra Reddy 
38d49b993fSSiva Chandra Reddy   libc_errno = -fd;
394abfe47eSSiva Chandra Reddy   return -1;
404abfe47eSSiva Chandra Reddy }
414abfe47eSSiva Chandra Reddy 
425ff3ff33SPetr Hosek } // namespace LIBC_NAMESPACE_DECL
43