• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 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 "ecmascript/dfx/hprof/file_stream.h"
17 
18 #include <climits>
19 #include <unistd.h>
20 
21 #include "ecmascript/log_wrapper.h"
22 
23 namespace panda::ecmascript {
FileStream(const std::string & fileName)24 FileStream::FileStream(const std::string &fileName)
25 {
26     Initialize(fileName);
27 }
28 
~FileStream()29 FileStream::~FileStream()
30 {
31     EndOfStream();
32 }
33 
EndOfStream()34 void FileStream::EndOfStream()
35 {
36     if (fileStream_.is_open()) {
37         fileStream_.close();
38     }
39 }
40 
Good()41 bool FileStream::Good()
42 {
43     return fileStream_.good();
44 }
45 
Initialize(const std::string & fileName)46 void FileStream::Initialize(const std::string &fileName)
47 {
48     // check file name
49     std::pair<bool, std::string> realPath = FilePathValid(fileName);
50     if (!realPath.first) {
51         LOG_ECMA(ERROR) << "FileStream: check file path failed";
52         return;
53     }
54 
55     fileStream_.open(realPath.second.c_str(), std::ios::out);
56     if (fileStream_.fail()) {
57         LOG_ECMA(ERROR) << "FileStream: open file failed";
58     }
59 }
60 
FilePathValid(const std::string & fileName)61 std::pair<bool, std::string> FileStream::FilePathValid(const std::string &fileName)
62 {
63     if (fileName.empty() || fileName.size() > PATH_MAX) {
64         return std::make_pair(false, "");
65     }
66     char resolvedPath[PATH_MAX] = {0};
67     auto result = realpath(fileName.c_str(), resolvedPath);
68     if (result == resolvedPath || errno == ENOENT) {
69         return std::make_pair(true, std::string(resolvedPath));
70     }
71     return std::make_pair(false, "");
72 }
73 
74 // Writes the chunk of data into the stream
WriteChunk(char * data,int32_t size)75 bool FileStream::WriteChunk(char *data, int32_t size)
76 {
77     if (fileStream_.fail()) {
78         return false;
79     }
80 
81     std::string str(data, size);
82 
83     fileStream_ << str;
84 
85     return true;
86 }
87 
EndOfStream()88 void FileDescriptorStream::EndOfStream()
89 {
90     if (Good()) {
91         close(fd_);
92     }
93 }
94 
Good()95 bool FileDescriptorStream::Good()
96 {
97     return fd_ > 0;
98 }
99 
100 // Writes the chunk of data into the stream
WriteChunk(char * data,int32_t size)101 bool FileDescriptorStream::WriteChunk(char *data, int32_t size)
102 {
103     if (fd_ < 0) {
104         return false;
105     }
106 
107     std::string str(data, size);
108     int ret = dprintf(fd_, "%s", str.c_str());
109     if (ret < 0) {
110         LOG_ECMA(ERROR) << "Write FD print failed, ret" << ret;
111         return false;
112     }
113     ret = fsync(fd_);
114     if (ret < 0) {
115         LOG_ECMA(ERROR) << "Write FD file failed, ret" << ret;
116         return false;
117     }
118     return true;
119 }
120 
WriteBinBlock(char * data,int32_t size)121 bool FileDescriptorStream::WriteBinBlock(char *data, int32_t size)
122 {
123     if (fd_ < 0) {
124         return false;
125     }
126     ssize_t written = write(fd_, data, size);
127     if (written == -1) {
128         perror("write");
129         return false;
130     }
131     return true;
132 }
133 }
134