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