LCOV - code coverage report
Current view: top level - adump/common - file.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 85.3 % 129 110
Test Date: 2026-07-28 10:54:24 Functions: 90.9 % 11 10

            Line data    Source code
       1              : /**
       2              :  * Copyright (c) 2025 Huawei Technologies Co., Ltd.
       3              :  * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
       4              :  * CANN Open Software License Agreement Version 2.0 (the "License").
       5              :  * Please refer to the License for details. You may not use this file except in compliance with the License.
       6              :  * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
       7              :  * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
       8              :  * See LICENSE in the root of the software repository for the full text of the License.
       9              :  */
      10              : 
      11              : #include "file.h"
      12              : #include "path.h"
      13              : #include "adump_pub.h"
      14              : #include "log/adx_log.h"
      15              : #include "extra_config.h"
      16              : 
      17              : namespace Adx {
      18              : namespace {
      19              : constexpr int32_t INVALID_FILE_FD = -1;
      20              : constexpr mmMode_t READ_WRITE_MODE = M_IRUSR | M_IWUSR;
      21              : constexpr int64_t MAX_BUFFER_LENGTH = 512;
      22              : static const std::string MAPPING_FILE_NAME = "mapping.csv";
      23              : }  // namespace
      24              : 
      25          223 : File::File(const std::string &path, int32_t flag, mmMode_t mode, bool lazyOpen)
      26          223 :     : filePath_(path), fd_(INVALID_FILE_FD), flag_(flag), mode_(mode)
      27              : {
      28          223 :     if (lazyOpen) {
      29           72 :         return;
      30              :     }
      31          151 :     if (Open(flag, mode) != ADUMP_SUCCESS) {
      32           15 :         fd_ = INVALID_FILE_FD;
      33              :     }
      34            0 : }
      35              : 
      36           21 : int32_t File::EnsureOpen()
      37              : {
      38           21 :     if (fd_ != INVALID_FILE_FD) {
      39            0 :         return ADUMP_SUCCESS;
      40              :     }
      41           21 :     if (Open(flag_, mode_) != ADUMP_SUCCESS) {
      42            0 :         fd_ = INVALID_FILE_FD;
      43            0 :         return ADUMP_FAILED;
      44              :     }
      45           21 :     return ADUMP_SUCCESS;
      46              : }
      47              : 
      48          223 : File::~File()
      49              : {
      50          223 :     (void)Close();
      51          223 : }
      52              : 
      53          172 : int32_t File::Open(int32_t flag, mmMode_t mode)
      54              : {
      55          172 :     Path filePath(filePath_);
      56          172 :     std::string fileName = filePath.GetFileName();
      57          172 :     Path parentPath = filePath.ParentPath();
      58          172 :     if (!parentPath.Empty() && !parentPath.RealPath()) {
      59            3 :         IDE_LOGE("Real file path failed, file: %s", filePath_.c_str());
      60            3 :         return ADUMP_FAILED;
      61              :     }
      62              : 
      63          169 :     std::string realFilePath = parentPath.Concat(fileName).GetString();
      64          169 :     fd_ = mmOpen2(realFilePath.c_str(), flag, mode);
      65          169 :     if (fd_ >= 0) {
      66          154 :         return ADUMP_SUCCESS;
      67              :     }
      68           15 :     if (mmGetErrorCode() != ENAMETOOLONG) {
      69            9 :         IDE_LOGE("Open file failed. file: %s, fd: %d, message: %s", realFilePath.c_str(), fd_, strerror(errno));
      70            9 :         return ADUMP_FAILED;
      71              :     }
      72            6 :     parentPath = filePath.ParentPath();
      73            6 :     if (!parentPath.Empty() && !parentPath.RealPath()) {
      74            0 :         IDE_LOGE("Real long name file path failed, file: %s", filePath_.c_str());
      75            0 :         return ADUMP_FAILED;
      76              :     }
      77            6 :     std::string hashName = std::to_string(std::hash<std::string>{}(fileName));
      78            6 :     if (AddMapping(parentPath.GetString(), fileName, hashName) != ADUMP_SUCCESS) {
      79            3 :         IDE_LOGE("Add mapping item [ %s ] failed", hashName.c_str());
      80              :     }
      81            6 :     realFilePath = parentPath.Concat(hashName).GetString();
      82            6 :     IDE_LOGW("File name [ %s ] too long rename as [ %s ] and the mapping record in %s",
      83              :         fileName.c_str(), realFilePath.c_str(), MAPPING_FILE_NAME.c_str());
      84            6 :     fd_ = mmOpen2(realFilePath.c_str(), O_APPEND | M_RDWR | M_CREAT, M_IREAD | M_IWRITE);
      85            6 :     IDE_CTRL_VALUE_FAILED(fd_ >= 0, return ADUMP_FAILED, "Open hash file failed, fd: %d", fd_);
      86            3 :     return ADUMP_SUCCESS;
      87          172 : }
      88              : 
      89            0 : int32_t File::GetFileDiscriptor() const
      90              : {
      91            0 :     return fd_;
      92              : }
      93              : 
      94          142 : int32_t File::IsFileOpen() const
      95              : {
      96          142 :     if (fd_ == INVALID_FILE_FD) {
      97           15 :         return ADUMP_FAILED;
      98              :     }
      99          127 :     return ADUMP_SUCCESS;
     100              : }
     101              : 
     102          235 : int32_t File::Close()
     103              : {
     104          235 :     if (fd_ == INVALID_FILE_FD) {
     105           72 :         return ADUMP_SUCCESS;
     106              :     }
     107              : 
     108          163 :     const int32_t ret = mmClose(fd_);
     109          163 :     if (ret != EN_OK) {
     110            6 :         IDE_LOGW("Can not close file handle, file: %s, ret: %d.", filePath_.c_str(), ret);
     111            6 :         return ADUMP_FAILED;
     112              :     }
     113          157 :     fd_ = INVALID_FILE_FD;
     114          157 :     return ADUMP_SUCCESS;
     115              : }
     116              : 
     117          278 : int64_t File::Write(const char *const buffer, int64_t length) const
     118              : {
     119          278 :     mmSsize_t ret = 0;
     120          278 :     UINT32 reserve = static_cast<UINT32>(length);
     121              :     do {
     122          284 :         ret = mmWrite(fd_, const_cast<char *>(buffer) + (static_cast<UINT32>(length) - reserve), reserve);
     123          284 :         if ((ret == EN_ERROR) && (mmGetErrorCode() == EINTR)) {
     124            0 :             continue;
     125              :         }
     126          284 :         if (ret < 0 || static_cast<UINT32>(ret) > reserve) {
     127            9 :             IDE_LOGE("Write data failed, buff: %p, length: %ld, ret: %zd", buffer, length, ret);
     128            9 :             break;
     129              :         }
     130          275 :         reserve -= ret;
     131          275 :         if (reserve == 0) {
     132          269 :             break;
     133              :         }
     134              :     } while (true);
     135              : 
     136          278 :     return static_cast<int64_t>(ret);
     137              : }
     138              : 
     139           79 : int64_t File::Read(char *buffer, int64_t length) const
     140              : {
     141              :     mmSsize_t ret;
     142              :     do {
     143           79 :         ret = mmRead(fd_, buffer, static_cast<UINT32>(length));
     144           79 :     } while (ret == EN_ERROR && mmGetErrorCode() == EINTR);
     145              : 
     146           79 :     if (ret == EN_ERROR) {
     147            3 :         IDE_LOGE("Read data failed, buff: %p, length: %ld bytes, ret: %zd", buffer, length, ret);
     148              :     }
     149           79 :     return static_cast<int64_t>(ret);
     150              : }
     151              : 
     152           29 : int32_t File::Copy(const std::string &srcPath, const std::string &dstPath)
     153              : {
     154           29 :     IDE_LOGI("copy file from %s to %s", srcPath.c_str(), dstPath.c_str());
     155           29 :     File srcFile(srcPath, M_RDONLY);
     156           29 :     int32_t ret = srcFile.IsFileOpen();
     157           29 :     if (ret != ADUMP_SUCCESS) {
     158            6 :         IDE_LOGE("Open src file failed, file: %s", srcPath.c_str());
     159            6 :         return ret;
     160              :     }
     161              : 
     162           23 :     File dstFile(dstPath, M_CREAT | M_WRONLY | M_TRUNC, READ_WRITE_MODE);
     163           23 :     ret = dstFile.IsFileOpen();
     164           23 :     if (ret != ADUMP_SUCCESS) {
     165            0 :         IDE_LOGE("Open dst file failed, file: %s", dstPath.c_str());
     166            0 :         return ret;
     167              :     }
     168              : 
     169           23 :     char buffer[MAX_BUFFER_LENGTH] = { 0 };
     170           23 :     int64_t size = 0;
     171              :     do {
     172           76 :         size = srcFile.Read(buffer, MAX_BUFFER_LENGTH);
     173           76 :         if (size < 0) {
     174            0 :             IDE_LOGE("Read file failed, file: %s", srcPath.c_str());
     175            0 :             return ADUMP_FAILED;
     176              :         }
     177           76 :         IDE_LOGD("Read file size: %ld bytes", size);
     178           76 :         if (size > 0) {
     179           59 :             const auto writeSize = dstFile.Write(buffer, size);
     180           59 :             if (writeSize < 0) {
     181            6 :                 IDE_LOGE("Write file failed, file: %s", dstPath.c_str());
     182            6 :                 return ADUMP_FAILED;
     183              :             }
     184              :         }
     185           70 :     } while (size > 0);
     186           17 :     return ADUMP_SUCCESS;
     187           29 : }
     188              : 
     189              :  /**
     190              :  * @brief       : add map item into mapping.csv
     191              :  * @param [in]  : filePath    file path
     192              :  * @param [in]  : hashName    hash value of file name
     193              :  * @return      : ADUMP_SUCCESS: success; ADUMP_FAILED: failed
     194              :  */
     195            6 : int32_t File::AddMapping(const std::string &filePath, const std::string &fileName, const std::string &hashName)
     196              : {
     197            6 :     IDE_CTRL_VALUE_FAILED(!filePath.empty(), return ADUMP_FAILED, "FilePath is empty");
     198            6 :     IDE_CTRL_VALUE_FAILED(!hashName.empty(), return ADUMP_FAILED, "HashName is empty");
     199              : 
     200            6 :     Path parentPath(filePath);
     201            6 :     std::string mappingFile = parentPath.Concat('/' + MAPPING_FILE_NAME).GetString();
     202            6 :     fd_ = mmOpen2(mappingFile.c_str(), O_APPEND | M_RDWR | M_CREAT, M_IRUSR | M_IWRITE);
     203            6 :     IDE_CTRL_VALUE_FAILED(fd_ >= 0, return ADUMP_FAILED, "Open mapping file failed, fd: %d", fd_);
     204              : 
     205            3 :     std::string mapping = hashName + ',' + fileName + '\n';
     206            3 :     uint32_t mappingLen = mapping.length();
     207            3 :     uint32_t residLen = mappingLen;
     208              : 
     209              :     do {
     210            3 :         mmSsize_t writeLen = mmWrite(fd_, const_cast<AdxStringBuffer>(mapping.c_str()) + (mappingLen - residLen),
     211              :             residLen);
     212            3 :         if (writeLen < 0) {
     213            0 :             IDE_LOGE("Write failed, info: %s, write length: %ld bytes", strerror(errno), writeLen);
     214            0 :             (void)Close();
     215            0 :             return ADUMP_FAILED;
     216              :         }
     217            3 :         if (residLen >= static_cast<uint32_t>(writeLen)) {
     218            3 :             residLen -= static_cast<uint32_t>(writeLen);
     219              :         } else {
     220            0 :             IDE_LOGE("Write failed, info: %s, write length larger than resid length", strerror(errno));
     221            0 :             (void)Close();
     222            0 :             return ADUMP_FAILED;
     223              :         }
     224            3 :     } while (residLen != 0);
     225              : 
     226            3 :     (void)Close();
     227            3 :     return ADUMP_SUCCESS;
     228            6 : }
     229              : }  // namespace Adx
        

Generated by: LCOV version 2.0-1