• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-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 "rmdirent.h"
17 
18 #include <cstring>
19 #include <dirent.h>
20 #include <tuple>
21 #include <unistd.h>
22 
23 #include <sys/stat.h>
24 #include <sys/types.h>
25 
26 #include "n_async_work_callback.h"
27 #include "n_async_work_promise.h"
28 #include "n_func_arg.h"
29 
30 namespace OHOS {
31 namespace DistributedFS {
32 namespace ModuleFileIO {
33 using namespace std;
34 
ParseJsPath(napi_env env,napi_value pathFromJs)35 static tuple<bool, unique_ptr<char[]>> ParseJsPath(napi_env env, napi_value pathFromJs)
36 {
37     auto [succ, path, ignore] = NVal(env, pathFromJs).ToUTF8StringPath();
38     return {succ, move(path)};
39 }
40 
rmdirent(napi_env env,string path)41 static UniError rmdirent(napi_env env, string path)
42 {
43     if (rmdir(path.c_str()) == 0) {
44         return UniError(ERRNO_NOERR);
45     }
46     auto dir = opendir(path.c_str());
47     if (!dir) {
48         return UniError(errno);
49     }
50     struct dirent* entry = readdir(dir);
51     while (entry) {
52         if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {
53             entry = readdir(dir);
54             continue;
55         }
56         struct stat fileInformation;
57         string filePath = path + '/';
58         filePath.insert(filePath.length(), entry->d_name);
59         if (stat(filePath.c_str(), &fileInformation) != 0) {
60             closedir(dir);
61             return UniError(errno);
62         }
63         if ((fileInformation.st_mode & S_IFMT) == S_IFDIR) {
64             auto err = rmdirent(env, filePath);
65             if (err) {
66                 closedir(dir);
67                 return err;
68             }
69         } else {
70             if (unlink(filePath.c_str()) != 0) {
71                 closedir(dir);
72                 return UniError(errno);
73             }
74         }
75         entry = readdir(dir);
76     }
77     closedir(dir);
78     if (rmdir(path.c_str()) != 0) {
79         return UniError(errno);
80     }
81     return UniError(ERRNO_NOERR);
82 }
83 
Sync(napi_env env,napi_callback_info info)84 napi_value Rmdirent::Sync(napi_env env, napi_callback_info info)
85 {
86     NFuncArg funcArg(env, info);
87 
88     if (!funcArg.InitArgs(NARG_CNT::ONE)) {
89         UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched");
90         return nullptr;
91     }
92 
93     auto [succ, path] = ParseJsPath(env, funcArg[NARG_POS::FIRST]);
94     if (!succ) {
95         UniError(EINVAL).ThrowErr(env, "Invalid path");
96         return nullptr;
97     }
98 
99     auto err = rmdirent(env, string(path.get()));
100     if (err) {
101         err.ThrowErr(env);
102         return nullptr;
103     }
104     return NVal::CreateUndefined(env).val_;
105 }
106 
Async(napi_env env,napi_callback_info info)107 napi_value Rmdirent::Async(napi_env env, napi_callback_info info)
108 {
109     NFuncArg funcArg(env, info);
110     if (!funcArg.InitArgs(NARG_CNT::ONE, NARG_CNT::TWO)) {
111         UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched");
112         return nullptr;
113     }
114 
115     auto [succ, path] = ParseJsPath(env, funcArg[NARG_POS::FIRST]);
116     if (!succ) {
117         UniError(EINVAL).ThrowErr(env, "Invalid path");
118         return nullptr;
119     }
120 
121     auto cbExec = [path = string(path.get())](napi_env env) -> UniError {
122         return rmdirent(env, path);
123     };
124     auto cbCompl = [](napi_env env, UniError err) -> NVal {
125         if (err) {
126             return { env, err.GetNapiErr(env) };
127         } else {
128             return NVal::CreateUndefined(env);
129         }
130     };
131 
132     NVal thisVar(env, funcArg.GetThisVar());
133     size_t argc = funcArg.GetArgc();
134     if (argc == NARG_CNT::ONE) {
135         return NAsyncWorkPromise(env, thisVar).Schedule(rmdirProcedureName, cbExec, cbCompl).val_;
136     } else {
137         NVal cb(env, funcArg[NARG_POS::SECOND]);
138         return NAsyncWorkCallback(env, thisVar, cb).Schedule(rmdirProcedureName, cbExec, cbCompl).val_;
139     }
140 }
141 } // namespace ModuleFileIO
142 } // namespace DistributedFS
143 } // namespace OHOS