1/* 2 * Copyright (c) 2023 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 "file_utils.h" 17 18#include <sys/types.h> 19#include <unistd.h> 20#include <fcntl.h> 21#include <unistd.h> 22 23#include "dfs_error.h" 24#include "utils_log.h" 25#include "xcollie_helper.h" 26 27namespace OHOS { 28namespace FileManagement { 29int64_t FileUtils::ReadFile(int fd, off_t offset, size_t size, void *data) 30{ 31 if ((fd < 0) || (offset < 0) || (size < 0) || (data == nullptr)) { 32 LOGE("invalid params, fd %{public}d, offset %{public}d, size %{public}zu, or buf is null", fd, 33 static_cast<int>(offset), size); 34 return -1; 35 } 36 37 off_t err = lseek(fd, offset, SEEK_SET); 38 if (err < 0) { 39 return -errno; 40 } 41 42 size_t readLen = 0; 43 while (readLen < size) { 44 ssize_t ret = read(fd, data, size - readLen); 45 if (ret < 0) { 46 LOGE("read failed, errno %{public}d, fd=%{public}d", errno, fd); 47 return ret; 48 } else if (ret == 0) { 49 break; 50 } 51 readLen += ret; 52 } 53 54 return readLen; 55} 56 57int64_t FileUtils::WriteFile(int fd, const void *data, off_t offset, size_t size) 58{ 59 if ((fd < 0) || (offset < 0) || (size < 0) || (data == nullptr)) { 60 LOGE("invalid params, fd %{public}d, offset %{public}d, size %{public}zu, or buf is null", fd, 61 static_cast<int>(offset), size); 62 return -1; 63 } 64 65 off_t err = lseek(fd, offset, SEEK_SET); 66 if (err < 0) { 67 return -errno; 68 } 69 70 size_t writeLen = 0; 71 while (writeLen < size) { 72 ssize_t ret = write(fd, data, size - writeLen); 73 if (ret <= 0) { 74 LOGE("write failed, errno %{public}d, fd=%{public}d", errno, fd); 75 return ret; 76 } 77 writeLen += ret; 78 } 79 80 return writeLen; 81} 82 83FileRangeLock::FileRangeLock(int fd, off_t offset, size_t size) : fd_(fd), offset_(offset), size_(size) 84{ 85 const int DFX_DELAY_S = 5; 86 xcollieId_ = XCollieHelper::SetTimer("CloudSyncService_RangeLockTask", DFX_DELAY_S, nullptr, nullptr, true); 87 struct flock fl; 88 fl.l_type = F_WRLCK; 89 fl.l_whence = SEEK_SET; 90 fl.l_start = offset; 91 fl.l_len = static_cast<decltype(fl.l_len)>(size); 92 if (fcntl(fd, F_SETLKW, &fl) < 0) { 93 LOGE("fcntl set F_WRLCK failed: %{public}d", errno); 94 lockFailed_ = true; 95 } 96} 97 98FileRangeLock::~FileRangeLock() 99{ 100 if (lockFailed_) { 101 XCollieHelper::CancelTimer(xcollieId_); 102 return; 103 } 104 105 struct flock fl; 106 fl.l_type = F_UNLCK; 107 fl.l_whence = SEEK_SET; 108 fl.l_start = offset_; 109 fl.l_len = static_cast<decltype(fl.l_len)>(size_); 110 if (fcntl(fd_, F_SETLKW, &fl) < 0) { 111 LOGE("fcntl F_UNLCK failed: %{public}d", errno); 112 } 113 XCollieHelper::CancelTimer(xcollieId_); 114} 115 116} // namespace FileManagement 117} // namespace OHOS 118