1 | #include <fcntl.h> |
2 | |
3 | #include <IO/ReadBufferFromFile.h> |
4 | #include <IO/WriteHelpers.h> |
5 | #include <Common/ProfileEvents.h> |
6 | #include <errno.h> |
7 | |
8 | |
9 | namespace ProfileEvents |
10 | { |
11 | extern const Event FileOpen; |
12 | } |
13 | |
14 | |
15 | namespace DB |
16 | { |
17 | |
18 | namespace ErrorCodes |
19 | { |
20 | extern const int FILE_DOESNT_EXIST; |
21 | extern const int CANNOT_OPEN_FILE; |
22 | extern const int CANNOT_CLOSE_FILE; |
23 | } |
24 | |
25 | |
26 | ReadBufferFromFile::ReadBufferFromFile( |
27 | const std::string & file_name_, |
28 | size_t buf_size, |
29 | int flags, |
30 | char * existing_memory, |
31 | size_t alignment) |
32 | : ReadBufferFromFileDescriptor(-1, buf_size, existing_memory, alignment), file_name(file_name_) |
33 | { |
34 | ProfileEvents::increment(ProfileEvents::FileOpen); |
35 | |
36 | #ifdef __APPLE__ |
37 | bool o_direct = (flags != -1) && (flags & O_DIRECT); |
38 | if (o_direct) |
39 | flags = flags & ~O_DIRECT; |
40 | #endif |
41 | fd = ::open(file_name.c_str(), flags == -1 ? O_RDONLY : flags); |
42 | |
43 | if (-1 == fd) |
44 | throwFromErrnoWithPath("Cannot open file " + file_name, file_name, |
45 | errno == ENOENT ? ErrorCodes::FILE_DOESNT_EXIST : ErrorCodes::CANNOT_OPEN_FILE); |
46 | #ifdef __APPLE__ |
47 | if (o_direct) |
48 | { |
49 | if (fcntl(fd, F_NOCACHE, 1) == -1) |
50 | throwFromErrnoWithPath("Cannot set F_NOCACHE on file " + file_name, file_name, ErrorCodes::CANNOT_OPEN_FILE); |
51 | } |
52 | #endif |
53 | } |
54 | |
55 | |
56 | ReadBufferFromFile::ReadBufferFromFile( |
57 | int fd_, |
58 | const std::string & original_file_name, |
59 | size_t buf_size, |
60 | char * existing_memory, |
61 | size_t alignment) |
62 | : |
63 | ReadBufferFromFileDescriptor(fd_, buf_size, existing_memory, alignment), |
64 | file_name(original_file_name.empty() ? "(fd = " + toString(fd_) + ")" : original_file_name) |
65 | { |
66 | } |
67 | |
68 | |
69 | ReadBufferFromFile::~ReadBufferFromFile() |
70 | { |
71 | if (fd < 0) |
72 | return; |
73 | |
74 | ::close(fd); |
75 | } |
76 | |
77 | |
78 | void ReadBufferFromFile::close() |
79 | { |
80 | if (0 != ::close(fd)) |
81 | throw Exception("Cannot close file" , ErrorCodes::CANNOT_CLOSE_FILE); |
82 | |
83 | fd = -1; |
84 | metric_increment.destroy(); |
85 | } |
86 | |
87 | } |
88 | |