forked from oils-for-unix/oils
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathstdlib.h
137 lines (101 loc) · 2.69 KB
/
stdlib.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
// cpp/stdlib.h: Replacement for pyext/posixmodule.c
#ifndef LEAKY_STDLIB_H
#define LEAKY_STDLIB_H
#include <errno.h>
#include <sys/types.h> // mode_t
#include <unistd.h>
#include "mycpp/runtime.h"
namespace fcntl_ {
// for F_GETFD
int fcntl(int fd, int cmd);
int fcntl(int fd, int cmd, int arg);
} // namespace fcntl_
namespace posix {
mode_t umask(mode_t mask);
inline bool access(Str* pathname, int mode) {
// No error case: 0 is success, -1 is error AND false.
return ::access(pathname->data_, mode) == 0;
}
inline Str* getcwd() {
Str* result = OverAllocatedStr(PATH_MAX);
char* p = ::getcwd(result->data_, PATH_MAX);
if (p == nullptr) {
throw Alloc<OSError>(errno);
}
// Important: set the length of the string!
result->MaybeShrink(strlen(result->data_));
return result;
}
// No error cases: the man page says these get*() functions always succeed
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) {
// No error case: false is the same as error (e.g. in pyext/posixmodule.c)
return ::isatty(fd);
}
inline Str* strerror(int err_num) {
// No error case: returns an appropriate string if err_num is invalid
return StrFromC(::strerror(err_num));
}
inline Tuple2<int, int> pipe() {
int fd[2];
if (::pipe(fd) < 0) {
throw Alloc<OSError>(errno);
}
return Tuple2<int, int>(fd[0], fd[1]);
}
inline int close(int fd) {
// TODO: handle errno. Although I'm not sure if it happens!
return ::close(fd);
}
void putenv(Str* name, Str* value);
inline int fork() {
int result = ::fork();
if (result < 0) {
throw Alloc<OSError>(errno);
}
return result;
}
inline void _exit(int status) {
// No error case: does not return
::_exit(status);
}
inline void write(int fd, Str* s) {
//
// IMPORTANT TODO: Write in a loop like posix_write() in pyext/posixmodule.c
//
if (::write(fd, s->data_, len(s)) < 0) {
throw Alloc<OSError>(errno);
}
}
// Can we use fcntl instead?
void dup2(int oldfd, int newfd);
int open(Str* path, int flags, int perms);
mylib::LineReader* fdopen(int fd, Str* c_mode);
void execve(Str* argv0, List<Str*>* argv, Dict<Str*, Str*>* environ);
void kill(int pid, int sig);
List<Str*>* listdir(Str* path);
} // namespace posix
namespace time_ {
void tzset();
time_t time();
// Note: This is translated in a weird way, unlike Python's API. Might want to
// factor out our own API with better types.
time_t localtime(time_t ts);
Str* strftime(Str* s, time_t ts);
void sleep(int seconds);
} // namespace time_
#endif // LEAKY_STDLIB_H