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