1#include <Common/createHardLink.h>
2#include <Common/Exception.h>
3#include <errno.h>
4#include <unistd.h>
5#include <sys/stat.h>
6
7
8namespace DB
9{
10
11namespace ErrorCodes
12{
13 extern const int CANNOT_STAT;
14 extern const int CANNOT_LINK;
15}
16
17void createHardLink(const String & source_path, const String & destination_path)
18{
19 if (0 != link(source_path.c_str(), destination_path.c_str()))
20 {
21 if (errno == EEXIST)
22 {
23 auto link_errno = errno;
24
25 struct stat source_descr;
26 struct stat destination_descr;
27
28 if (0 != lstat(source_path.c_str(), &source_descr))
29 throwFromErrnoWithPath("Cannot stat " + source_path, source_path, ErrorCodes::CANNOT_STAT);
30
31 if (0 != lstat(destination_path.c_str(), &destination_descr))
32 throwFromErrnoWithPath("Cannot stat " + destination_path, destination_path, ErrorCodes::CANNOT_STAT);
33
34 if (source_descr.st_ino != destination_descr.st_ino)
35 throwFromErrnoWithPath(
36 "Destination file " + destination_path + " is already exist and have different inode.",
37 destination_path, ErrorCodes::CANNOT_LINK, link_errno);
38 }
39 else
40 throwFromErrnoWithPath("Cannot link " + source_path + " to " + destination_path, destination_path,
41 ErrorCodes::CANNOT_LINK);
42 }
43}
44
45}
46