cpp

Coverage Report

Created: 2023-09-13 01:07

/home/andy/git/oilshell/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(Str* 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 Str* getcwd() {
30
2
  Str* 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 Str* 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(Str* name, Str* 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, Str* 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
  pid_t ret = ::setpgid(pid, pgid);
113
0
  if (ret < 0) {
114
0
    throw Alloc<OSError>(errno);
115
0
  }
116
0
}
117
118
0
inline int getpgid(pid_t pid) {
119
0
  return ::getpgid(pid);
120
0
}
121
122
0
inline void tcsetpgrp(int fd, pid_t pgid) {
123
0
  pid_t ret = ::tcsetpgrp(fd, pgid);
124
0
  if (ret < 0) {
125
0
    throw Alloc<OSError>(errno);
126
0
  }
127
0
}
128
129
0
inline int tcgetpgrp(int fd) {
130
0
  pid_t ret = ::tcgetpgrp(fd);
131
0
  if (ret < 0) {
132
0
    throw Alloc<OSError>(errno);
133
0
  }
134
0
  return ret;
135
0
}
136
137
// Can we use fcntl instead?
138
void dup2(int oldfd, int newfd);
139
140
int open(Str* path, int flags, int perms);
141
142
mylib::LineReader* fdopen(int fd, Str* c_mode);
143
144
void execve(Str* argv0, List<Str*>* argv, Dict<Str*, Str*>* environ);
145
146
void kill(int pid, int sig);
147
void killpg(int pgid, int sig);
148
149
List<Str*>* listdir(Str* path);
150
151
}  // namespace posix
152
153
namespace time_ {
154
155
void tzset();
156
time_t time();
157
// Note: This is translated in a weird way, unlike Python's API.  Might want to
158
// factor out our own API with better types.
159
time_t localtime(time_t ts);
160
Str* strftime(Str* s, time_t ts);
161
void sleep(int seconds);
162
163
}  // namespace time_
164
165
#endif  // LEAKY_STDLIB_H