1*4abfe47eSSiva Chandra Reddy //===-- Implementation of openat ------------------------------------------===//
2*4abfe47eSSiva Chandra Reddy //
3*4abfe47eSSiva Chandra Reddy // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*4abfe47eSSiva Chandra Reddy // See https://llvm.org/LICENSE.txt for license information.
5*4abfe47eSSiva Chandra Reddy // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*4abfe47eSSiva Chandra Reddy //
7*4abfe47eSSiva Chandra Reddy //===----------------------------------------------------------------------===//
8*4abfe47eSSiva Chandra Reddy 
9*4abfe47eSSiva Chandra Reddy #include "src/fcntl/openat.h"
10*4abfe47eSSiva Chandra Reddy 
11*4abfe47eSSiva Chandra Reddy #include "src/__support/OSUtil/syscall.h" // For internal syscall function.
12*4abfe47eSSiva Chandra Reddy #include "src/__support/common.h"
13*4abfe47eSSiva Chandra Reddy 
14*4abfe47eSSiva Chandra Reddy #include <errno.h>
15*4abfe47eSSiva Chandra Reddy #include <fcntl.h>
16*4abfe47eSSiva Chandra Reddy #include <stdarg.h>
17*4abfe47eSSiva Chandra Reddy #include <sys/syscall.h> // For syscall numbers.
18*4abfe47eSSiva Chandra Reddy 
19*4abfe47eSSiva Chandra Reddy namespace __llvm_libc {
20*4abfe47eSSiva Chandra Reddy 
21*4abfe47eSSiva Chandra Reddy LLVM_LIBC_FUNCTION(int, openat, (int dfd, const char *path, int flags, ...)) {
22*4abfe47eSSiva Chandra Reddy   mode_t mode_flags = 0;
23*4abfe47eSSiva Chandra Reddy   // O_TMPFILE is a multi-bit flag so we test all bits by checking for equality
24*4abfe47eSSiva Chandra Reddy   // with O_TMPFILE
25*4abfe47eSSiva Chandra Reddy   if ((flags & O_CREAT) || (flags & O_TMPFILE) == O_TMPFILE) {
26*4abfe47eSSiva Chandra Reddy     va_list varargs;
27*4abfe47eSSiva Chandra Reddy     va_start(varargs, flags);
28*4abfe47eSSiva Chandra Reddy     mode_flags = va_arg(varargs, mode_t);
29*4abfe47eSSiva Chandra Reddy     va_end(varargs);
30*4abfe47eSSiva Chandra Reddy   }
31*4abfe47eSSiva Chandra Reddy 
32*4abfe47eSSiva Chandra Reddy   int fd = __llvm_libc::syscall(SYS_openat, dfd, path, flags, mode_flags);
33*4abfe47eSSiva Chandra Reddy   if (fd > 0)
34*4abfe47eSSiva Chandra Reddy     return fd;
35*4abfe47eSSiva Chandra Reddy 
36*4abfe47eSSiva Chandra Reddy   errno = -fd;
37*4abfe47eSSiva Chandra Reddy   return -1;
38*4abfe47eSSiva Chandra Reddy }
39*4abfe47eSSiva Chandra Reddy 
40*4abfe47eSSiva Chandra Reddy } // namespace __llvm_libc
41