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