1 /*
2 * Copyright (c) 2025 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "mkdir_core.h"
17
18 #include <cstring>
19 #include <ctime>
20 #include <iostream>
21 #include <memory>
22 #include <sstream>
23 #include <unistd.h>
24
25 #include "filemgmt_libhilog.h"
26
27 #if !defined(WIN_PLATFORM) && !defined(IOS_PLATFORM)
28 #include "rust_file.h"
29 #endif
30
31 #ifdef FILE_API_TRACE
32 #include "hitrace_meter.h"
33 #endif
34
35 namespace OHOS {
36 namespace FileManagement {
37 namespace ModuleFileIO {
38 using namespace std;
39
UvAccess(const string & path,int mode)40 static int UvAccess(const string &path, int mode)
41 {
42 std::unique_ptr<uv_fs_t, decltype(FsUtils::FsReqCleanup) *> accessReq = { new uv_fs_t, FsUtils::FsReqCleanup };
43 if (!accessReq) {
44 HILOGE("Failed to request heap memory.");
45 return ENOMEM;
46 }
47 return uv_fs_access(nullptr, accessReq.get(), path.c_str(), mode, nullptr);
48 }
49
MkdirCore(const string & path)50 static int MkdirCore(const string &path)
51 {
52 std::unique_ptr<uv_fs_t, decltype(FsUtils::FsReqCleanup) *> mkdirReq = { new uv_fs_t, FsUtils::FsReqCleanup };
53 if (!mkdirReq) {
54 HILOGE("Failed to request heap memory.");
55 return ENOMEM;
56 }
57 return uv_fs_mkdir(nullptr, mkdirReq.get(), path.c_str(), DIR_DEFAULT_PERM, nullptr);
58 }
59
MkdirExec(const string & path,bool recursion,bool hasOption)60 static int32_t MkdirExec(const string &path, bool recursion, bool hasOption)
61 {
62 #if !defined(WIN_PLATFORM) && !defined(IOS_PLATFORM)
63 if (hasOption) {
64 int ret = UvAccess(path, 0);
65 if (ret == ERRNO_NOERR) {
66 HILOGD("The path already exists");
67 return EEXIST;
68 }
69 if (ret != -ENOENT) {
70 HILOGE("Failed to check for illegal path or request for heap memory");
71 return ret;
72 }
73 if (::Mkdirs(path.c_str(), static_cast<MakeDirectionMode>(recursion)) < 0) {
74 HILOGD("Failed to create directories, error: %{public}d", errno);
75 return errno;
76 }
77 ret = UvAccess(path, 0);
78 if (ret) {
79 HILOGE("Failed to verify the result of Mkdirs function");
80 return ret;
81 }
82 return ERRNO_NOERR;
83 }
84 #endif
85 int ret = MkdirCore(path);
86 if (ret) {
87 HILOGD("Failed to create directory");
88 return ret;
89 }
90 return ERRNO_NOERR;
91 }
92
DoMkdir(const std::string & path,std::optional<bool> recursion)93 FsResult<void> MkdirCore::DoMkdir(const std::string &path, std::optional<bool> recursion)
94 {
95 bool hasOption = false;
96 bool mkdirRecursion = false;
97 #if !defined(WIN_PLATFORM) && !defined(IOS_PLATFORM)
98 hasOption = recursion.has_value();
99 if (hasOption) {
100 mkdirRecursion = recursion.value();
101 }
102 #endif
103 auto err = MkdirExec(path, mkdirRecursion, hasOption);
104 if (err) {
105 return FsResult<void>::Error(err);
106 }
107 return FsResult<void>::Success();
108 }
109
110 } // namespace ModuleFileIO
111 } // namespace FileManagement
112 } // namespace OHOS