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