Simple interface for Mbed Cloud Client
Embed:
(wiki syntax)
Show/hide line numbers
pal_plat_fileSystem.cpp
00001 /******************************************************************************* 00002 * Copyright 2016, 2017 ARM Ltd. 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 *******************************************************************************/ 00016 #include "mbed.h" 00017 00018 #include <errno.h> 00019 #include <stdio.h> 00020 #include <string.h> 00021 #include <stdlib.h> 00022 00023 #include "FileSystemLike.h" 00024 #include "FilePath.h" 00025 00026 00027 //PAL Includes 00028 #include "pal.h" 00029 #include "pal_plat_fileSystem.h" 00030 00031 00032 #ifndef EEXIST 00033 #define EEXIST 17 00034 #endif 00035 #ifndef EACCES 00036 #define EACCES 13 00037 #endif 00038 #ifndef EFAULT 00039 #define EFAULT 14 00040 #endif 00041 #ifndef EROFS 00042 #define EROFS 30 00043 #endif 00044 #ifndef EBUSY 00045 #define EBUSY 16 00046 #endif 00047 #ifndef ENAMETOOLONG 00048 #define ENAMETOOLONG 36 00049 #endif 00050 #ifndef EBADF 00051 #define EBADF 9 00052 #endif 00053 #ifndef EISDIR 00054 #define EISDIR 21 00055 #endif 00056 #ifndef ENOTEMPTY 00057 #define ENOTEMPTY 39 00058 #endif 00059 #ifndef ENOENT 00060 #define ENOENT 2 00061 #endif 00062 00063 00064 00065 #define PAL_FS_COPY_BUFFER_SIZE 256 //!< Size of the chunk to copy files 00066 PAL_PRIVATE const char *g_platOpenModeConvert[] = {"0", "r", "r+", "w+x", "w+"}; //!< platform convert table for \b fopen() modes 00067 PAL_PRIVATE const int g_platSeekWhenceConvert[] = {0, SEEK_SET, SEEK_CUR, SEEK_END}; //!< platform convert table for \b fseek() relative position modes 00068 00069 00070 00071 00072 00073 /*! \brief This function find the next file in a directory 00074 * 00075 * @param[in] *dh - Directory handler to an open DIR 00076 * @param[out] CurrentEntry - entry for the file found in Directory (pre allocated) 00077 * 00078 * \return true - upon successful operation.\n 00079 * 00080 */ 00081 PAL_PRIVATE bool pal_plat_findNextFile(DIR *dh, struct dirent ** CurrentEntry); 00082 00083 /*! \brief This function translate the platform errors opcode to pal error codes 00084 * 00085 * @param[in] errorOpCode - platform opcode to be translated 00086 * 00087 * \return PAL_SUCCESS upon successful operation.\n 00088 */ 00089 PAL_PRIVATE palStatus_t pal_plat_errorTranslation (int errorOpCode); 00090 00091 00092 /*! \brief This function build the full path name by adding the filename to the working path given in pathName arg 00093 * 00094 * @param[in] *pathName - pointer to the null-terminated string that specifies the directory name. 00095 * @param[in] *fileName - pointer to the file name 00096 * @param[out] *fullPath - pointer to the full path including the filename (pre allocated) 00097 * 00098 * \return PAL_SUCCESS upon successful operation.\n 00099 * PAL_FILE_SYSTEM_ERROR - see error code description \c palError_t 00100 * 00101 */ 00102 PAL_PRIVATE palStatus_t pal_plat_addFileNameToPath(const char *pathName, const char * fileName, char * fullPath); 00103 00104 /*! \brief This function copy one file from source folder to destination folder 00105 * 00106 * @param[in] pathNameSrc - Pointer to a null-terminated string that specifies the source dir. 00107 * @param[in] pathNameDest - Pointer to a null-terminated string that specifies the destination dir 00108 * @param[in] fileName - pointer the the file name 00109 * 00110 * \return PAL_SUCCESS upon successful operation.\n 00111 * PAL_FILE_SYSTEM_ERROR - see error code description \c palError_t 00112 * 00113 * \note File should not be open.\n 00114 * If the Destination file exist then it shall be truncated 00115 * 00116 */ 00117 PAL_PRIVATE palStatus_t pal_plat_fsCpFile(const char *pathNameSrc, char *pathNameDest, char * fileName); 00118 00119 palStatus_t pal_plat_fsMkdir(const char *pathName) 00120 { 00121 palStatus_t ret = PAL_SUCCESS; 00122 if(mkdir(pathName, 0600)) 00123 { 00124 ret = pal_plat_errorTranslation(errno); 00125 } 00126 return ret; 00127 } 00128 00129 00130 palStatus_t pal_plat_fsRmdir(const char *pathName) 00131 { 00132 palStatus_t ret = PAL_SUCCESS; 00133 00134 if (remove(pathName)) 00135 { 00136 if((EINVAL == errno) || (EACCES == errno) || (ENOTEMPTY == errno)) // EINVAL LittleFS error code, EACCES FatFS error code 00137 { 00138 ret = PAL_ERR_FS_DIR_NOT_EMPTY; 00139 } 00140 else if(errno == ENOENT) 00141 { 00142 ret = PAL_ERR_FS_NO_PATH; 00143 } 00144 else 00145 { 00146 ret = pal_plat_errorTranslation(errno); 00147 } 00148 } 00149 return ret; 00150 } 00151 00152 00153 palStatus_t pal_plat_fsFopen(const char *pathName, pal_fsFileMode_t mode, palFileDescriptor_t *fd) 00154 { 00155 palStatus_t ret = PAL_SUCCESS; 00156 00157 if (mode == PAL_FS_FLAG_READWRITEEXCLUSIVE) 00158 { 00159 *fd = (palFileDescriptor_t)fopen(pathName, "r"); 00160 if (*fd) 00161 { 00162 ret = PAL_ERR_FS_NAME_ALREADY_EXIST; 00163 fclose((FILE *)*fd); 00164 } 00165 } 00166 00167 if(ret == PAL_SUCCESS) 00168 { 00169 *fd = (palFileDescriptor_t)fopen(pathName, g_platOpenModeConvert[mode]); 00170 if (!(*fd)) 00171 { 00172 ret = pal_plat_errorTranslation(errno); 00173 } 00174 } 00175 return ret; 00176 } 00177 00178 00179 palStatus_t pal_plat_fsFclose(palFileDescriptor_t *fd) 00180 { 00181 palStatus_t ret = PAL_SUCCESS; 00182 if (fclose((FILE *)*fd)) 00183 { 00184 ret = pal_plat_errorTranslation(errno); 00185 } 00186 return ret; 00187 } 00188 00189 00190 palStatus_t pal_plat_fsFread(palFileDescriptor_t *fd, void * buffer, size_t numOfBytes, size_t *numberOfBytesRead) 00191 { 00192 palStatus_t ret = PAL_SUCCESS; 00193 clearerr((FILE *)*fd); 00194 *numberOfBytesRead = fread(buffer, 1, numOfBytes, (FILE *)*fd); 00195 if (*numberOfBytesRead != numOfBytes) 00196 { 00197 if (ferror((FILE *)*fd)) 00198 { 00199 ret = PAL_ERR_FS_ERROR; 00200 } 00201 clearerr((FILE *)*fd); 00202 } 00203 return ret; 00204 } 00205 00206 00207 palStatus_t pal_plat_fsFwrite(palFileDescriptor_t *fd, const void *buffer, size_t numOfBytes, size_t *numberOfBytesWritten) 00208 { 00209 palStatus_t ret = PAL_SUCCESS; 00210 errno = 0; 00211 *numberOfBytesWritten = fwrite(buffer, 1, numOfBytes, (FILE *)*fd); 00212 if (*numberOfBytesWritten != numOfBytes) 00213 { 00214 if(errno == EBADF) 00215 { 00216 ret = PAL_ERR_FS_ACCESS_DENIED; 00217 } 00218 else 00219 { 00220 ret = pal_plat_errorTranslation(errno); 00221 } 00222 } 00223 return ret; 00224 } 00225 00226 00227 palStatus_t pal_plat_fsFseek(palFileDescriptor_t *fd, int32_t offset, pal_fsOffset_t whence) 00228 { 00229 palStatus_t ret = PAL_SUCCESS; 00230 if (fseek((FILE *)*fd, offset, g_platSeekWhenceConvert[whence])) 00231 { 00232 ret = pal_plat_errorTranslation(errno); 00233 } 00234 return ret; 00235 } 00236 00237 00238 palStatus_t pal_plat_fsFtell(palFileDescriptor_t *fd, int32_t * pos) 00239 { 00240 palStatus_t ret = PAL_SUCCESS; 00241 long retPos = 0; 00242 *pos = 0; 00243 retPos = ftell((FILE *)*fd); 00244 if (retPos < 0) 00245 { 00246 ret = pal_plat_errorTranslation(errno); 00247 } 00248 else 00249 { 00250 *pos = retPos; 00251 } 00252 return ret; 00253 } 00254 00255 00256 palStatus_t pal_plat_fsUnlink(const char *pathName) 00257 { 00258 palStatus_t ret = PAL_SUCCESS; 00259 if (remove(pathName)) 00260 { 00261 ret = pal_plat_errorTranslation(errno); 00262 } 00263 return ret; 00264 } 00265 00266 00267 palStatus_t pal_plat_fsRmFiles(const char *pathName) 00268 { 00269 DIR *dh = NULL; //Directory handler 00270 palStatus_t ret = PAL_SUCCESS; 00271 char buffer[PAL_MAX_FILE_AND_FOLDER_LENGTH] = {0}; //Buffer for coping the name and folder 00272 struct dirent * currentEntry = NULL; //file Entry 00273 00274 dh = opendir(pathName); 00275 if (dh) 00276 { 00277 while(true) 00278 { 00279 if (!pal_plat_findNextFile(dh, ¤tEntry)) 00280 { 00281 ret = PAL_ERR_FS_ERROR_IN_SEARCHING; 00282 break; 00283 } 00284 00285 if (currentEntry) 00286 { 00287 pal_plat_addFileNameToPath(pathName, currentEntry->d_name, buffer); 00288 if (currentEntry->d_type == DT_DIR) 00289 { 00290 pal_plat_fsRmFiles(buffer); 00291 } 00292 if (remove(buffer)) 00293 { 00294 ret = pal_plat_errorTranslation(errno); 00295 break; 00296 } 00297 } 00298 else 00299 {//End of directory reached without errors break, close directory and exit 00300 break; 00301 } 00302 }//while() 00303 } 00304 else//if (dh) 00305 { 00306 ret = PAL_ERR_FS_NO_PATH; 00307 } 00308 00309 if (dh) 00310 { 00311 closedir(dh); //Close DIR handler 00312 } 00313 return ret; 00314 } 00315 00316 00317 palStatus_t pal_plat_fsCpFolder(const char *pathNameSrc, char *pathNameDest) 00318 { 00319 DIR *src_dh = NULL; //Directory for the source Directory handler 00320 palStatus_t ret = PAL_SUCCESS; 00321 struct dirent * currentEntry = NULL; //file Entry 00322 00323 src_dh = opendir(pathNameSrc); 00324 if (src_dh == NULL) 00325 { 00326 ret = PAL_ERR_FS_NO_PATH; 00327 } 00328 00329 if (ret == PAL_SUCCESS) 00330 { 00331 while(true) 00332 { 00333 if (!pal_plat_findNextFile(src_dh, ¤tEntry)) 00334 { 00335 ret = PAL_ERR_FS_ERROR_IN_SEARCHING; 00336 break; 00337 } 00338 00339 if (currentEntry) 00340 { 00341 if (currentEntry->d_type == DT_DIR) 00342 { 00343 continue; 00344 } 00345 //copy the file to the destination 00346 ret = pal_plat_fsCpFile(pathNameSrc, pathNameDest, currentEntry->d_name); 00347 if (ret != PAL_SUCCESS) 00348 { 00349 break; 00350 } 00351 } 00352 else 00353 {//End of directory reached without errors break and close directory and exit 00354 break; 00355 } 00356 }//while() 00357 } 00358 00359 if (src_dh) 00360 { 00361 closedir(src_dh); 00362 } 00363 return ret; 00364 } 00365 00366 00367 PAL_PRIVATE palStatus_t pal_plat_fsCpFile(const char *pathNameSrc, char *pathNameDest, char * fileName) 00368 { 00369 palStatus_t ret = PAL_SUCCESS; 00370 palFileDescriptor_t src_fd = 0; 00371 palFileDescriptor_t dst_fd = 0; 00372 char buffer_name[PAL_MAX_FILE_AND_FOLDER_LENGTH] = {0}; //Buffer for coping the name and folder 00373 char * buffer = NULL; 00374 size_t bytesCount = 0; 00375 00376 //Add file name to path 00377 pal_plat_addFileNameToPath(pathNameSrc, fileName, buffer_name); 00378 src_fd = (palFileDescriptor_t)fopen(buffer_name, g_platOpenModeConvert[PAL_FS_FLAG_READONLY]); 00379 if (src_fd == 0) 00380 { 00381 ret = pal_plat_errorTranslation(errno); 00382 } 00383 else 00384 { 00385 //Add file name to path 00386 pal_plat_addFileNameToPath(pathNameDest, fileName, buffer_name); 00387 dst_fd = (palFileDescriptor_t)fopen(buffer_name, g_platOpenModeConvert[PAL_FS_FLAG_READWRITETRUNC]); 00388 if (dst_fd == 0) 00389 { 00390 ret = pal_plat_errorTranslation(errno); 00391 } 00392 else 00393 { 00394 buffer = (char*)malloc(PAL_FS_COPY_BUFFER_SIZE); 00395 if (!buffer) 00396 { 00397 ret = PAL_ERR_RTOS_RESOURCE ; 00398 } 00399 } 00400 } 00401 00402 if (ret == PAL_SUCCESS) 00403 { 00404 while (1) 00405 { 00406 ret = pal_fsFread(&src_fd, buffer, PAL_FS_COPY_BUFFER_SIZE, &bytesCount); 00407 if (ret != PAL_SUCCESS) 00408 { 00409 break; 00410 } 00411 00412 //Check if end of file reached 00413 if (bytesCount == 0) 00414 { 00415 break; 00416 } 00417 00418 ret = pal_fsFwrite(&dst_fd, buffer, bytesCount, &bytesCount); 00419 if (ret != PAL_SUCCESS) 00420 { 00421 break; 00422 } 00423 } 00424 } 00425 00426 if (src_fd != 0) 00427 { 00428 pal_fsFclose(&src_fd); 00429 } 00430 if (dst_fd != 0) 00431 { 00432 pal_fsFclose(&dst_fd); 00433 } 00434 if (buffer) 00435 { 00436 free(buffer); 00437 } 00438 return ret; 00439 } 00440 00441 00442 const char* pal_plat_fsGetDefaultRootFolder(pal_fsStorageID_t dataID) 00443 { 00444 const char* returnedRoot = NULL; 00445 if (PAL_FS_PARTITION_PRIMARY == dataID) 00446 { 00447 returnedRoot = PAL_FS_MOUNT_POINT_PRIMARY; 00448 } 00449 else if (PAL_FS_PARTITION_SECONDARY == dataID) 00450 { 00451 returnedRoot = PAL_FS_MOUNT_POINT_SECONDARY; 00452 } 00453 00454 return returnedRoot; 00455 } 00456 00457 00458 PAL_PRIVATE bool pal_plat_findNextFile(DIR *dh, struct dirent ** CurrentEntry) 00459 { 00460 bool ret = true; 00461 bool skip = false; 00462 bool foundFile = false; 00463 00464 do 00465 { 00466 errno = 0; 00467 *CurrentEntry = readdir(dh); 00468 if (*CurrentEntry) 00469 { 00470 /* Skip the names "." and ".." as we don't want to remove them. also make sure that the current entry point to REGULER file*/ 00471 skip = (!strcmp((*CurrentEntry)->d_name, ".")) || (!strcmp((*CurrentEntry)->d_name, "..")); 00472 if (skip) 00473 { 00474 continue; 00475 } 00476 else 00477 { 00478 foundFile = true; 00479 } 00480 } 00481 else 00482 {//Check if EOF reached 00483 if (errno) 00484 {//NOT!!! EOF other error 00485 ret = false; 00486 } 00487 break; //Break from while 00488 } 00489 } 00490 while((!foundFile) && (ret)); //While file has been found or ret is set to false 00491 00492 return ret; 00493 } 00494 00495 PAL_PRIVATE palStatus_t pal_plat_addFileNameToPath(const char *pathName, const char * fileName, char * fullPath) 00496 { 00497 palStatus_t ret = PAL_SUCCESS; 00498 00499 if ((strlen(pathName) >= PAL_MAX_FOLDER_DEPTH_CHAR) || (strlen(fileName) >= PAL_MAX_FULL_FILE_NAME)) 00500 { 00501 ret = PAL_ERR_FS_FILENAME_LENGTH; 00502 } 00503 else if (fullPath) 00504 { 00505 strcpy(fullPath, pathName); 00506 strcat(fullPath, "/"); 00507 strcat(fullPath, fileName); 00508 } 00509 else 00510 { 00511 ret = PAL_ERR_RTOS_RESOURCE ; 00512 } 00513 return ret; 00514 } 00515 00516 00517 00518 00519 PAL_PRIVATE palStatus_t pal_plat_errorTranslation (int errorOpCode) 00520 { 00521 palStatus_t ret = PAL_SUCCESS; 00522 00523 switch(errorOpCode) 00524 { 00525 case 0: 00526 break; 00527 case EACCES: 00528 case EFAULT: 00529 case EROFS: 00530 ret = PAL_ERR_FS_ACCESS_DENIED; 00531 break; 00532 00533 case EBUSY : 00534 ret = PAL_ERR_FS_BUSY; 00535 break; 00536 00537 case EEXIST: 00538 ret = PAL_ERR_FS_NAME_ALREADY_EXIST; 00539 break; 00540 00541 case ENAMETOOLONG: 00542 ret = PAL_ERR_FS_FILENAME_LENGTH; 00543 break; 00544 00545 case EBADF: 00546 ret = PAL_ERR_FS_BAD_FD; 00547 break; 00548 00549 case EINVAL: 00550 ret = PAL_ERR_FS_INVALID_ARGUMENT; 00551 break; 00552 00553 case EISDIR: 00554 ret = PAL_ERR_FS_FILE_IS_DIR; 00555 break; 00556 00557 case ENOTEMPTY: 00558 ret = PAL_ERR_FS_DIR_NOT_EMPTY; 00559 break; 00560 00561 case ENOENT: 00562 ret = PAL_ERR_FS_NO_FILE; 00563 break; 00564 00565 default: 00566 ret = PAL_ERR_FS_ERROR; 00567 break; 00568 } 00569 return ret; 00570 } 00571 00572 00573 size_t pal_plat_fsSizeCheck(const char *stringToChk) 00574 { 00575 size_t length = 0; 00576 length = strlen(stringToChk); 00577 return length; 00578 } 00579 00580 00581 00582 00583 00584 palStatus_t pal_plat_fsFormat(pal_fsStorageID_t dataID) 00585 { 00586 const char* partitionTranslationArray[] = 00587 { 00588 PAL_FS_MOUNT_POINT_PRIMARY, 00589 PAL_FS_MOUNT_POINT_SECONDARY 00590 };// "/sd\0" 00591 FileSystem *myFs; 00592 int err = 0; 00593 palStatus_t status = PAL_SUCCESS; 00594 FilePath myPath(partitionTranslationArray[dataID]); 00595 myFs = (FileSystem*)myPath.fileSystem(); 00596 if (NULL != myFs) 00597 { 00598 err = myFs->reformat(NULL); 00599 if (err < 0) 00600 { 00601 status = PAL_ERR_FS_ERROR; 00602 } 00603 } 00604 else //This should not happen 00605 { 00606 status = PAL_ERR_FS_ERROR; 00607 } 00608 return status; 00609 } 00610
Generated on Tue Jul 12 2022 19:01:36 by 1.7.2