15bebb993Sopenharmony_ci/* 25bebb993Sopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd. 35bebb993Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 45bebb993Sopenharmony_ci * you may not use this file except in compliance with the License. 55bebb993Sopenharmony_ci * You may obtain a copy of the License at 65bebb993Sopenharmony_ci * 75bebb993Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 85bebb993Sopenharmony_ci * 95bebb993Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 105bebb993Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 115bebb993Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 125bebb993Sopenharmony_ci * See the License for the specific language governing permissions and 135bebb993Sopenharmony_ci * limitations under the License. 145bebb993Sopenharmony_ci */ 155bebb993Sopenharmony_ci 165bebb993Sopenharmony_ci#include "ffi_remote_data.h" 175bebb993Sopenharmony_ci#include "cj_common_ffi.h" 185bebb993Sopenharmony_ci#include "uni_error.h" 195bebb993Sopenharmony_ci#include "uri.h" 205bebb993Sopenharmony_ci#include "open.h" 215bebb993Sopenharmony_ci#include "datashare_helper.h" 225bebb993Sopenharmony_ci#include "utils.h" 235bebb993Sopenharmony_ci#include "iremote_stub.h" 245bebb993Sopenharmony_ci#include "file_uri.h" 255bebb993Sopenharmony_ci#include "want.h" 265bebb993Sopenharmony_ci#include "ability_manager_client.h" 275bebb993Sopenharmony_ci#include "remote_uri.h" 285bebb993Sopenharmony_ci#include "file_utils.h" 295bebb993Sopenharmony_ci#include "securec.h" 305bebb993Sopenharmony_ci#include "file_impl.h" 315bebb993Sopenharmony_ci 325bebb993Sopenharmony_cistatic const std::string PROCEDURE_OPEN_NAME = "FileIOOpen"; 335bebb993Sopenharmony_cistatic const std::string MEDIALIBRARY_DATA_URI = "datashare:///media"; 345bebb993Sopenharmony_cistatic const std::string FILE_DATA_URI = "file://"; 355bebb993Sopenharmony_cistatic const std::string PATH_SHARE = "/data/storage/el2/share"; 365bebb993Sopenharmony_cistatic const std::string MODE_RW = "/rw/"; 375bebb993Sopenharmony_cistatic const std::string MODE_R = "/r/"; 385bebb993Sopenharmony_cistatic const std::string DOCS = "docs"; 395bebb993Sopenharmony_cistatic const std::string DATASHARE = "datashare"; 405bebb993Sopenharmony_cistatic const std::string SCHEME_BROKER = "content"; 415bebb993Sopenharmony_ciconstexpr uint32_t MAX_WANT_FLAG = 4; 425bebb993Sopenharmony_ci 435bebb993Sopenharmony_cinamespace { 445bebb993Sopenharmony_ciusing Uri = OHOS::Uri; 455bebb993Sopenharmony_ciusing namespace OHOS; 465bebb993Sopenharmony_ciusing namespace DistributedFS; 475bebb993Sopenharmony_ciusing namespace OHOS::CJSystemapi; 485bebb993Sopenharmony_ciusing namespace OHOS::CJSystemapi::FileFs; 495bebb993Sopenharmony_ciusing namespace OHOS::FileManagement; 505bebb993Sopenharmony_ciusing namespace OHOS::FileManagement::ModuleFileIO; 515bebb993Sopenharmony_ciusing namespace OHOS::DistributedFS::ModuleRemoteUri; 525bebb993Sopenharmony_ciusing namespace std; 535bebb993Sopenharmony_ci 545bebb993Sopenharmony_cistatic int OpenFileByPath(const std::string &path, unsigned int mode) 555bebb993Sopenharmony_ci{ 565bebb993Sopenharmony_ci std::unique_ptr<uv_fs_t, decltype(CommonFunc::FsReqCleanup)*> open_req = { 575bebb993Sopenharmony_ci new (std::nothrow) uv_fs_t, CommonFunc::FsReqCleanup }; 585bebb993Sopenharmony_ci if (!open_req) { 595bebb993Sopenharmony_ci LOGE("Failed to request heap memory."); 605bebb993Sopenharmony_ci return -ENOMEM; 615bebb993Sopenharmony_ci } 625bebb993Sopenharmony_ci int ret = uv_fs_open(nullptr, open_req.get(), path.c_str(), mode, S_IRUSR | 635bebb993Sopenharmony_ci S_IWUSR | S_IRGRP | S_IWGRP, nullptr); 645bebb993Sopenharmony_ci if (ret < 0) { 655bebb993Sopenharmony_ci LOGE("Failed to open OpenFileByPath error %{public}d", ret); 665bebb993Sopenharmony_ci } 675bebb993Sopenharmony_ci return ret; 685bebb993Sopenharmony_ci} 695bebb993Sopenharmony_ci 705bebb993Sopenharmony_cistatic int OpenFileByDatashare(const std::string &path, int64_t flags) 715bebb993Sopenharmony_ci{ 725bebb993Sopenharmony_ci std::shared_ptr<DataShare::DataShareHelper> dataShareHelper = nullptr; 735bebb993Sopenharmony_ci sptr<FileIoToken> remote = new (std::nothrow) OHOS::IRemoteStub<FileIoToken>(); 745bebb993Sopenharmony_ci if (!remote) { 755bebb993Sopenharmony_ci LOGE("Failed to get remote object"); 765bebb993Sopenharmony_ci return -ENOMEM; 775bebb993Sopenharmony_ci } 785bebb993Sopenharmony_ci 795bebb993Sopenharmony_ci dataShareHelper = DataShare::DataShareHelper::Creator(remote->AsObject(), MEDIALIBRARY_DATA_URI); 805bebb993Sopenharmony_ci if (!dataShareHelper) { 815bebb993Sopenharmony_ci LOGE("Failed to connect to datashare"); 825bebb993Sopenharmony_ci return -E_PERMISSION; 835bebb993Sopenharmony_ci } 845bebb993Sopenharmony_ci Uri uri(path); 855bebb993Sopenharmony_ci int fd = dataShareHelper->OpenFile(uri, CommonFunc::GetModeFromFlags(flags)); 865bebb993Sopenharmony_ci return fd; 875bebb993Sopenharmony_ci} 885bebb993Sopenharmony_ci 895bebb993Sopenharmony_cistatic std::tuple<int, std::string> OpenByFileDataUri(Uri &uri, const std::string &uriStr, unsigned int mode) 905bebb993Sopenharmony_ci{ 915bebb993Sopenharmony_ci std::string bundleName = uri.GetAuthority(); 925bebb993Sopenharmony_ci AppFileService::ModuleFileUri::FileUri fileUri(uriStr); 935bebb993Sopenharmony_ci std::string realPath = fileUri.GetRealPath(); 945bebb993Sopenharmony_ci if ((bundleName == MEDIA || bundleName == DOCS) && access(realPath.c_str(), F_OK) != 0) { 955bebb993Sopenharmony_ci int res = OpenFileByDatashare(uri.ToString(), mode); 965bebb993Sopenharmony_ci if (res < 0) { 975bebb993Sopenharmony_ci LOGE("Failed to open file by Datashare error %{public}d", res); 985bebb993Sopenharmony_ci } 995bebb993Sopenharmony_ci return { res, uri.ToString() }; 1005bebb993Sopenharmony_ci } 1015bebb993Sopenharmony_ci int ret = OpenFileByPath(realPath, mode); 1025bebb993Sopenharmony_ci if (ret < 0) { 1035bebb993Sopenharmony_ci if (bundleName == MEDIA) { 1045bebb993Sopenharmony_ci ret = OpenFileByDatashare(uriStr, mode); 1055bebb993Sopenharmony_ci if (ret < 0) { 1065bebb993Sopenharmony_ci LOGE("Failed to open file by Datashare error %{public}d", ret); 1075bebb993Sopenharmony_ci } 1085bebb993Sopenharmony_ci } else { 1095bebb993Sopenharmony_ci LOGE("Failed to open file for libuv error %{public}d", ret); 1105bebb993Sopenharmony_ci } 1115bebb993Sopenharmony_ci } 1125bebb993Sopenharmony_ci return { ret, uriStr }; 1135bebb993Sopenharmony_ci} 1145bebb993Sopenharmony_ci 1155bebb993Sopenharmony_cistatic std::tuple<int, std::string> OpenFileByBroker(const Uri &uri, uint32_t mode) 1165bebb993Sopenharmony_ci{ 1175bebb993Sopenharmony_ci uint32_t flag = (mode % MAX_WANT_FLAG) > 0 ? 1185bebb993Sopenharmony_ci AAFwk::Want::FLAG_AUTH_WRITE_URI_PERMISSION : 1195bebb993Sopenharmony_ci AAFwk::Want::FLAG_AUTH_READ_URI_PERMISSION; 1205bebb993Sopenharmony_ci int ret = AAFwk::AbilityManagerClient::GetInstance()->OpenFile(uri, flag); 1215bebb993Sopenharmony_ci if (ret < 0) { 1225bebb993Sopenharmony_ci LOGE("Failed to open file by Broker error %{public}d", ret); 1235bebb993Sopenharmony_ci } 1245bebb993Sopenharmony_ci return { ret, uri.ToString() }; 1255bebb993Sopenharmony_ci} 1265bebb993Sopenharmony_ci 1275bebb993Sopenharmony_cistatic std::tuple<int, std::string> CheckDataShareUri(const std::string &path, uint32_t mode) 1285bebb993Sopenharmony_ci{ 1295bebb993Sopenharmony_ci // datashare:////#fdFromBinder=xx 1305bebb993Sopenharmony_ci int fd = -1; 1315bebb993Sopenharmony_ci if (RemoteUri::IsRemoteUri(path, fd, mode)) { 1325bebb993Sopenharmony_ci if (fd >= 0) { 1335bebb993Sopenharmony_ci return { fd, path }; 1345bebb993Sopenharmony_ci } 1355bebb993Sopenharmony_ci LOGE("Failed to open file by RemoteUri"); 1365bebb993Sopenharmony_ci } 1375bebb993Sopenharmony_ci return { -EINVAL, path }; 1385bebb993Sopenharmony_ci} 1395bebb993Sopenharmony_ci 1405bebb993Sopenharmony_cistatic std::tuple<int, std::string> OpenFileByUri(const std::string &path, uint32_t mode) 1415bebb993Sopenharmony_ci{ 1425bebb993Sopenharmony_ci Uri uri(path); 1435bebb993Sopenharmony_ci std::string uriType = uri.GetScheme(); 1445bebb993Sopenharmony_ci if (uriType == SCHEME_FILE) { 1455bebb993Sopenharmony_ci return OpenByFileDataUri(uri, path, mode); 1465bebb993Sopenharmony_ci } else if (uriType == SCHEME_BROKER) { 1475bebb993Sopenharmony_ci return OpenFileByBroker(uri, mode); 1485bebb993Sopenharmony_ci } else if (uriType == DATASHARE) { 1495bebb993Sopenharmony_ci return CheckDataShareUri(path, mode); 1505bebb993Sopenharmony_ci } 1515bebb993Sopenharmony_ci LOGE("Failed to open file by invalid uri"); 1525bebb993Sopenharmony_ci return { -EINVAL, path }; 1535bebb993Sopenharmony_ci} 1545bebb993Sopenharmony_ci 1555bebb993Sopenharmony_ciFileEntity* InstantiateFile(int fd, const std::string& pathOrUri, bool isUri) 1565bebb993Sopenharmony_ci{ 1575bebb993Sopenharmony_ci auto fdg = CreateUniquePtr<DistributedFS::FDGuard>(fd, false); 1585bebb993Sopenharmony_ci if (fdg == nullptr) { 1595bebb993Sopenharmony_ci LOGE("Failed to request heap memory."); 1605bebb993Sopenharmony_ci close(fd); 1615bebb993Sopenharmony_ci return nullptr; 1625bebb993Sopenharmony_ci } 1635bebb993Sopenharmony_ci FileEntity *fileEntity = new(std::nothrow) FileEntity(); 1645bebb993Sopenharmony_ci if (fileEntity == nullptr) { 1655bebb993Sopenharmony_ci return nullptr; 1665bebb993Sopenharmony_ci } 1675bebb993Sopenharmony_ci fileEntity->fd_.swap(fdg); 1685bebb993Sopenharmony_ci if (isUri) { 1695bebb993Sopenharmony_ci fileEntity->path_ = ""; 1705bebb993Sopenharmony_ci fileEntity->uri_ = pathOrUri; 1715bebb993Sopenharmony_ci } else { 1725bebb993Sopenharmony_ci fileEntity->path_ = pathOrUri; 1735bebb993Sopenharmony_ci fileEntity->uri_ = ""; 1745bebb993Sopenharmony_ci } 1755bebb993Sopenharmony_ci return fileEntity; 1765bebb993Sopenharmony_ci} 1775bebb993Sopenharmony_ci 1785bebb993Sopenharmony_cistatic tuple<bool, unsigned int> GetCjFlags(int64_t mode) 1795bebb993Sopenharmony_ci{ 1805bebb993Sopenharmony_ci unsigned int flags = O_RDONLY; 1815bebb993Sopenharmony_ci unsigned int invalidMode = (O_WRONLY | O_RDWR); 1825bebb993Sopenharmony_ci if (mode < 0 || (static_cast<unsigned int>(mode) & invalidMode) == invalidMode) { 1835bebb993Sopenharmony_ci LOGE("Invalid mode"); 1845bebb993Sopenharmony_ci return { false, flags }; 1855bebb993Sopenharmony_ci } 1865bebb993Sopenharmony_ci flags = static_cast<unsigned int>(mode); 1875bebb993Sopenharmony_ci (void)CommonFunc::ConvertCjFlags(flags); 1885bebb993Sopenharmony_ci return { true, flags }; 1895bebb993Sopenharmony_ci} 1905bebb993Sopenharmony_ci} 1915bebb993Sopenharmony_ci 1925bebb993Sopenharmony_cinamespace OHOS { 1935bebb993Sopenharmony_cinamespace CJSystemapi { 1945bebb993Sopenharmony_cinamespace FileFs { 1955bebb993Sopenharmony_ciusing namespace OHOS::FFI; 1965bebb993Sopenharmony_cistd::tuple<int32_t, sptr<FileEntity>> FileEntity::Open(const char* path, int64_t mode) 1975bebb993Sopenharmony_ci{ 1985bebb993Sopenharmony_ci auto [succMode, flags] = GetCjFlags(mode); 1995bebb993Sopenharmony_ci if (!succMode) { 2005bebb993Sopenharmony_ci return {EINVAL, nullptr}; 2015bebb993Sopenharmony_ci } 2025bebb993Sopenharmony_ci std::string pathStr(path); 2035bebb993Sopenharmony_ci#if !defined(WIN_PLATFORM) && !defined(IOS_PLATFORM) 2045bebb993Sopenharmony_ci if (pathStr.find("://") != string::npos) { 2055bebb993Sopenharmony_ci auto [res, uriStr] = OpenFileByUri(pathStr, flags); 2065bebb993Sopenharmony_ci if (res < 0) { 2075bebb993Sopenharmony_ci return {res, nullptr}; 2085bebb993Sopenharmony_ci } 2095bebb993Sopenharmony_ci auto fileEntity = InstantiateFile(res, uriStr, true); 2105bebb993Sopenharmony_ci if (fileEntity == nullptr) { 2115bebb993Sopenharmony_ci return { ENOMEM, nullptr}; 2125bebb993Sopenharmony_ci } 2135bebb993Sopenharmony_ci auto fileUri = FFIData::Create<FileEntity>(std::move(fileEntity->fd_), fileEntity->path_, fileEntity->uri_); 2145bebb993Sopenharmony_ci delete(fileEntity); 2155bebb993Sopenharmony_ci fileEntity = nullptr; 2165bebb993Sopenharmony_ci if (!fileUri) { 2175bebb993Sopenharmony_ci return {ENOMEM, nullptr}; 2185bebb993Sopenharmony_ci } 2195bebb993Sopenharmony_ci return {SUCCESS_CODE, fileUri}; 2205bebb993Sopenharmony_ci } 2215bebb993Sopenharmony_ci#endif 2225bebb993Sopenharmony_ci int ret = OpenFileByPath(pathStr, flags); 2235bebb993Sopenharmony_ci if (ret < 0) { 2245bebb993Sopenharmony_ci LOGE("Failed to open file for libuv error %{public}d", ret); 2255bebb993Sopenharmony_ci return {ret, nullptr}; 2265bebb993Sopenharmony_ci } 2275bebb993Sopenharmony_ci auto file = InstantiateFile(ret, pathStr, false); 2285bebb993Sopenharmony_ci if (file == nullptr) { 2295bebb993Sopenharmony_ci return { ENOMEM, nullptr}; 2305bebb993Sopenharmony_ci } 2315bebb993Sopenharmony_ci auto filePath = FFIData::Create<FileEntity>(std::move(file->fd_), file->path_, file->uri_); 2325bebb993Sopenharmony_ci delete(file); 2335bebb993Sopenharmony_ci file = nullptr; 2345bebb993Sopenharmony_ci if (!filePath) { 2355bebb993Sopenharmony_ci return {ENOMEM, nullptr}; 2365bebb993Sopenharmony_ci } 2375bebb993Sopenharmony_ci return {SUCCESS_CODE, filePath}; 2385bebb993Sopenharmony_ci} 2395bebb993Sopenharmony_ci 2405bebb993Sopenharmony_cistd::tuple<int32_t, sptr<FileEntity>> FileEntity::Dup(int32_t fd) 2415bebb993Sopenharmony_ci{ 2425bebb993Sopenharmony_ci LOGI("FS_TEST::FileEntity::Dup start"); 2435bebb993Sopenharmony_ci if (fd < 0) { 2445bebb993Sopenharmony_ci LOGE("Invalid fd"); 2455bebb993Sopenharmony_ci return {EINVAL, nullptr}; 2465bebb993Sopenharmony_ci } 2475bebb993Sopenharmony_ci int dstFd = dup(fd); 2485bebb993Sopenharmony_ci if (dstFd < 0) { 2495bebb993Sopenharmony_ci LOGE("Failed to dup fd, errno: %{public}d", errno); 2505bebb993Sopenharmony_ci return {errno, nullptr}; 2515bebb993Sopenharmony_ci } 2525bebb993Sopenharmony_ci unique_ptr<uv_fs_t, decltype(CommonFunc::FsReqCleanup)*> readlink_req = { 2535bebb993Sopenharmony_ci new (std::nothrow) uv_fs_t, CommonFunc::FsReqCleanup }; 2545bebb993Sopenharmony_ci if (!readlink_req) { 2555bebb993Sopenharmony_ci LOGE("Failed to request heap memory."); 2565bebb993Sopenharmony_ci return {ENOMEM, nullptr}; 2575bebb993Sopenharmony_ci } 2585bebb993Sopenharmony_ci string path = "/proc/self/fd/" + to_string(dstFd); 2595bebb993Sopenharmony_ci int ret = uv_fs_readlink(nullptr, readlink_req.get(), path.c_str(), nullptr); 2605bebb993Sopenharmony_ci if (ret < 0) { 2615bebb993Sopenharmony_ci LOGE("Failed to readlink fd, ret: %{public}d", ret); 2625bebb993Sopenharmony_ci return {ret, nullptr}; 2635bebb993Sopenharmony_ci } 2645bebb993Sopenharmony_ci auto fdPrt = CreateUniquePtr<DistributedFS::FDGuard>(dstFd, false); 2655bebb993Sopenharmony_ci if (fdPrt == nullptr) { 2665bebb993Sopenharmony_ci LOGE("Failed to request heap memory."); 2675bebb993Sopenharmony_ci return {ENOMEM, nullptr}; 2685bebb993Sopenharmony_ci } 2695bebb993Sopenharmony_ci auto pathStr = string(static_cast<const char *>(readlink_req->ptr)); 2705bebb993Sopenharmony_ci auto fileEntity = FFIData::Create<FileEntity>(std::move(fdPrt), pathStr, ""); 2715bebb993Sopenharmony_ci if (!fileEntity) { 2725bebb993Sopenharmony_ci return {ENOMEM, nullptr}; 2735bebb993Sopenharmony_ci } 2745bebb993Sopenharmony_ci return {SUCCESS_CODE, fileEntity}; 2755bebb993Sopenharmony_ci} 2765bebb993Sopenharmony_ci 2775bebb993Sopenharmony_cistatic tuple<int, unique_ptr<uv_fs_t, decltype(CommonFunc::FsReqCleanup)*>> RealPathCore(const string &srcPath) 2785bebb993Sopenharmony_ci{ 2795bebb993Sopenharmony_ci std::unique_ptr<uv_fs_t, decltype(CommonFunc::FsReqCleanup)*> realpath_req = { 2805bebb993Sopenharmony_ci new (std::nothrow) uv_fs_t, CommonFunc::FsReqCleanup }; 2815bebb993Sopenharmony_ci if (!realpath_req) { 2825bebb993Sopenharmony_ci LOGE("Failed to request heap memory."); 2835bebb993Sopenharmony_ci return { ENOMEM, move(realpath_req)}; 2845bebb993Sopenharmony_ci } 2855bebb993Sopenharmony_ci int ret = uv_fs_realpath(nullptr, realpath_req.get(), srcPath.c_str(), nullptr); 2865bebb993Sopenharmony_ci if (ret < 0) { 2875bebb993Sopenharmony_ci LOGE("Failed to realpath, ret: %{public}d", ret); 2885bebb993Sopenharmony_ci return { ret, move(realpath_req)}; 2895bebb993Sopenharmony_ci } 2905bebb993Sopenharmony_ci return { ERRNO_NOERR, move(realpath_req) }; 2915bebb993Sopenharmony_ci} 2925bebb993Sopenharmony_ci 2935bebb993Sopenharmony_ciint FileEntity::GetFD(int64_t id) 2945bebb993Sopenharmony_ci{ 2955bebb993Sopenharmony_ci auto fileEntity = FFIData::GetData<FileEntity>(id); 2965bebb993Sopenharmony_ci if (!fileEntity) { 2975bebb993Sopenharmony_ci LOGE("FileEntity instance not exist %{public}" PRId64, id); 2985bebb993Sopenharmony_ci return ERR_INVALID_INSTANCE_CODE; 2995bebb993Sopenharmony_ci } 3005bebb993Sopenharmony_ci return fileEntity->fd_.get()->GetFD(); 3015bebb993Sopenharmony_ci} 3025bebb993Sopenharmony_ci 3035bebb993Sopenharmony_ciconst char* FileEntity::GetPath(int64_t id) 3045bebb993Sopenharmony_ci{ 3055bebb993Sopenharmony_ci auto fileEntity = FFIData::GetData<FileEntity>(id); 3065bebb993Sopenharmony_ci if (!fileEntity) { 3075bebb993Sopenharmony_ci LOGE("FileEntity instance not exist %{public}" PRId64, id); 3085bebb993Sopenharmony_ci return nullptr; 3095bebb993Sopenharmony_ci } 3105bebb993Sopenharmony_ci auto [realPathRes, realPath] = RealPathCore(fileEntity->path_); 3115bebb993Sopenharmony_ci if (realPathRes != ERRNO_NOERR) { 3125bebb993Sopenharmony_ci return nullptr; 3135bebb993Sopenharmony_ci } 3145bebb993Sopenharmony_ci string tempPath = string(static_cast<char*>(realPath->ptr)); 3155bebb993Sopenharmony_ci char* value = static_cast<char*>(malloc((tempPath.size() + 1) * sizeof(char))); 3165bebb993Sopenharmony_ci if (value == nullptr) { 3175bebb993Sopenharmony_ci return nullptr; 3185bebb993Sopenharmony_ci } 3195bebb993Sopenharmony_ci if (strcpy_s(value, tempPath.size() + 1, tempPath.c_str()) != 0) { 3205bebb993Sopenharmony_ci free(value); 3215bebb993Sopenharmony_ci value = nullptr; 3225bebb993Sopenharmony_ci return nullptr; 3235bebb993Sopenharmony_ci } 3245bebb993Sopenharmony_ci return value; 3255bebb993Sopenharmony_ci} 3265bebb993Sopenharmony_ci 3275bebb993Sopenharmony_ciconst char* FileEntity::GetName(int64_t id) 3285bebb993Sopenharmony_ci{ 3295bebb993Sopenharmony_ci string path = FileEntity::GetPath(id); 3305bebb993Sopenharmony_ci auto pos = path.find_last_of('/'); 3315bebb993Sopenharmony_ci if (pos == string::npos) { 3325bebb993Sopenharmony_ci LOGE("Failed to split filename from path"); 3335bebb993Sopenharmony_ci return nullptr; 3345bebb993Sopenharmony_ci } 3355bebb993Sopenharmony_ci auto name = path.substr(pos + 1); 3365bebb993Sopenharmony_ci char* value = static_cast<char*>(malloc((name.size() + 1) * sizeof(char))); 3375bebb993Sopenharmony_ci if (value == nullptr) { 3385bebb993Sopenharmony_ci return nullptr; 3395bebb993Sopenharmony_ci } 3405bebb993Sopenharmony_ci if (strcpy_s(value, name.size() + 1, name.c_str()) != 0) { 3415bebb993Sopenharmony_ci free(value); 3425bebb993Sopenharmony_ci return nullptr; 3435bebb993Sopenharmony_ci } 3445bebb993Sopenharmony_ci return value; 3455bebb993Sopenharmony_ci} 3465bebb993Sopenharmony_ci 3475bebb993Sopenharmony_ciint FileEntity::TryLock(int64_t id, bool exclusive) 3485bebb993Sopenharmony_ci{ 3495bebb993Sopenharmony_ci auto fileEntity = FFIData::GetData<FileEntity>(id); 3505bebb993Sopenharmony_ci if (!fileEntity) { 3515bebb993Sopenharmony_ci LOGE("FileEntity instance not exist %{public}" PRId64, id); 3525bebb993Sopenharmony_ci return ERR_INVALID_INSTANCE_CODE; 3535bebb993Sopenharmony_ci } 3545bebb993Sopenharmony_ci int ret = 0; 3555bebb993Sopenharmony_ci auto mode = exclusive ? LOCK_EX : LOCK_SH; 3565bebb993Sopenharmony_ci ret = flock(fileEntity->fd_.get()->GetFD(), static_cast<unsigned int>(mode) | LOCK_NB); 3575bebb993Sopenharmony_ci if (ret < 0) { 3585bebb993Sopenharmony_ci LOGE("Failed to try to lock file"); 3595bebb993Sopenharmony_ci return GetErrorCode(ETXTBSY); 3605bebb993Sopenharmony_ci } 3615bebb993Sopenharmony_ci return SUCCESS_CODE; 3625bebb993Sopenharmony_ci} 3635bebb993Sopenharmony_ci 3645bebb993Sopenharmony_ciint FileEntity::UnLock(int64_t id) 3655bebb993Sopenharmony_ci{ 3665bebb993Sopenharmony_ci auto fileEntity = FFIData::GetData<FileEntity>(id); 3675bebb993Sopenharmony_ci if (!fileEntity) { 3685bebb993Sopenharmony_ci LOGE("FileEntity instance not exist %{public}" PRId64, id); 3695bebb993Sopenharmony_ci return ERR_INVALID_INSTANCE_CODE; 3705bebb993Sopenharmony_ci } 3715bebb993Sopenharmony_ci int ret = 0; 3725bebb993Sopenharmony_ci ret = flock(fileEntity->fd_.get()->GetFD(), LOCK_UN); 3735bebb993Sopenharmony_ci if (ret < 0) { 3745bebb993Sopenharmony_ci LOGE("Failed to unlock file"); 3755bebb993Sopenharmony_ci return GetErrorCode(ETXTBSY); 3765bebb993Sopenharmony_ci } 3775bebb993Sopenharmony_ci return SUCCESS_CODE; 3785bebb993Sopenharmony_ci} 3795bebb993Sopenharmony_ci 3805bebb993Sopenharmony_ciRetDataCString FileEntity::GetParent() 3815bebb993Sopenharmony_ci{ 3825bebb993Sopenharmony_ci LOGI("FS_TEST::FileEntity::GetParent start"); 3835bebb993Sopenharmony_ci RetDataCString ret = { .code = EINVAL, .data = nullptr }; 3845bebb993Sopenharmony_ci string path(path_); 3855bebb993Sopenharmony_ci if (uri_.length() != 0) { 3865bebb993Sopenharmony_ci AppFileService::ModuleFileUri::FileUri fileUri(uri_); 3875bebb993Sopenharmony_ci path = fileUri.GetRealPath(); 3885bebb993Sopenharmony_ci } 3895bebb993Sopenharmony_ci auto [realPathRes, realPath] = RealPathCore(path); 3905bebb993Sopenharmony_ci if (realPathRes != ERRNO_NOERR) { 3915bebb993Sopenharmony_ci LOGE("realPath error"); 3925bebb993Sopenharmony_ci ret.code = realPathRes; 3935bebb993Sopenharmony_ci return ret; 3945bebb993Sopenharmony_ci } 3955bebb993Sopenharmony_ci path = string(static_cast<const char *>(realPath->ptr)); 3965bebb993Sopenharmony_ci auto pos = path.find_last_of('/'); 3975bebb993Sopenharmony_ci if (pos == string::npos) { 3985bebb993Sopenharmony_ci LOGE("Failed to split filename from path"); 3995bebb993Sopenharmony_ci ret.code = ENOENT; 4005bebb993Sopenharmony_ci return ret; 4015bebb993Sopenharmony_ci } 4025bebb993Sopenharmony_ci ret.code = SUCCESS_CODE; 4035bebb993Sopenharmony_ci auto parent = path.substr(0, pos); 4045bebb993Sopenharmony_ci char* result = new(std::nothrow) char[parent.length() + 1]; 4055bebb993Sopenharmony_ci if (result == nullptr) { 4065bebb993Sopenharmony_ci ret.code = ENOMEM; 4075bebb993Sopenharmony_ci return ret; 4085bebb993Sopenharmony_ci } 4095bebb993Sopenharmony_ci if (strcpy_s(result, parent.length() + 1, parent.c_str()) != 0) { 4105bebb993Sopenharmony_ci ret.code = ENOMEM; 4115bebb993Sopenharmony_ci delete[] (result); 4125bebb993Sopenharmony_ci result = nullptr; 4135bebb993Sopenharmony_ci return ret; 4145bebb993Sopenharmony_ci } 4155bebb993Sopenharmony_ci ret.data = result; 4165bebb993Sopenharmony_ci LOGI("FS_TEST::FileEntity::GetParent success"); 4175bebb993Sopenharmony_ci return ret; 4185bebb993Sopenharmony_ci} 4195bebb993Sopenharmony_ci 4205bebb993Sopenharmony_ci} // namespace FileFs 4215bebb993Sopenharmony_ci} // namespace CJSystemapi 4225bebb993Sopenharmony_ci} // namespace OHOS