-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.cpp
105 lines (94 loc) · 2.54 KB
/
main.cpp
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
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <cstring>
#include <cstdio>
#include <filesystem>
#include <vector>
// 標準出力にファイルディスクリプタの内容を出力する
// エラー時には std::runtime_error を発生させる
void printFD(const int fd)
{
std::vector<char> rdBuf(1024, 0);
while (true)
{
const auto rdSize = read(fd, rdBuf.data(), rdBuf.size());
if (rdSize == -1)
{
const std::string err = "read error, " + std::string(strerror(errno));
throw std::runtime_error(err);
}
if (rdSize == 0)
{
return;
}
const auto wrSize = write(STDOUT_FILENO, rdBuf.data(), rdSize);
if (wrSize == -1)
{
const std::string err = "write error, " + std::string(strerror(errno));
throw std::runtime_error(err);
}
if (wrSize != rdSize)
{
const std::string err = "write size error, " + std::to_string(wrSize);
throw std::runtime_error(err);
}
}
}
// 標準出力にファイルの内容を出力する
// エラー時には std::runtime_error を発生させる
void printFile(const std::filesystem::path &path)
{
const auto fd = open(path.c_str(), O_RDONLY);
if (fd == -1)
{
const std::string err = "open error, " + std::string(strerror(errno));
throw std::runtime_error(err);
}
try
{
printFD(fd);
}
catch (const std::runtime_error &e)
{
close(fd);
const std::string err = "printFD error, " + std::string(e.what());
throw std::runtime_error(err);
}
close(fd);
}
void printStdIn()
{
while (true)
{
printFD(STDIN_FILENO);
}
}
int main(int argc, char *argv[])
{
int ret = EXIT_SUCCESS;
if (argc < 2)
{
printStdIn();
return ret;
}
for (int i = 1; i < argc; i++)
{
const std::filesystem::path path(argv[i]);
try
{
printFile(path);
}
catch (const std::runtime_error &e)
{
// fprintf は今回は使わない
// fprintf ではなくて perror(const char *s) でもいいけど
// "s : strerror(errnum)" のような表記で標準エラー出力される
ret = EXIT_FAILURE;
const std::string err = std::string(path.c_str()) + ": " + std::string(e.what()) + "\n";
write(STDERR_FILENO, err.c_str(), err.size());
}
}
return ret;
}