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