8
8
9
9
#include " src/__support/OSUtil/fcntl.h"
10
10
11
+ #include " hdr/errno_macros.h"
11
12
#include " hdr/fcntl_macros.h"
13
+ #include " hdr/types/mode_t.h"
12
14
#include " hdr/types/off_t.h"
13
15
#include " hdr/types/struct_f_owner_ex.h"
14
16
#include " hdr/types/struct_flock.h"
15
17
#include " hdr/types/struct_flock64.h"
16
18
#include " src/__support/OSUtil/syscall.h" // For internal syscall function.
17
19
#include " src/__support/common.h"
18
- #include " src/__support/libc_errno .h"
20
+ #include " src/__support/error_or .h"
19
21
#include " src/__support/macros/config.h"
20
22
21
- #include < stdarg.h>
22
23
#include < sys/syscall.h> // For syscall numbers.
23
24
24
25
namespace LIBC_NAMESPACE_DECL {
25
26
namespace internal {
26
27
27
- int fcntl (int fd, int cmd, void *arg) {
28
+ ErrorOr< int > fcntl (int fd, int cmd, void *arg) {
28
29
#if SYS_fcntl
29
30
constexpr auto FCNTL_SYSCALL_ID = SYS_fcntl;
30
31
#elif defined(SYS_fcntl64)
@@ -33,8 +34,7 @@ int fcntl(int fd, int cmd, void *arg) {
33
34
#error "fcntl and fcntl64 syscalls not available."
34
35
#endif
35
36
36
- int new_cmd = cmd;
37
- switch (new_cmd) {
37
+ switch (cmd) {
38
38
case F_OFD_SETLKW: {
39
39
struct flock *flk = reinterpret_cast <struct flock *>(arg);
40
40
// convert the struct to a flock64
@@ -45,8 +45,11 @@ int fcntl(int fd, int cmd, void *arg) {
45
45
flk64.l_len = flk->l_len ;
46
46
flk64.l_pid = flk->l_pid ;
47
47
// 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;
50
53
}
51
54
case F_OFD_GETLK:
52
55
case F_OFD_SETLK: {
@@ -59,60 +62,80 @@ int fcntl(int fd, int cmd, void *arg) {
59
62
flk64.l_len = flk->l_len ;
60
63
flk64.l_pid = flk->l_pid ;
61
64
// 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);
64
67
// On failure, return
65
- if (retVal == - 1 )
66
- return - 1 ;
68
+ if (ret < 0 )
69
+ return Error (- 1 ) ;
67
70
// Check for overflow, i.e. the offsets are not the same when cast
68
71
// to off_t from off64_t.
69
72
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
+
74
76
// Now copy back into flk, in case flk64 got modified
75
77
flk->l_type = flk64.l_type ;
76
78
flk->l_whence = flk64.l_whence ;
77
79
flk->l_start = static_cast <decltype (flk->l_start )>(flk64.l_start );
78
80
flk->l_len = static_cast <decltype (flk->l_len )>(flk64.l_len );
79
81
flk->l_pid = flk64.l_pid ;
80
- return retVal ;
82
+ return ret ;
81
83
}
82
84
case F_GETOWN: {
83
85
struct f_owner_ex fex;
84
86
int ret = LIBC_NAMESPACE::syscall_impl<int >(FCNTL_SYSCALL_ID, fd,
85
87
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 ;
90
91
}
91
92
#ifdef SYS_fcntl64
92
93
case F_GETLK: {
93
94
if constexpr (FCNTL_SYSCALL_ID == SYS_fcntl64)
94
- new_cmd = F_GETLK64;
95
+ cmd = F_GETLK64;
95
96
break ;
96
97
}
97
98
case F_SETLK: {
98
99
if constexpr (FCNTL_SYSCALL_ID == SYS_fcntl64)
99
- new_cmd = F_SETLK64;
100
+ cmd = F_SETLK64;
100
101
break ;
101
102
}
102
103
case F_SETLKW: {
103
104
if constexpr (FCNTL_SYSCALL_ID == SYS_fcntl64)
104
- new_cmd = F_SETLKW64;
105
+ cmd = F_SETLKW64;
105
106
break ;
106
107
}
107
108
#endif
108
109
}
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;
116
139
}
117
140
118
141
} // namespace internal
0 commit comments