cpp

Coverage Report

Created: 2023-03-07 20:24

/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 int close(int fd) {
81
  // TODO: handle errno.  Although I'm not sure if it happens!
82
1
  return ::close(fd);
83
1
}
84
85
void putenv(Str* name, Str* value);
86
87
0
inline int fork() {
88
0
  int result = ::fork();
89
0
  if (result < 0) {
90
0
    throw Alloc<OSError>(errno);
91
0
  }
92
0
  return result;
93
0
}
94
95
0
inline void _exit(int status) {
96
0
  // No error case: does not return
97
0
  ::_exit(status);
98
0
}
99
100
0
inline void write(int fd, Str* s) {
101
0
  //
102
0
  // IMPORTANT TODO: Write in a loop like posix_write() in pyext/posixmodule.c
103
0
  //
104
0
105
0
  if (::write(fd, s->data_, len(s)) < 0) {
106
0
    throw Alloc<OSError>(errno);
107
0
  }
108
0
}
109
110
// Can we use fcntl instead?
111
void dup2(int oldfd, int newfd);
112
113
int open(Str* path, int flags, int perms);
114
115
mylib::LineReader* fdopen(int fd, Str* c_mode);
116
117
void execve(Str* argv0, List<Str*>* argv, Dict<Str*, Str*>* environ);
118
119
void kill(int pid, int sig);
120
121
List<Str*>* listdir(Str* path);
122
123
}  // namespace posix
124
125
namespace time_ {
126
127
void tzset();
128
time_t time();
129
// Note: This is translated in a weird way, unlike Python's API.  Might want to
130
// factor out our own API with better types.
131
time_t localtime(time_t ts);
132
Str* strftime(Str* s, time_t ts);
133
void sleep(int seconds);
134
135
}  // namespace time_
136
137
#endif  // LEAKY_STDLIB_H