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
9namespace ProfileEvents
10{
11 extern const Event FileOpen;
12}
13
14
15namespace DB
16{
17
18namespace 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
26ReadBufferFromFile::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
56ReadBufferFromFile::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
69ReadBufferFromFile::~ReadBufferFromFile()
70{
71 if (fd < 0)
72 return;
73
74 ::close(fd);
75}
76
77
78void 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