/home/uke/oil/cpp/stdlib.h
Line | Count | Source (jump to first uncovered line) |
1 | | // cpp/stdlib.h: Replacement for pyext/posixmodule.c |
2 | | |
3 | | #ifndef LEAKY_STDLIB_H |
4 | | #define LEAKY_STDLIB_H |
5 | | |
6 | | #include <errno.h> |
7 | | #include <sys/types.h> // mode_t |
8 | | #include <unistd.h> |
9 | | |
10 | | #include "mycpp/runtime.h" |
11 | | |
12 | | namespace math { |
13 | | |
14 | | bool isinf(double f); |
15 | | bool isnan(double f); |
16 | | |
17 | | } // namespace math |
18 | | |
19 | | namespace fcntl_ { |
20 | | |
21 | | // for F_GETFD |
22 | | int fcntl(int fd, int cmd); |
23 | | int fcntl(int fd, int cmd, int arg); |
24 | | |
25 | | } // namespace fcntl_ |
26 | | |
27 | | namespace posix { |
28 | | |
29 | | mode_t umask(mode_t mask); |
30 | | |
31 | 1 | inline bool access(BigStr* pathname, int mode) { |
32 | | // No error case: 0 is success, -1 is error AND false. |
33 | 1 | return ::access(pathname->data_, mode) == 0; |
34 | 1 | } |
35 | | |
36 | 2 | inline BigStr* getcwd() { |
37 | 2 | BigStr* result = OverAllocatedStr(PATH_MAX); |
38 | 2 | char* p = ::getcwd(result->data_, PATH_MAX); |
39 | 2 | if (p == nullptr) { |
40 | 0 | throw Alloc<OSError>(errno); |
41 | 0 | } |
42 | | // Important: set the length of the string! |
43 | 2 | result->MaybeShrink(strlen(result->data_)); |
44 | 2 | return result; |
45 | 2 | } |
46 | | |
47 | | // No error cases: the man page says these get*() functions always succeed |
48 | | |
49 | 1 | inline int getegid() { |
50 | 1 | return ::getegid(); |
51 | 1 | } |
52 | | |
53 | 1 | inline int geteuid() { |
54 | 1 | return ::geteuid(); |
55 | 1 | } |
56 | | |
57 | 1 | inline int getpid() { |
58 | 1 | return ::getpid(); |
59 | 1 | } |
60 | | |
61 | 1 | inline int getppid() { |
62 | 1 | return ::getppid(); |
63 | 1 | } |
64 | | |
65 | 1 | inline int getuid() { |
66 | 1 | return ::getuid(); |
67 | 1 | } |
68 | | |
69 | 1 | inline bool isatty(int fd) { |
70 | | // No error case: false is the same as error (e.g. in pyext/posixmodule.c) |
71 | 1 | return ::isatty(fd); |
72 | 1 | } |
73 | | |
74 | 1 | inline BigStr* strerror(int err_num) { |
75 | | // No error case: returns an appropriate string if err_num is invalid |
76 | 1 | return StrFromC(::strerror(err_num)); |
77 | 1 | } |
78 | | |
79 | 1 | inline Tuple2<int, int> pipe() { |
80 | 1 | int fd[2]; |
81 | 1 | if (::pipe(fd) < 0) { |
82 | 0 | throw Alloc<OSError>(errno); |
83 | 0 | } |
84 | 1 | return Tuple2<int, int>(fd[0], fd[1]); |
85 | 1 | } |
86 | | |
87 | 1 | inline void close(int fd) { |
88 | 1 | if (::close(fd) < 0) { |
89 | 0 | throw Alloc<OSError>(errno); |
90 | 0 | } |
91 | 1 | } |
92 | | |
93 | | void putenv(BigStr* name, BigStr* value); |
94 | | |
95 | 0 | inline int fork() { |
96 | 0 | int result = ::fork(); |
97 | 0 | if (result < 0) { |
98 | 0 | throw Alloc<OSError>(errno); |
99 | 0 | } |
100 | 0 | return result; |
101 | 0 | } |
102 | | |
103 | 0 | inline void _exit(int status) { |
104 | 0 | // No error case: does not return |
105 | 0 | ::_exit(status); |
106 | 0 | } |
107 | | |
108 | 0 | inline void write(int fd, BigStr* s) { |
109 | 0 | // |
110 | 0 | // IMPORTANT TODO: Write in a loop like posix_write() in pyext/posixmodule.c |
111 | 0 | // |
112 | 0 |
|
113 | 0 | if (::write(fd, s->data_, len(s)) < 0) { |
114 | 0 | throw Alloc<OSError>(errno); |
115 | 0 | } |
116 | 0 | } |
117 | | |
118 | 0 | inline void setpgid(pid_t pid, pid_t pgid) { |
119 | 0 | int ret = ::setpgid(pid, pgid); |
120 | 0 | if (ret < 0) { |
121 | 0 | throw Alloc<OSError>(errno); |
122 | 0 | } |
123 | 0 | } |
124 | | |
125 | 1 | inline int getpgid(pid_t pid) { |
126 | 1 | pid_t ret = ::getpgid(pid); |
127 | 1 | if (ret < 0) { |
128 | 0 | throw Alloc<OSError>(errno); |
129 | 0 | } |
130 | 1 | return ret; |
131 | 1 | } |
132 | | |
133 | 0 | inline void tcsetpgrp(int fd, pid_t pgid) { |
134 | 0 | int ret = ::tcsetpgrp(fd, pgid); |
135 | 0 | if (ret < 0) { |
136 | 0 | throw Alloc<OSError>(errno); |
137 | 0 | } |
138 | 0 | } |
139 | | |
140 | 0 | inline int tcgetpgrp(int fd) { |
141 | 0 | pid_t ret = ::tcgetpgrp(fd); |
142 | 0 | if (ret < 0) { |
143 | 0 | throw Alloc<OSError>(errno); |
144 | 0 | } |
145 | 0 | return ret; |
146 | 0 | } |
147 | | |
148 | | // Can we use fcntl instead? |
149 | | void dup2(int oldfd, int newfd); |
150 | | |
151 | | int open(BigStr* path, int flags, int perms); |
152 | | |
153 | | mylib::File* fdopen(int fd, BigStr* c_mode); |
154 | | |
155 | | void execve(BigStr* argv0, List<BigStr*>* argv, |
156 | | Dict<BigStr*, BigStr*>* environ); |
157 | | |
158 | | void kill(int pid, int sig); |
159 | | void killpg(int pgid, int sig); |
160 | | |
161 | | List<BigStr*>* listdir(BigStr* path); |
162 | | |
163 | | } // namespace posix |
164 | | |
165 | | namespace time_ { |
166 | | |
167 | | void tzset(); |
168 | | time_t time(); |
169 | | // Note: This is translated in a weird way, unlike Python's API. Might want to |
170 | | // factor out our own API with better types. |
171 | | time_t localtime(time_t ts); |
172 | | BigStr* strftime(BigStr* s, time_t ts); |
173 | | void sleep(int seconds); |
174 | | |
175 | | } // namespace time_ |
176 | | |
177 | | #endif // LEAKY_STDLIB_H |