forked from oils-for-unix/oils
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathposix.h
190 lines (148 loc) · 3.48 KB
/
posix.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
// posix.h: Replacement for native/posixmodule.c
#ifndef POSIX_H
#define POSIX_H
#include <sys/wait.h> // waitpid
#include <unistd.h>
#include "mylib.h"
// Save as a different name
#define X_OK_ X_OK
#define R_OK_ R_OK
#define W_OK_ W_OK
#define O_APPEND_ O_APPEND
#define O_CREAT_ O_CREAT
#define O_RDONLY_ O_RDONLY
#define O_RDWR_ O_RDWR
#define O_WRONLY_ O_WRONLY
#define O_TRUNC_ O_TRUNC
#undef X_OK
#undef R_OK
#undef W_OK
#undef O_APPEND
#undef O_CREAT
#undef O_RDONLY
#undef O_RDWR
#undef O_WRONLY
#undef O_TRUNC
namespace posix {
// aliases in this namespace
extern int X_OK;
extern int R_OK;
extern int W_OK;
extern int O_APPEND;
extern int O_CREAT;
extern int O_RDONLY;
extern int O_RDWR;
extern int O_WRONLY;
extern int O_TRUNC;
inline int access(Str* pathname, int mode) {
// Are there any errno I care about?
mylib::Str0 pathname0(pathname);
return ::access(pathname0.Get(), mode) == 0;
}
inline Str* getcwd() {
char* buf = static_cast<char*>(malloc(PATH_MAX + 1));
char* result = ::getcwd(buf, PATH_MAX + 1);
if (result == nullptr) {
// TODO: print errno, e.g. ENAMETOOLONG
throw new RuntimeError(new Str("Couldn't get working directory"));
}
return new Str(buf);
}
inline int getegid() {
return ::getegid();
}
inline int geteuid() {
return ::geteuid();
}
inline int getpid() {
return ::getpid();
}
inline int getppid() {
return ::getppid();
}
inline int getuid() {
return ::getuid();
}
inline bool isatty(int fd) {
return ::isatty(fd);
}
inline Str* strerror(int err_num) {
assert(0);
}
inline Str* uname() {
assert(0);
}
// TODO: write proper signatures
// stat returns stat_result
inline void stat() {
assert(0);
}
inline void lstat() {
assert(0);
}
inline Tuple2<int, int> pipe() {
assert(0);
}
inline int close(int fd) {
// TODO: handle errno. Although I'm not sure if it happens!
return ::close(fd);
}
inline int putenv(Str* name, Str* value) {
assert(0);
}
// TODO: errors
inline int chdir(Str* path) {
assert(0);
}
inline int fork() {
return ::fork();
}
inline void _exit(int status) {
exit(status);
}
inline void write(int fd, Str* value) {
assert(0);
}
inline Tuple2<int, int> waitpid(int pid, int options) {
int status;
int result_pid = ::waitpid(pid, &status, options);
return Tuple2<int, int>(result_pid, status);
}
// Can we use fcntl instead?
inline void dup2(int oldfd, int newfd) {
assert(0);
}
inline Str* read(int fd, int num_requested) {
char* buf = static_cast<char*>(malloc(num_requested + 1));
int num_read = ::read(fd, buf, num_requested);
buf[num_read] = '\0';
if (num_read < 0) {
throw new AssertionError(); // TODO: throw with errno
}
return new Str(buf, num_read); // could be a short read
}
int open(Str* path, int mode, int perms);
inline mylib::LineReader* fdopen(int fd, Str* c_mode) {
mylib::Str0 c_mode0(c_mode);
FILE* f = ::fdopen(fd, c_mode0.Get());
// TODO: raise exception
assert(f);
return new mylib::CFileLineReader(f);
}
inline void execve(Str* argv0, List<Str*>* argv, Dict<Str*, Str*>* environ) {
mylib::Str0 _argv0(argv0);
int n = len(argv);
// never deallocated
char** _argv = static_cast<char**>(malloc(n + 1));
// Annoying const_cast
// https://stackoverflow.com/questions/190184/execv-and-const-ness
for (int i = 0; i < n; ++i) {
_argv[i] = const_cast<char*>(argv->index(i)->data_);
}
_argv[n] = nullptr;
::execve(_argv0.Get(), _argv, nullptr);
}
// Dummy exception posix::error
class error {};
} // namespace posix
#endif // POSIX_H