1fa7767c5Sopenharmony_ci/*
2fa7767c5Sopenharmony_ci * Copyright (c) 2022-2022 Huawei Device Co., Ltd.
3fa7767c5Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4fa7767c5Sopenharmony_ci * you may not use this file except in compliance with the License.
5fa7767c5Sopenharmony_ci * You may obtain a copy of the License at
6fa7767c5Sopenharmony_ci *
7fa7767c5Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8fa7767c5Sopenharmony_ci *
9fa7767c5Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10fa7767c5Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11fa7767c5Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12fa7767c5Sopenharmony_ci * See the License for the specific language governing permissions and
13fa7767c5Sopenharmony_ci * limitations under the License.
14fa7767c5Sopenharmony_ci */
15fa7767c5Sopenharmony_ci#define HST_LOG_TAG "FileSystem"
16fa7767c5Sopenharmony_ci
17fa7767c5Sopenharmony_ci#include "osal/filesystem/file_system.h"
18fa7767c5Sopenharmony_ci#ifdef _WIN32
19fa7767c5Sopenharmony_ci#include <direct.h>
20fa7767c5Sopenharmony_ci#include <fcntl.h>
21fa7767c5Sopenharmony_ci#include <windows.h>
22fa7767c5Sopenharmony_ci#else
23fa7767c5Sopenharmony_ci#include <unistd.h>
24fa7767c5Sopenharmony_ci#endif
25fa7767c5Sopenharmony_ci
26fa7767c5Sopenharmony_ci#include <cerrno>
27fa7767c5Sopenharmony_ci#include <cstdio>
28fa7767c5Sopenharmony_ci#include <cstdlib>
29fa7767c5Sopenharmony_ci#include <cstring>
30fa7767c5Sopenharmony_ci#include <dirent.h>
31fa7767c5Sopenharmony_ci#include "common/log.h"
32fa7767c5Sopenharmony_ci
33fa7767c5Sopenharmony_cinamespace {
34fa7767c5Sopenharmony_ciconstexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, LOG_DOMAIN_FOUNDATION, "FileSystem" };
35fa7767c5Sopenharmony_ci}
36fa7767c5Sopenharmony_ci
37fa7767c5Sopenharmony_ci#ifndef _WIN32
38fa7767c5Sopenharmony_cimode_t umask(mode_t mask);
39fa7767c5Sopenharmony_ci#endif
40fa7767c5Sopenharmony_ci
41fa7767c5Sopenharmony_cinamespace OHOS {
42fa7767c5Sopenharmony_cinamespace Media {
43fa7767c5Sopenharmony_cibool FileSystem::IsRegularFile(const std::string& path)
44fa7767c5Sopenharmony_ci{
45fa7767c5Sopenharmony_ci    struct stat s {};
46fa7767c5Sopenharmony_ci    return (stat(path.c_str(), &s) == 0) && S_ISREG(s.st_mode);
47fa7767c5Sopenharmony_ci}
48fa7767c5Sopenharmony_ci
49fa7767c5Sopenharmony_cibool FileSystem::IsFdValid(int32_t fd, struct stat& s)
50fa7767c5Sopenharmony_ci{
51fa7767c5Sopenharmony_ci    return fstat(fd, &s) == 0;
52fa7767c5Sopenharmony_ci}
53fa7767c5Sopenharmony_ci
54fa7767c5Sopenharmony_cibool FileSystem::IsRegularFile(int32_t fd)
55fa7767c5Sopenharmony_ci{
56fa7767c5Sopenharmony_ci    struct stat s {};
57fa7767c5Sopenharmony_ci    return IsFdValid(fd, s) && S_ISREG(s.st_mode);
58fa7767c5Sopenharmony_ci}
59fa7767c5Sopenharmony_ci
60fa7767c5Sopenharmony_cibool FileSystem::IsSocketFile(int32_t fd)
61fa7767c5Sopenharmony_ci{
62fa7767c5Sopenharmony_ci    struct stat s {};
63fa7767c5Sopenharmony_ci    return IsFdValid(fd, s) && S_ISSOCK(s.st_mode);
64fa7767c5Sopenharmony_ci}
65fa7767c5Sopenharmony_ci
66fa7767c5Sopenharmony_cibool FileSystem::IsSeekable(int32_t fd)
67fa7767c5Sopenharmony_ci{
68fa7767c5Sopenharmony_ci    return IsRegularFile(fd) && lseek(fd, 0, SEEK_CUR) != -1;
69fa7767c5Sopenharmony_ci}
70fa7767c5Sopenharmony_ci
71fa7767c5Sopenharmony_cibool FileSystem::IsDirectory(const std::string& path)
72fa7767c5Sopenharmony_ci{
73fa7767c5Sopenharmony_ci    struct stat s {};
74fa7767c5Sopenharmony_ci    return (stat(path.c_str(), &s) == 0) && S_ISDIR(s.st_mode);
75fa7767c5Sopenharmony_ci}
76fa7767c5Sopenharmony_ci
77fa7767c5Sopenharmony_ci// judge regular file, directory, symbolic link file path exists
78fa7767c5Sopenharmony_cibool FileSystem::IsExists(const std::string& path)
79fa7767c5Sopenharmony_ci{
80fa7767c5Sopenharmony_ci    return access(path.c_str(), 0) != -1;
81fa7767c5Sopenharmony_ci}
82fa7767c5Sopenharmony_ci
83fa7767c5Sopenharmony_cibool FileSystem::MakeDir(const std::string& path)
84fa7767c5Sopenharmony_ci{
85fa7767c5Sopenharmony_ci#ifdef _WIN32
86fa7767c5Sopenharmony_ci    if (mkdir(path.c_str()) == -1) {
87fa7767c5Sopenharmony_ci        MEDIA_LOG_E("Fail to create dir " PUBLIC_LOG_S " due to " PUBLIC_LOG_S, path.c_str(), std::strerror(errno));
88fa7767c5Sopenharmony_ci        return false;
89fa7767c5Sopenharmony_ci    }
90fa7767c5Sopenharmony_ci#else
91fa7767c5Sopenharmony_ci#ifndef OHOS_LITE
92fa7767c5Sopenharmony_ci    auto oldMask = umask(0);
93fa7767c5Sopenharmony_ci#endif
94fa7767c5Sopenharmony_ci    if (mkdir(path.c_str(), 755) == -1) { // 755 directory access permissions
95fa7767c5Sopenharmony_ci        MEDIA_LOG_E("Fail to create dir " PUBLIC_LOG_S " due to " PUBLIC_LOG_S, path.c_str(), std::strerror(errno));
96fa7767c5Sopenharmony_ci#ifndef OHOS_LITE
97fa7767c5Sopenharmony_ci        umask(oldMask);
98fa7767c5Sopenharmony_ci#endif
99fa7767c5Sopenharmony_ci        return false;
100fa7767c5Sopenharmony_ci    }
101fa7767c5Sopenharmony_ci#ifndef OHOS_LITE
102fa7767c5Sopenharmony_ci    umask(oldMask);
103fa7767c5Sopenharmony_ci#endif
104fa7767c5Sopenharmony_ci#endif
105fa7767c5Sopenharmony_ci    return true;
106fa7767c5Sopenharmony_ci}
107fa7767c5Sopenharmony_ci
108fa7767c5Sopenharmony_cibool FileSystem::MakeMultipleDir(const std::string& path)
109fa7767c5Sopenharmony_ci{
110fa7767c5Sopenharmony_ci    FALSE_RETURN_V(!IsExists(path), true);
111fa7767c5Sopenharmony_ci
112fa7767c5Sopenharmony_ci    // pos is 1, not 0  example: D:/a/b, /local/tmp/
113fa7767c5Sopenharmony_ci    // Avoid Linux root path before is empty string, which makes it impossible to judge whether the path exists
114fa7767c5Sopenharmony_ci    auto index = path.find('/', 1);
115fa7767c5Sopenharmony_ci    while (index != std::string::npos) {
116fa7767c5Sopenharmony_ci        std::string tPath = path.substr(0, index);
117fa7767c5Sopenharmony_ci        FALSE_RETURN_V(IsExists(tPath) || MakeDir(tPath), false);
118fa7767c5Sopenharmony_ci        index = path.find('/', index + 1);
119fa7767c5Sopenharmony_ci    }
120fa7767c5Sopenharmony_ci    return path[path.size() - 1] == '/' || MakeDir(path);
121fa7767c5Sopenharmony_ci}
122fa7767c5Sopenharmony_ci
123fa7767c5Sopenharmony_civoid FileSystem::ClearFileContent(const std::string& fullPath)
124fa7767c5Sopenharmony_ci{
125fa7767c5Sopenharmony_ci    MEDIA_LOG_I("Clear file content path : " PUBLIC_LOG_S, fullPath.c_str());
126fa7767c5Sopenharmony_ci    auto filePtr = fopen(fullPath.c_str(), "w+");
127fa7767c5Sopenharmony_ci    if (!filePtr) {
128fa7767c5Sopenharmony_ci        MEDIA_LOG_E("Clear file content fail.");
129fa7767c5Sopenharmony_ci        return;
130fa7767c5Sopenharmony_ci    }
131fa7767c5Sopenharmony_ci    fclose(filePtr);
132fa7767c5Sopenharmony_ci}
133fa7767c5Sopenharmony_ci
134fa7767c5Sopenharmony_civoid FileSystem::RemoveFilesInDir(const std::string& path)
135fa7767c5Sopenharmony_ci{
136fa7767c5Sopenharmony_ci    DIR *directory;
137fa7767c5Sopenharmony_ci    if ((directory = opendir(path.c_str())) != nullptr) {
138fa7767c5Sopenharmony_ci        struct dirent *info;
139fa7767c5Sopenharmony_ci        while ((info = readdir(directory)) != nullptr) {
140fa7767c5Sopenharmony_ci            if (strcmp(info->d_name, ".") == 0 || strcmp(info->d_name, "..") == 0) {
141fa7767c5Sopenharmony_ci                continue;
142fa7767c5Sopenharmony_ci            }
143fa7767c5Sopenharmony_ci            std::string fullPath = path + "/" + info->d_name;
144fa7767c5Sopenharmony_ci            MEDIA_LOG_D("Remove file : " PUBLIC_LOG_S, fullPath.c_str());
145fa7767c5Sopenharmony_ci            NZERO_LOG(remove(fullPath.c_str()));
146fa7767c5Sopenharmony_ci        }
147fa7767c5Sopenharmony_ci        closedir(directory);
148fa7767c5Sopenharmony_ci    }
149fa7767c5Sopenharmony_ci}
150fa7767c5Sopenharmony_ci} // namespace Media
151fa7767c5Sopenharmony_ci} // namespace OHOS