• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

mavlink / MAVSDK / 29462275360

16 Jul 2026 12:44AM UTC coverage: 50.438%. First build
29462275360

Pull #2936

github

web-flow
Merge a1505e5d2 into 23fd28534
Pull Request #2936: Backport various bugfixes to v3

161 of 239 new or added lines in 22 files covered. (67.36%)

19309 of 38283 relevant lines covered (50.44%)

671.19 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

83.33
/src/mavsdk/core/fs_utils.cpp
1

2
#include "fs_utils.h"
3
#include "log.h"
4
#include <algorithm>
5
#include <cctype>
6
#include <fstream>
7
#include <random>
8
#include <string>
9

10
#if defined(LINUX) || defined(APPLE)
11
#include <pwd.h>
12
#include <sys/types.h>
13
#include <unistd.h>
14
#endif
15

16
#ifdef WINDOWS
17
#include <windows.h>
18
#include <shlobj.h>
19
#endif
20

21
namespace mavsdk {
22

23
#ifdef ANDROID
24
extern "C" {
25
// Default Android temp path that can be overridden by JNI if needed
26
char* mavsdk_temp_path = const_cast<char*>("/data/local/tmp");
27
}
28
#endif
29

30
#ifdef WINDOWS
31
static std::optional<std::filesystem::path> get_known_windows_path(REFKNOWNFOLDERID folderId)
32
{
33
    std::filesystem::path path;
34
    PWSTR path_tmp;
35

36
    /* Attempt to get user's AppData folder
37
     *
38
     * Microsoft Docs:
39
     * https://learn.microsoft.com/en-us/windows/win32/api/shlobj_core/nf-shlobj_core-shgetknownfolderpath
40
     * https://learn.microsoft.com/en-us/windows/win32/shell/knownfolderid
41
     */
42
    auto get_folder_path_ret = SHGetKnownFolderPath(folderId, 0, nullptr, &path_tmp);
43

44
    /* Error check */
45
    if (get_folder_path_ret != S_OK) {
46
        CoTaskMemFree(path_tmp);
47
        return std::nullopt;
48
    }
49

50
    /* Convert the Windows path type to a C++ path */
51
    path = path_tmp;
52

53
    CoTaskMemFree(path_tmp);
54
    return path;
55
}
56
#endif
57

58
std::optional<std::filesystem::path> get_cache_directory()
186✔
59
{
60
    // Windows: %LOCALAPPDATA%
61
    // Android: /data/data/<package>/cache
62
    // Linux: ~/.cache
63
    // macOS: ~/Library/Caches
64
#if defined(WINDOWS)
65
    auto path = get_known_windows_path(FOLDERID_LocalAppData);
66
    if (path) {
67
        return path->append("mavsdk_cache");
68
    }
69
#elif defined(ANDROID)
70
    // Read /proc/self/cmdline
71
    std::ifstream cmdline("/proc/self/cmdline");
72
    std::string line;
73
    // /proc/self/cmdline stores the package name followed by a NUL byte, which we want to exclude
74
    if (std::getline(cmdline, line, '\0')) {
75
        return "/data/data/" + line + "/mavsdk_cache";
76
    }
77
#elif defined(APPLE) || defined(LINUX)
78
    const char* homedir;
79
    if ((homedir = getenv("HOME")) == NULL) {
186✔
80
        // getpwuid() can return NULL if there is no passwd entry for the uid (common in
81
        // minimal containers), so guard against dereferencing it.
NEW
82
        const struct passwd* pw = getpwuid(getuid());
×
NEW
83
        homedir = (pw != nullptr) ? pw->pw_dir : nullptr;
×
84
    }
85
    if (!homedir) {
186✔
86
        return std::nullopt;
×
87
    }
88
#if defined(APPLE)
89
    return std::filesystem::path(homedir) / "Library" / "Caches" / "mavsdk";
90
#else // Linux
91
    return std::filesystem::path(homedir) / ".cache" / "mavsdk";
186✔
92
#endif
93
#else
94
#error "Unsupported platform"
95
#endif
96

97
    return std::nullopt;
98
}
99

100
std::optional<std::filesystem::path> create_tmp_directory(const std::string& prefix)
187✔
101
{
102
    // Inspired by https://stackoverflow.com/a/58454949/8548472
103
#ifdef ANDROID
104
    const auto tmp_dir = std::filesystem::path(mavsdk_temp_path);
105
#else
106
    const auto tmp_dir = std::filesystem::temp_directory_path();
187✔
107
#endif
108

109
    std::random_device dev;
187✔
110
    std::mt19937 prng(dev());
187✔
111
    std::uniform_int_distribution<uint32_t> rand(0);
187✔
112

113
    static constexpr unsigned max_tries = 100;
114

115
    for (unsigned i = 0; i < max_tries; ++i) {
187✔
116
        std::stringstream ss;
187✔
117
        ss << prefix << '-' << std::hex << rand(prng);
187✔
118
        auto path = tmp_dir / ss.str();
374✔
119

120
        const auto created = std::filesystem::create_directory(path);
187✔
121
        if (created) {
187✔
122
            return path.string();
187✔
123
        }
124
    }
374✔
125

126
    LogErr() << "Could not create a temporary directory, aborting.";
×
127
    return std::nullopt;
×
128
}
187✔
129

130
std::string replace_non_ascii_and_whitespace(const std::string& input)
4✔
131
{
132
    std::string result = input;
4✔
133
    std::transform(result.begin(), result.end(), result.begin(), [](unsigned char ch) {
4✔
134
        if (ch > 127 || std::isspace(ch)) {
200✔
135
            return '_';
8✔
136
        }
137
        return static_cast<char>(ch);
192✔
138
    });
139
    return result;
4✔
140
}
141

142
} // namespace mavsdk
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc