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