88
99#include " src/__support/OSUtil/fcntl.h"
1010
11+ #include " hdr/errno_macros.h"
1112#include " hdr/fcntl_macros.h"
13+ #include " hdr/types/mode_t.h"
1214#include " hdr/types/off_t.h"
1315#include " hdr/types/struct_f_owner_ex.h"
1416#include " hdr/types/struct_flock.h"
1517#include " hdr/types/struct_flock64.h"
1618#include " src/__support/OSUtil/syscall.h" // For internal syscall function.
1719#include " src/__support/common.h"
18- #include " src/__support/libc_errno .h"
20+ #include " src/__support/error_or .h"
1921#include " src/__support/macros/config.h"
2022
21- #include < stdarg.h>
2223#include < sys/syscall.h> // For syscall numbers.
2324
2425namespace LIBC_NAMESPACE_DECL {
2526namespace internal {
2627
27- int fcntl (int fd, int cmd, void *arg) {
28+ ErrorOr< int > fcntl (int fd, int cmd, void *arg) {
2829#if SYS_fcntl
2930 constexpr auto FCNTL_SYSCALL_ID = SYS_fcntl;
3031#elif defined(SYS_fcntl64)
@@ -33,8 +34,7 @@ int fcntl(int fd, int cmd, void *arg) {
3334#error "fcntl and fcntl64 syscalls not available."
3435#endif
3536
36- int new_cmd = cmd;
37- switch (new_cmd) {
37+ switch (cmd) {
3838 case F_OFD_SETLKW: {
3939 struct flock *flk = reinterpret_cast <struct flock *>(arg);
4040 // convert the struct to a flock64
@@ -45,8 +45,11 @@ int fcntl(int fd, int cmd, void *arg) {
4545 flk64.l_len = flk->l_len ;
4646 flk64.l_pid = flk->l_pid ;
4747 // create a syscall
48- return LIBC_NAMESPACE::syscall_impl<int >(FCNTL_SYSCALL_ID, fd, new_cmd,
49- &flk64);
48+ int ret =
49+ LIBC_NAMESPACE::syscall_impl<int >(FCNTL_SYSCALL_ID, fd, cmd, &flk64);
50+ if (ret < 0 )
51+ return Error (-ret);
52+ return ret;
5053 }
5154 case F_OFD_GETLK:
5255 case F_OFD_SETLK: {
@@ -59,60 +62,80 @@ int fcntl(int fd, int cmd, void *arg) {
5962 flk64.l_len = flk->l_len ;
6063 flk64.l_pid = flk->l_pid ;
6164 // create a syscall
62- int retVal = LIBC_NAMESPACE::syscall_impl< int >(FCNTL_SYSCALL_ID, fd,
63- new_cmd , &flk64);
65+ int ret =
66+ LIBC_NAMESPACE::syscall_impl< int >(FCNTL_SYSCALL_ID, fd, cmd , &flk64);
6467 // On failure, return
65- if (retVal == - 1 )
66- return - 1 ;
68+ if (ret < 0 )
69+ return Error (- 1 ) ;
6770 // Check for overflow, i.e. the offsets are not the same when cast
6871 // to off_t from off64_t.
6972 if (static_cast <off_t >(flk64.l_len ) != flk64.l_len ||
70- static_cast <off_t >(flk64.l_start ) != flk64.l_start ) {
71- libc_errno = EOVERFLOW;
72- return -1 ;
73- }
73+ static_cast <off_t >(flk64.l_start ) != flk64.l_start )
74+ return Error (EOVERFLOW);
75+
7476 // Now copy back into flk, in case flk64 got modified
7577 flk->l_type = flk64.l_type ;
7678 flk->l_whence = flk64.l_whence ;
7779 flk->l_start = static_cast <decltype (flk->l_start )>(flk64.l_start );
7880 flk->l_len = static_cast <decltype (flk->l_len )>(flk64.l_len );
7981 flk->l_pid = flk64.l_pid ;
80- return retVal ;
82+ return ret ;
8183 }
8284 case F_GETOWN: {
8385 struct f_owner_ex fex;
8486 int ret = LIBC_NAMESPACE::syscall_impl<int >(FCNTL_SYSCALL_ID, fd,
8587 F_GETOWN_EX, &fex);
86- if (ret >= 0 )
87- return fex.type == F_OWNER_PGRP ? -fex.pid : fex.pid ;
88- libc_errno = -ret;
89- return -1 ;
88+ if (ret < 0 )
89+ return Error (-ret);
90+ return fex.type == F_OWNER_PGRP ? -fex.pid : fex.pid ;
9091 }
9192#ifdef SYS_fcntl64
9293 case F_GETLK: {
9394 if constexpr (FCNTL_SYSCALL_ID == SYS_fcntl64)
94- new_cmd = F_GETLK64;
95+ cmd = F_GETLK64;
9596 break ;
9697 }
9798 case F_SETLK: {
9899 if constexpr (FCNTL_SYSCALL_ID == SYS_fcntl64)
99- new_cmd = F_SETLK64;
100+ cmd = F_SETLK64;
100101 break ;
101102 }
102103 case F_SETLKW: {
103104 if constexpr (FCNTL_SYSCALL_ID == SYS_fcntl64)
104- new_cmd = F_SETLKW64;
105+ cmd = F_SETLKW64;
105106 break ;
106107 }
107108#endif
108109 }
109- int retVal = LIBC_NAMESPACE::syscall_impl<int >(FCNTL_SYSCALL_ID, fd, new_cmd,
110- reinterpret_cast <void *>(arg));
111- if (retVal >= 0 ) {
112- return retVal;
113- }
114- libc_errno = -retVal;
115- return -1 ;
110+
111+ // default, but may use rewritten cmd from above.
112+ int ret = LIBC_NAMESPACE::syscall_impl<int >(FCNTL_SYSCALL_ID, fd, cmd,
113+ reinterpret_cast <void *>(arg));
114+ if (ret < 0 )
115+ return Error (-ret);
116+ return ret;
117+ }
118+
119+ ErrorOr<int > open (const char *path, int flags, mode_t mode_flags) {
120+ #ifdef SYS_open
121+ int fd = LIBC_NAMESPACE::syscall_impl<int >(SYS_open, path, flags, mode_flags);
122+ #else
123+ int fd = LIBC_NAMESPACE::syscall_impl<int >(SYS_openat, AT_FDCWD, path, flags,
124+ mode_flags);
125+ #endif
126+ if (fd < 0 )
127+ return Error (-fd);
128+
129+ return fd;
130+ }
131+
132+ ErrorOr<int > close (int fd) {
133+ int ret = LIBC_NAMESPACE::syscall_impl<int >(SYS_close, fd);
134+
135+ if (ret < 0 )
136+ return Error (-ret);
137+
138+ return ret;
116139}
117140
118141} // namespace internal
0 commit comments