• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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 "platform_specific.h"
17 
18 #include <ctime>
19 #include <cstdlib>
20 #include <cstring>
21 #include <climits>
22 
23 #include <dirent.h>
24 #include <fcntl.h>
25 #include <sys/stat.h>
26 #include <sys/time.h>
27 #include <sys/types.h>
28 #include <unistd.h>
29 #if defined OS_TYPE_WINDOWS
30 #include <io.h>
31 #include <stdlib.h>
32 #include <windows.h>
33 #endif
34 
35 #include "db_errno.h"
36 #include "log_print.h"
37 #include "securec.h"
38 
39 namespace DistributedDB {
40 namespace OS {
41 /*
42  * Common part that is the same between each os
43  */
44 #if defined OS_TYPE_WINDOWS
45 namespace {
46     const int ACCESS_MODE_EXISTENCE = 0;
47 }
48 
49 struct FileHandle {
50     int handle = -1;
51 };
52 
CheckPathExistence(const std::string & filePath)53 bool CheckPathExistence(const std::string &filePath)
54 {
55     int ret = _access(filePath.c_str(), ACCESS_MODE_EXISTENCE);
56     LOGI("CheckPathExistence error:%d", ret);
57     return (ret == 0);
58 }
59 
RenameFilePath(const std::string & oldFilePath,const std::string & newFilePath)60 int RenameFilePath(const std::string &oldFilePath, const std::string &newFilePath)
61 {
62     int errCode = rename(oldFilePath.c_str(), newFilePath.c_str());
63     if (errCode < 0) {
64         LOGE("[Rename] Rename file fail. err = %d", errno);
65         return -E_SYSTEM_API_FAIL;
66     }
67     LOGI("Rename file path successfully!");
68     return E_OK;
69 }
70 
RemoveFile(const std::string & filePath)71 int RemoveFile(const std::string &filePath)
72 {
73 #ifdef DB_DEBUG_ENV
74     LOGD("---> remove db");
75 #endif
76     int errCode = remove(filePath.c_str());
77     if (errCode < 0) {
78         LOGE("[RemoveFile] Remove file fail, %d err = %d", errCode, errno);
79         return -E_SYSTEM_API_FAIL;
80     }
81     LOGD("Remove file successfully!");
82     return E_OK;
83 }
84 
CalFileSize(const std::string & fileUrl,uint64_t & size)85 int CalFileSize(const std::string &fileUrl, uint64_t &size)
86 {
87     struct _stat64 fileStat;
88     if (fileUrl.empty() || _stat64(fileUrl.c_str(), &fileStat) < 0 || fileStat.st_size < 0) {
89         int errCode = (errno == ENOENT) ? -E_NOT_FOUND : -E_INVALID_DB;
90         LOGD("Get file[%zu] size failed, errno [%d].", fileUrl.size(), errno);
91         return errCode;
92     }
93 
94     size = static_cast<uint64_t>(fileStat.st_size);
95     return E_OK;
96 }
97 
SplitFilePath(const std::string & filePath,std::string & fileDir,std::string & fileName)98 void SplitFilePath(const std::string &filePath, std::string &fileDir, std::string &fileName)
99 {
100     if (filePath.empty()) {
101         return;
102     }
103 
104     auto slashPos = filePath.find_last_of('/');
105     if (slashPos == std::string::npos) {
106         fileName = filePath;
107         fileDir = "";
108         return;
109     }
110 
111     fileDir = filePath.substr(0, slashPos);
112     fileName = filePath.substr(slashPos + 1);
113     return;
114 }
115 
MakeDBDirectory(const std::string & directory)116 int MakeDBDirectory(const std::string &directory)
117 {
118     int errCode = mkdir(directory.c_str());
119     if (errCode < 0) {
120         LOGE("[MakeDir] Make directory fail:%d, %s", errno,
121             directory.empty() ? "empty directory path" : "directory path error");
122         return -E_SYSTEM_API_FAIL;
123     }
124     return E_OK;
125 }
126 
RemoveDBDirectory(const std::string & directory)127 int RemoveDBDirectory(const std::string &directory)
128 {
129 #ifdef DB_DEBUG_ENV
130     LOGD("---> remove db directory");
131 #endif
132     int ret = rmdir(directory.c_str());
133     LOGI("CheckPathExistence ret:%d error %d", ret, errno);
134     return ret;
135 }
136 
CreateFileByFileName(const std::string & fileName)137 int CreateFileByFileName(const std::string &fileName)
138 {
139     int fp = _open(fileName.c_str(), (O_WRONLY | O_CREAT), _S_IREAD | _S_IWRITE);
140     if (fp < 0) {
141         LOGE("[CreateFile] Create file fail:%d.", errno);
142         return -E_SYSTEM_API_FAIL;
143     }
144     close(fp);
145     return E_OK;
146 }
147 
GetRealPath(const std::string & inOriPath,std::string & outRealPath)148 int GetRealPath(const std::string &inOriPath, std::string &outRealPath)
149 {
150     const unsigned int MAX_PATH_LENGTH = PATH_MAX;
151     if (inOriPath.length() > MAX_PATH_LENGTH || MAX_PATH_LENGTH > 0x10000) { // max limit is 64K(0x10000).
152         LOGE("[RealPath] OriPath too long.");
153         return -E_INVALID_ARGS;
154     }
155 
156     char *realPath = new (std::nothrow) char[MAX_PATH_LENGTH + 1];
157     if (realPath == nullptr) {
158         return -E_OUT_OF_MEMORY;
159     }
160     if (memset_s(realPath, MAX_PATH_LENGTH + 1, 0, MAX_PATH_LENGTH + 1) != EOK) {
161         delete [] realPath;
162         return -E_SECUREC_ERROR;
163     }
164 
165     if (_fullpath(realPath, inOriPath.c_str(), MAX_PATH_LENGTH) == nullptr) {
166         LOGE("[OS] Realpath error:%d.", errno);
167         delete [] realPath;
168         return -E_SYSTEM_API_FAIL;
169     }
170     outRealPath = std::string(realPath);
171     delete [] realPath;
172     return E_OK;
173 }
174 #ifndef DB_DEBUG_ENV
175 namespace {
176     const uint64_t MULTIPLES_BETWEEN_MICROSECONDS_AND_NANOSECONDS = 1000;
177     const uint64_t MULTIPLES_BETWEEN_MICROSECONDS_AND_100_NANOSECONDS = 10;
178     const uint64_t MICROSECONDS_OFFSET = 11644473600000000;  // microseconds from January 1, 1601 to January 1, 1970
179     const uint64_t UINT32_BIT_LENGTH = 32;
180 }
181 
GetCurrentSysTimeInMicrosecond(uint64_t & outTime)182 int GetCurrentSysTimeInMicrosecond(uint64_t &outTime)
183 {
184     FILETIME rawTime;
185     GetSystemTimeAsFileTime(&rawTime);
186     outTime = ((static_cast<uint64_t>(rawTime.dwHighDateTime) << UINT32_BIT_LENGTH) +
187         (static_cast<uint64_t>(rawTime.dwLowDateTime))) / MULTIPLES_BETWEEN_MICROSECONDS_AND_100_NANOSECONDS -
188         MICROSECONDS_OFFSET;
189     return E_OK;
190 }
191 #endif  // DB_DEBUG_ENV
192 
GetMonotonicRelativeTimeInMicrosecond(uint64_t & outTime)193 int GetMonotonicRelativeTimeInMicrosecond(uint64_t &outTime)
194 {
195     LARGE_INTEGER frequency;
196     LARGE_INTEGER rawTime;
197     if (!QueryPerformanceFrequency(&frequency)) {
198         LOGE("query performance frequency fail %d", errno);
199         return -E_SYSTEM_API_FAIL;
200     }
201 
202     if (frequency.QuadPart == 0) {
203         LOGE("frequency quadpart zero!");
204         return -E_SYSTEM_API_FAIL;
205     }
206 
207     if (!QueryPerformanceCounter(&rawTime)) {
208         LOGE("query frequency counter fail %d!", errno);
209         return -E_SYSTEM_API_FAIL;
210     }
211 
212     outTime = (static_cast<uint64_t>(rawTime.QuadPart) * MULTIPLES_BETWEEN_MICROSECONDS_AND_NANOSECONDS) /
213         static_cast<uint64_t>(frequency.QuadPart);
214     return E_OK;
215 }
216 
InitFileType(const _finddata_t & file,FileAttr & fileAttr)217 static void InitFileType(const _finddata_t &file, FileAttr& fileAttr)
218 {
219     switch (file.attrib) {
220         case _A_NORMAL:
221         case _A_ARCH:
222             fileAttr.fileType = FILE;
223             return;
224         case _A_SUBDIR:
225             fileAttr.fileType = PATH;
226             return;
227         default:
228             fileAttr.fileType = OTHER;
229             return;
230     }
231 }
232 
GetFilePathAttr(const std::string & topPath,const std::string & relativePath,std::list<FileAttr> & files,bool isNeedAllPath)233 static int GetFilePathAttr(const std::string &topPath, const std::string &relativePath,
234     std::list<FileAttr> &files, bool isNeedAllPath)
235 {
236     _finddata_t file;
237     std::string findPath = std::string(topPath) + "\\*.*";
238     intptr_t handle = _findfirst(findPath.c_str(), &file);
239     if (handle < 0) {
240         LOGE("Open dir error: %d.", errno);
241         return -E_INVALID_PATH;
242     }
243     int errCode = E_OK;
244     std::string fileAbsName;
245     struct _stat64 fileStat;
246 
247     FileAttr fileAttr;
248     do {
249         InitFileType(file, fileAttr);
250 
251         if (strlen(file.name) == 0 || strcmp(file.name, ".") == 0 ||
252             strcmp(file.name, "..") == 0) {
253             continue;
254         }
255 
256         fileAttr.fileName = relativePath + file.name;
257         fileAbsName = topPath + "/" + file.name;
258         errCode = _stat64(fileAbsName.c_str(), &fileStat);
259         if (errCode != 0) {
260             LOGE("[GetFileAttr]Get file stat failed, error = %d.", errCode);
261             errCode = -E_INVALID_PATH;
262             break;
263         }
264         if (isNeedAllPath) {
265             fileAttr.fileName = fileAbsName;
266         }
267         fileAttr.fileLen = static_cast<uint64_t>(fileStat.st_size);
268         files.push_back(fileAttr);
269         if (fileAttr.fileType == PATH) {
270             errCode = GetFilePathAttr(fileAbsName, relativePath + file.name + "/", files, isNeedAllPath);
271             if (errCode != E_OK) {
272                 LOGE("[GetFileAttr]GetFilePathAttr failed, error = %d.", errCode);
273                 break;
274             }
275         }
276     } while (_findnext(handle, &file) == 0);
277     _findclose(handle);
278     return errCode;
279 }
280 
GetFileAttrFromPath(const std::string & filePath,std::list<FileAttr> & files,bool isNeedAllPath)281 int GetFileAttrFromPath(const std::string &filePath, std::list<FileAttr> &files, bool isNeedAllPath)
282 {
283     return GetFilePathAttr(filePath, std::string(), files, isNeedAllPath);
284 }
285 
GetFilePermissions(const std::string & fileName,uint32_t & permissions)286 int GetFilePermissions(const std::string &fileName, uint32_t &permissions)
287 {
288     struct _stat64 fileStat;
289     int errCode = _stat64(fileName.c_str(), &fileStat);
290     if (errCode != E_OK) {
291         permissions = _S_IREAD | _S_IWRITE;
292         LOGE("Get file stat failed, error = %d.", errno);
293         return -E_SYSTEM_API_FAIL;
294     }
295     permissions = fileStat.st_mode & (_S_IRWXU | _S_IFMT | _S_IFDIR | _S_IFCHR | _S_IFIFO | _S_IFREG);
296     return E_OK;
297 }
298 
SetFilePermissions(const std::string & fileName,uint32_t permissions)299 int SetFilePermissions(const std::string &fileName, uint32_t permissions)
300 {
301     if (permissions > (S_IRWXU | S_IRWXG | S_IRWXO)) {
302         return -E_INVALID_ARGS;
303     }
304     int errCode = _chmod(fileName.c_str(), _S_IREAD | _S_IWRITE);
305     if (errCode != E_OK) {
306         LOGE("Set file permissions failed, error = %d.", errno);
307         return -E_SYSTEM_API_FAIL;
308     }
309     return E_OK;
310 }
311 
OpenFile(const std::string & fileName,FileHandle * & fileHandle)312 int OpenFile(const std::string &fileName, FileHandle *&fileHandle)
313 {
314     fileHandle = new (std::nothrow)FileHandle;
315     if (fileHandle == nullptr) {
316         return -E_OUT_OF_MEMORY;
317     }
318     fileHandle->handle = _open(fileName.c_str(), (O_WRONLY | O_CREAT), _S_IREAD | _S_IWRITE);
319     if (fileHandle->handle < 0) {
320         LOGE("[FileLock] can not open file when lock it:[%d]", errno);
321         delete fileHandle;
322         fileHandle = nullptr;
323         return -E_SYSTEM_API_FAIL;
324     }
325     return E_OK;
326 }
327 
CloseFile(FileHandle * fileHandle)328 int CloseFile(FileHandle *fileHandle)
329 {
330     if (fileHandle == nullptr || fileHandle->handle == -1) {
331         LOGI("[CloseFile] file handle is invalid!");
332         return -E_INVALID_ARGS;
333     }
334 
335     if (close(fileHandle->handle) != 0) {
336         LOGE("close file failed, errno:%d", errno);
337         return -E_SYSTEM_API_FAIL;
338     }
339     delete fileHandle;
340     return E_OK;
341 }
342 
FileLock(const FileHandle * fileHandle,bool isBlock)343 int FileLock(const FileHandle *fileHandle, bool isBlock)
344 {
345     if (fileHandle == nullptr) {
346         return -E_INVALID_ARGS;
347     }
348     if (fileHandle->handle < 0) {
349         LOGE("[FileLock] can not open file when lock it:[%d]", errno);
350         return -E_SYSTEM_API_FAIL;
351     }
352     // windows下的LockFile与Linux差异较大,先不替换
353     return E_OK;
354 }
355 
FileUnlock(FileHandle * fileHandle)356 int FileUnlock(FileHandle *fileHandle)
357 {
358     return E_OK;
359 }
360 #else
361 namespace {
362     const int ACCESS_MODE_EXISTENCE = 0;
363     const uint64_t MULTIPLES_BETWEEN_SECONDS_AND_MICROSECONDS = 1000000;
364 }
365 
366 struct FileHandle {
367     int handle = -1;
368 };
369 
370 bool CheckPathExistence(const std::string &filePath)
371 {
372     return (access(filePath.c_str(), ACCESS_MODE_EXISTENCE) == 0);
373 }
374 
375 int RenameFilePath(const std::string &oldFilePath, const std::string &newFilePath)
376 {
377     int errCode = rename(oldFilePath.c_str(), newFilePath.c_str());
378     if (errCode < 0) {
379         LOGE("[Rename] Rename file fail. err = %d", errno);
380         return -E_SYSTEM_API_FAIL;
381     }
382     LOGI("Rename file path successfully!");
383     return E_OK;
384 }
385 
386 int RemoveFile(const std::string &filePath)
387 {
388     int errCode = remove(filePath.c_str());
389     if (errCode < 0) {
390         LOGE("[RemoveFile] Remove file fail. err = %d", errno);
391         return -E_SYSTEM_API_FAIL;
392     }
393     LOGD("Remove file successfully!");
394     return E_OK;
395 }
396 
397 int CalFileSize(const std::string &fileUrl, uint64_t &size)
398 {
399     struct stat fileStat;
400     if (fileUrl.empty() || stat(fileUrl.c_str(), &fileStat) < 0 || fileStat.st_size < 0) {
401         int errCode = (errno == ENOENT) ? -E_NOT_FOUND : -E_INVALID_DB;
402         LOGD("Get file[%zu] size failed, errno [%d].", fileUrl.size(), errno);
403         return errCode;
404     }
405 
406     size = static_cast<uint64_t>(fileStat.st_size);
407     return E_OK;
408 }
409 
410 void SplitFilePath(const std::string &filePath, std::string &fileDir, std::string &fileName)
411 {
412     if (filePath.empty()) {
413         return;
414     }
415 
416     auto slashPos = filePath.find_last_of('/');
417     if (slashPos == std::string::npos) {
418         fileName = filePath;
419         fileDir = "";
420         return;
421     }
422 
423     fileDir = filePath.substr(0, slashPos);
424     fileName = filePath.substr(slashPos + 1);
425     return;
426 }
427 
428 int MakeDBDirectory(const std::string &directory)
429 {
430     int errCode = mkdir(directory.c_str(), (S_IRWXU | S_IRWXG)); // The permission is 770 for linux based os
431     if (errCode < 0) {
432         LOGE("[MakeDir] Make directory fail:%d, %s", errno,
433             directory.empty() ? "empty directory path" : "directory path error");
434         return -E_SYSTEM_API_FAIL;
435     }
436     return E_OK;
437 }
438 
439 int RemoveDBDirectory(const std::string &directory)
440 {
441     return remove(directory.c_str());
442 }
443 
444 int CreateFileByFileName(const std::string &fileName)
445 {
446     int fp = open(fileName.c_str(), (O_WRONLY | O_CREAT), (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP));
447     if (fp < 0) {
448         LOGE("[CreateFile] Create file fail:%d.", errno);
449         return -E_SYSTEM_API_FAIL;
450     }
451     close(fp);
452     return E_OK;
453 }
454 
455 int GetRealPath(const std::string &inOriPath, std::string &outRealPath)
456 {
457     const unsigned int MAX_PATH_LENGTH = PATH_MAX;
458     if (inOriPath.length() > MAX_PATH_LENGTH || MAX_PATH_LENGTH > 0x10000) { // max limit is 64K(0x10000).
459         LOGE("[RealPath] OriPath too long.");
460         return -E_INVALID_ARGS;
461     }
462 
463     char *realPath = new (std::nothrow) char[MAX_PATH_LENGTH + 1];
464     if (realPath == nullptr) {
465         return -E_OUT_OF_MEMORY;
466     }
467     if (memset_s(realPath, MAX_PATH_LENGTH + 1, 0, MAX_PATH_LENGTH + 1) != EOK) {
468         delete []realPath;
469         return -E_SECUREC_ERROR;
470     }
471 
472     if (realpath(inOriPath.c_str(), realPath) == nullptr) {
473         LOGE("[OS] Realpath error:%d.", errno);
474         delete []realPath;
475         return -E_SYSTEM_API_FAIL;
476     }
477     outRealPath = std::string(realPath);
478     delete []realPath;
479     return E_OK;
480 }
481 
482 #ifndef DB_DEBUG_ENV
483 int GetCurrentSysTimeInMicrosecond(uint64_t &outTime)
484 {
485     struct timeval rawTime;
486     int errCode = gettimeofday(&rawTime, nullptr);
487     if (errCode < 0) {
488         LOGE("[GetSysTime] Fail:%d.", errCode);
489         return -E_SYSTEM_API_FAIL;
490     }
491     outTime = static_cast<uint64_t>(rawTime.tv_sec) * MULTIPLES_BETWEEN_SECONDS_AND_MICROSECONDS +
492               static_cast<uint64_t>(rawTime.tv_usec);
493     return E_OK;
494 }
495 #endif // DB_DEBUG_ENV
496 
497 namespace {
498     const uint64_t MULTIPLES_BETWEEN_MICROSECONDS_AND_NANOSECONDS = 1000;
499 }
500 
501 int GetMonotonicRelativeTimeInMicrosecond(uint64_t &outTime)
502 {
503     struct timespec rawTime;
504     clockid_t clockId = CLOCK_REALTIME;
505 #ifdef OS_TYPE_MAC
506     clockId = CLOCK_UPTIME_RAW;
507 #else
508     clockId = CLOCK_BOOTTIME;
509 #endif
510     int errCode = clock_gettime(clockId, &rawTime);
511     if (errCode < 0) {
512         LOGE("[GetMonoTime] Fail.");
513         return -E_SYSTEM_API_FAIL;
514     }
515 
516     outTime = static_cast<uint64_t>(rawTime.tv_sec) * MULTIPLES_BETWEEN_SECONDS_AND_MICROSECONDS +
517               static_cast<uint64_t>(rawTime.tv_nsec) / MULTIPLES_BETWEEN_MICROSECONDS_AND_NANOSECONDS;
518     return E_OK;
519 }
520 
521 static int GetFilePathAttr(const std::string &topPath, const std::string &relativePath,
522                            std::list<FileAttr> &files, bool isNeedAllPath)
523 {
524     DIR *dir = opendir(topPath.c_str());
525     if (dir == nullptr) {
526         LOGE("Open dir error:%d.", errno);
527         return -E_INVALID_PATH;
528     }
529     struct stat fileStat;
530     std::string fileAbsName;
531     int errCode = E_OK;
532     FileAttr file;
533     for (struct dirent *fileDirInfo = readdir(dir); fileDirInfo != nullptr; fileDirInfo = readdir(dir)) {
534         switch (fileDirInfo->d_type) {
535             case DT_REG:
536                 file.fileType = FILE;
537                 break;
538             case DT_DIR:
539                 file.fileType = PATH;
540                 break;
541             default:
542                 file.fileType = OTHER;
543         }
544         if (strlen(fileDirInfo->d_name) == 0 || strcmp(fileDirInfo->d_name, ".") == 0 ||
545             strcmp(fileDirInfo->d_name, "..") == 0) {
546             continue;
547         }
548         file.fileName = relativePath + fileDirInfo->d_name;
549         fileAbsName = topPath + "/" + fileDirInfo->d_name;
550         errCode = stat(fileAbsName.c_str(), &fileStat);
551         if (errCode != 0) {
552             LOGE("[GetFileAttr]Get file stat failed, error = %d.", errno);
553             errCode = -E_INVALID_PATH;
554             break;
555         }
556         if (isNeedAllPath) {
557             file.fileName = fileAbsName;
558         }
559         file.fileLen = static_cast<uint64_t>(fileStat.st_size);
560         files.push_back(file);
561         if (file.fileType == PATH) {
562             errCode = GetFilePathAttr(fileAbsName, relativePath + fileDirInfo->d_name + "/", files, isNeedAllPath);
563             if (errCode != E_OK) {
564                 break;
565             }
566         }
567     }
568 
569     closedir(dir);
570     return errCode;
571 }
572 
573 int GetFileAttrFromPath(const std::string &filePath, std::list<FileAttr> &files, bool isNeedAllPath)
574 {
575     return GetFilePathAttr(filePath, std::string(), files, isNeedAllPath);
576 }
577 
578 int GetFilePermissions(const std::string &fileName, uint32_t &permissions)
579 {
580     struct stat fileStat;
581     int errCode = stat(fileName.c_str(), &fileStat);
582     if (errCode != E_OK) {
583         permissions = S_IRUSR | S_IWUSR;
584         LOGE("Get file stat failed, error = %d.", errno);
585         return -E_SYSTEM_API_FAIL;
586     }
587     permissions = fileStat.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO);
588     return E_OK;
589 }
590 
591 int SetFilePermissions(const std::string &fileName, uint32_t permissions)
592 {
593     if (permissions > (S_IRWXU | S_IRWXG | S_IRWXO)) {
594         return -E_INVALID_ARGS;
595     }
596     int errCode = chmod(fileName.c_str(), permissions);
597     if (errCode != E_OK) {
598         LOGE("Set file permissions failed, error = %d.", errno);
599         return -E_SYSTEM_API_FAIL;
600     }
601     return E_OK;
602 }
603 
604 int OpenFile(const std::string &fileName, FileHandle *&fileHandle)
605 {
606     fileHandle = new (std::nothrow)FileHandle;
607     if (fileHandle == nullptr) {
608         return -E_OUT_OF_MEMORY;
609     }
610     fileHandle->handle = open(fileName.c_str(), (O_WRONLY | O_CREAT), (S_IRUSR | S_IWUSR | S_IRGRP));
611     if (fileHandle->handle < 0) {
612         LOGE("[FileLock] can not open file when lock it:[%d]", errno);
613         delete fileHandle;
614         fileHandle = nullptr;
615         return -E_SYSTEM_API_FAIL;
616     }
617     return E_OK;
618 }
619 
620 int CloseFile(FileHandle *fileHandle)
621 {
622     if (fileHandle == nullptr || fileHandle->handle == -1) {
623         LOGI("[CloseFile] file handle is invalid!");
624         return -E_INVALID_ARGS;
625     }
626     if (close(fileHandle->handle) != 0) {
627         LOGE("close file failed, errno:%d", errno);
628         return -E_SYSTEM_API_FAIL;
629     }
630     delete fileHandle;
631     return E_OK;
632 }
633 
634 int FileLock(const FileHandle *fileHandle, bool isBlock)
635 {
636     if (fileHandle == nullptr) {
637         return -E_INVALID_ARGS;
638     }
639     if (fileHandle->handle < 0) {
640         LOGE("[FileLock] can not open file when lock it:[%d]", errno);
641         return -E_SYSTEM_API_FAIL;
642     }
643 
644     struct flock fileLockInfo;
645     (void)memset_s(&fileLockInfo, sizeof(fileLockInfo), 0, sizeof(fileLockInfo));
646     fileLockInfo.l_type = F_WRLCK;
647     fileLockInfo.l_whence = SEEK_SET;
648     fileLockInfo.l_start = 0;
649     fileLockInfo.l_len = 0;
650     LOGD("Lock file isBlock[%d]", isBlock);
651     if (fcntl(fileHandle->handle, isBlock ? F_SETLKW : F_SETLK, &fileLockInfo) == -1 && !isBlock) {
652         LOGD("Lock file is Blocked, please retry!");
653         return -E_BUSY;
654     }
655     LOGI("file locked! errno:%d", errno);
656     return E_OK;
657 }
658 
659 int FileUnlock(FileHandle *fileHandle)
660 {
661     if (fileHandle == nullptr || fileHandle->handle == -1) {
662         LOGI("[FileUnlock] file handle is invalid!");
663         return E_OK;
664     }
665 
666     struct flock fileLockInfo;
667     (void)memset_s(&fileLockInfo, sizeof(fileLockInfo), 0, sizeof(fileLockInfo));
668     fileLockInfo.l_type = F_UNLCK;
669     fileLockInfo.l_whence = SEEK_SET;
670     fileLockInfo.l_start = 0;
671     fileLockInfo.l_len = 0;
672     if (fcntl(fileHandle->handle, F_SETLK, &fileLockInfo) == -1) {
673         LOGE("Unlock file failed. errno:%d", errno);
674         return -E_SYSTEM_API_FAIL;
675     }
676     return E_OK;
677 }
678 #endif
679 } // namespace OS
680 } // namespace DistributedDB
681