Skip to content

Commit d61ac46

Browse files
authored
Fix compilation on QNX7 (#1146)
Dir::Size() method switched from using fstatat64() to lstat64() due to absence of dirfd() function on QNX. Fixed broken traversal of subdirectories in Dir::Size(). New suite DirTest added to functional tests with tests for Dir::Size(). Fixed missing includes. Relates-To: OCMAMQNX-2, OCMAMQNX-9 Signed-off-by: Jakub Mirek <[email protected]>
1 parent 403f01e commit d61ac46

File tree

5 files changed

+114
-12
lines changed

5 files changed

+114
-12
lines changed

olp-cpp-sdk-core/src/cache/DiskCache.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (C) 2019 HERE Europe B.V.
2+
* Copyright (C) 2019-2021 HERE Europe B.V.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -20,6 +20,7 @@
2020
#pragma once
2121

2222
#include <time.h>
23+
#include <atomic>
2324
#include <functional>
2425
#include <limits>
2526
#include <map>

olp-cpp-sdk-core/src/client/repository/ApiCacheRepository.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (C) 2020 HERE Europe B.V.
2+
* Copyright (C) 2020-2021 HERE Europe B.V.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -19,11 +19,12 @@
1919

2020
#pragma once
2121

22+
#include <time.h>
2223
#include <memory>
24+
#include <string>
2325

2426
#include <olp/core/client/HRN.h>
2527
#include <boost/optional.hpp>
26-
#include <string>
2728

2829
namespace olp {
2930
namespace cache {

olp-cpp-sdk-core/src/utils/Dir.cpp

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (C) 2019-2020 HERE Europe B.V.
2+
* Copyright (C) 2019-2021 HERE Europe B.V.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -56,8 +56,8 @@ std::wstring ConvertStringToWideString(const std::string& str) {
5656
size_needed);
5757
return wstr_path;
5858
}
59-
#endif // _UNICODE
60-
#endif // _WIN32 && _MINGW32
59+
#endif // _UNICODE
60+
#endif // _WIN32 && _MINGW32
6161

6262
#if !defined(_WIN32) || defined(__MINGW32__)
6363
int remove_dir_callback(const char* file, const struct stat* /*stat*/, int flag,
@@ -127,7 +127,7 @@ static bool mkdir_all(const char* dirname, int mode) {
127127

128128
#if defined(_WIN32) && !defined(__MINGW32__)
129129
void Tokenize(const std::string& path, const std::string& delimiters,
130-
std::vector<std::string>& result) {
130+
std::vector<std::string>& result) {
131131
std::string sub_path = path;
132132
while (1) {
133133
size_t position = sub_path.find(delimiters);
@@ -445,15 +445,14 @@ uint64_t Dir::Size(const std::string& path, FilterFunction filter_fn) {
445445
struct dirent* ent = nullptr;
446446

447447
if ((dir = opendir(path.c_str())) != nullptr) {
448-
int fd = dirfd(dir);
449-
450448
while ((ent = readdir(dir)) != nullptr) {
449+
std::string ent_path = path + "/" + ent->d_name;
451450
#ifdef __APPLE__
452451
struct stat sb;
453-
if (fstatat(fd, ent->d_name, &sb, AT_SYMLINK_NOFOLLOW) == 0) {
452+
if (lstat(ent_path.c_str(), &sb) == 0) {
454453
#else
455454
struct stat64 sb;
456-
if (fstatat64(fd, ent->d_name, &sb, AT_SYMLINK_NOFOLLOW) == 0) {
455+
if (lstat64(ent_path.c_str(), &sb) == 0) {
457456
#endif
458457
if (strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0) {
459458
continue;
@@ -465,7 +464,7 @@ uint64_t Dir::Size(const std::string& path, FilterFunction filter_fn) {
465464

466465
switch (sb.st_mode & S_IFMT) {
467466
case S_IFDIR:
468-
result += Size(ent->d_name, filter_fn);
467+
result += Size(ent_path, filter_fn);
469468
break;
470469
case S_IFREG:
471470
result += sb.st_size;

tests/functional/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818

1919
set(OLP_SDK_FUNCTIONAL_TESTS_SOURCES
20+
./olp-cpp-sdk-core/DirTest.cpp
2021
./olp-cpp-sdk-core/OlpClientDefaultAsyncHttpTest.cpp
2122
./olp-cpp-sdk-dataservice-read/ApiTest.cpp
2223
./olp-cpp-sdk-dataservice-read/CatalogClientTest.cpp
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
/*
2+
* Copyright (C) 2021 HERE Europe B.V.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*
16+
* SPDX-License-Identifier: Apache-2.0
17+
* License-Filename: LICENSE
18+
*/
19+
20+
#include <gmock/gmock.h>
21+
#include <gtest/gtest.h>
22+
#include <olp/core/utils/Dir.h>
23+
#include <fstream>
24+
#if !defined(_WIN32) || defined(__MINGW32__)
25+
#include <unistd.h>
26+
#else
27+
#include <windows.h>
28+
#endif
29+
30+
namespace {
31+
using Dir = olp::utils::Dir;
32+
33+
#if defined(_WIN32) && !defined(__MINGW32__)
34+
const char kSeparator[] = "\\";
35+
#else
36+
const char kSeparator[] = "/";
37+
#endif
38+
39+
void CreateFile(const std::string& path, size_t size) {
40+
std::ofstream file(path.c_str(), std::ios::out | std::ios::binary);
41+
file.seekp(size - 1);
42+
file.write("", 1);
43+
file.close();
44+
}
45+
46+
void CreateDirectory(const std::string& path) { Dir::Create(path); }
47+
48+
void CreateSymLink(const std::string& to, const std::string& link) {
49+
#if !defined(_WIN32) || defined(__MINGW32__)
50+
symlink(to.c_str(), link.c_str());
51+
#else
52+
CreateSymbolicLink(to.c_str(), link.c_str(), 0);
53+
#endif
54+
}
55+
56+
std::string PathBuild(std::string arg) { return arg; }
57+
58+
template <typename... Ts>
59+
std::string PathBuild(std::string arg1, std::string arg2, Ts... args) {
60+
return PathBuild(std::string(arg1) + kSeparator + std::string(arg2), args...);
61+
}
62+
63+
} // namespace
64+
65+
TEST(DirTest, CheckDirSize) {
66+
std::string path = PathBuild(Dir::TempDirectory(), "temporary_test_dir");
67+
Dir::Remove(path);
68+
CreateDirectory(path);
69+
{
70+
SCOPED_TRACE("Single file");
71+
CreateFile(PathBuild(path, "file1"), 10);
72+
EXPECT_EQ(Dir::Size(path), 10u);
73+
}
74+
{
75+
SCOPED_TRACE("First level subdirectory");
76+
CreateDirectory(PathBuild(path, "sub"));
77+
CreateFile(PathBuild(path, "sub", "sub_file1"), 10);
78+
EXPECT_EQ(Dir::Size(path), 20u);
79+
}
80+
{
81+
SCOPED_TRACE("Second level subdirectory");
82+
CreateDirectory(PathBuild(path, "sub", "subsub"));
83+
CreateFile(PathBuild(path, "sub", "subsub", "subsub_file1"), 10);
84+
EXPECT_EQ(Dir::Size(path), 30u);
85+
}
86+
{
87+
SCOPED_TRACE("Symbolic links to directory and file");
88+
CreateSymLink("sub", PathBuild(path, "sub_lnk"));
89+
CreateSymLink("file1", PathBuild(path, "file1_lnk"));
90+
EXPECT_EQ(Dir::Size(path), 30u);
91+
}
92+
{
93+
SCOPED_TRACE("Second file in directory and subdirectories");
94+
CreateFile(PathBuild(path, "file2"), 10);
95+
CreateFile(PathBuild(path, "sub", "sub_file2"), 10);
96+
CreateFile(PathBuild(path, "sub", "subsub", "subsub_file2"), 10);
97+
EXPECT_EQ(Dir::Size(path), 60u);
98+
}
99+
Dir::Remove(path);
100+
}

0 commit comments

Comments
 (0)