2 FreeRTOS V9.0.0rc2 - Copyright (C) 2016 Real Time Engineers Ltd.
\r
5 VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
\r
7 This file is part of the FreeRTOS distribution.
\r
9 FreeRTOS is free software; you can redistribute it and/or modify it under
\r
10 the terms of the GNU General Public License (version 2) as published by the
\r
11 Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
\r
13 ***************************************************************************
\r
14 >>! NOTE: The modification to the GPL is included to allow you to !<<
\r
15 >>! distribute a combined work that includes FreeRTOS without being !<<
\r
16 >>! obliged to provide the source code for proprietary components !<<
\r
17 >>! outside of the FreeRTOS kernel. !<<
\r
18 ***************************************************************************
\r
20 FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
\r
21 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
\r
22 FOR A PARTICULAR PURPOSE. Full license text is available on the following
\r
23 link: http://www.freertos.org/a00114.html
\r
25 ***************************************************************************
\r
27 * FreeRTOS provides completely free yet professionally developed, *
\r
28 * robust, strictly quality controlled, supported, and cross *
\r
29 * platform software that is more than just the market leader, it *
\r
30 * is the industry's de facto standard. *
\r
32 * Help yourself get started quickly while simultaneously helping *
\r
33 * to support the FreeRTOS project by purchasing a FreeRTOS *
\r
34 * tutorial book, reference manual, or both: *
\r
35 * http://www.FreeRTOS.org/Documentation *
\r
37 ***************************************************************************
\r
39 http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
\r
40 the FAQ page "My application does not run, what could be wrong?". Have you
\r
41 defined configASSERT()?
\r
43 http://www.FreeRTOS.org/support - In return for receiving this top quality
\r
44 embedded software for free we request you assist our global community by
\r
45 participating in the support forum.
\r
47 http://www.FreeRTOS.org/training - Investing in training allows your team to
\r
48 be as productive as possible as early as possible. Now you can receive
\r
49 FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
\r
50 Ltd, and the world's leading authority on the world's leading RTOS.
\r
52 http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
\r
53 including FreeRTOS+Trace - an indispensable productivity tool, a DOS
\r
54 compatible FAT file system, and our tiny thread aware UDP/IP stack.
\r
56 http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
\r
57 Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
\r
59 http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
\r
60 Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
\r
61 licenses offer ticketed support, indemnification and commercial middleware.
\r
63 http://www.SafeRTOS.com - High Integrity Systems also provide a safety
\r
64 engineered and independently SIL3 certified version for use in safety and
\r
65 mission critical applications that require provable dependability.
\r
70 /* FreeRTOS includes. */
\r
71 #include "FreeRTOS.h"
\r
74 /* Standard includes. */
\r
79 /* FreeRTOS+CLI includes. */
\r
80 #include "FreeRTOS_CLI.h"
\r
82 /* File system includes. */
\r
83 #include <redposix.h>
\r
84 #include <redtests.h>
\r
87 #define snprintf _snprintf
\r
90 #define cliNEW_LINE "\r\n"
\r
92 /*******************************************************************************
\r
93 * See the URL in the comments within main.c for the location of the online
\r
95 ******************************************************************************/
\r
98 * Print out information on a single file.
\r
100 static void prvCreateFileInfoString( char *pcBuffer, REDDIRENT *pxDirent );
\r
103 * Copies an existing file into a newly created file.
\r
105 static BaseType_t prvPerformCopy( int32_t lSourceFildes,
\r
106 int32_t lDestinationFiledes,
\r
107 char *pxWriteBuffer,
\r
108 size_t xWriteBufferLen );
\r
111 * Implements the DIR command.
\r
113 static BaseType_t prvDIRCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString );
\r
116 * Implements the DEL command.
\r
118 static BaseType_t prvDELCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString );
\r
121 * Implements the TYPE command.
\r
123 static BaseType_t prvTYPECommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString );
\r
126 * Implements the APPEND command.
\r
128 static BaseType_t prvAPPENDCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString );
\r
131 * Implements the COPY command.
\r
133 static BaseType_t prvCOPYCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString );
\r
136 * Implements the CREATE command.
\r
138 static BaseType_t prvCREATECommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString );
\r
141 * Implements the MKDIR command.
\r
143 static BaseType_t prvMKDIRCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString );
\r
146 * Implements the RENAME command.
\r
148 static BaseType_t prvRENAMECommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString );
\r
151 * Implements the LINK command.
\r
153 static BaseType_t prvLINKCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString );
\r
156 * Implements the STAT command.
\r
158 static BaseType_t prvSTATCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString );
\r
161 * Implements the STATFS command.
\r
163 static BaseType_t prvSTATFSCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString );
\r
166 * Implements the FORMAT command.
\r
168 static BaseType_t prvFORMATCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString );
\r
171 * Implements the TRANSACT command.
\r
173 static BaseType_t prvTRANSACTCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString );
\r
176 * Implements the TRANSMASKGET command.
\r
178 static BaseType_t prvTRANSMASKGETCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString );
\r
181 * Implements the TRANSMASKSET command.
\r
183 static BaseType_t prvTRANSMASKSETCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString );
\r
186 * Implements the ABORT command.
\r
188 static BaseType_t prvABORTCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString );
\r
191 * Implements the TEST command.
\r
193 static BaseType_t prvTESTFSCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString );
\r
196 /* Structure that defines the DIR command line command, which lists all the
\r
197 files in the current directory. */
\r
198 static const CLI_Command_Definition_t xDIR =
\r
200 "dir", /* The command string to type. */
\r
201 "\r\ndir <filename>:\r\n Lists the files in the named directory\r\n",
\r
202 prvDIRCommand, /* The function to run. */
\r
203 1 /* One parameter is expected. */
\r
206 /* Structure that defines the TYPE command line command, which prints the
\r
207 contents of a file to the console. */
\r
208 static const CLI_Command_Definition_t xTYPE =
\r
210 "type", /* The command string to type. */
\r
211 "\r\ntype <filename>:\r\n Prints file contents to the terminal\r\n",
\r
212 prvTYPECommand, /* The function to run. */
\r
213 1 /* One parameter is expected. */
\r
216 /* Structure that defines the APPEND command line command, which appends data
\r
218 static const CLI_Command_Definition_t xAPPEND =
\r
220 "append", /* The command string to type. */
\r
221 "\r\nappend <filename> <character> <length>:\r\n Appends data to a file (created if it does not exist)\r\n",
\r
222 prvAPPENDCommand, /* The function to run. */
\r
223 3 /* Three parameters are expected. */
\r
226 /* Structure that defines the DEL command line command, which deletes a file. */
\r
227 static const CLI_Command_Definition_t xDEL =
\r
229 "del", /* The command string to type. */
\r
230 "\r\ndel <filename>:\r\n deletes a file or directory\r\n",
\r
231 prvDELCommand, /* The function to run. */
\r
232 1 /* One parameter is expected. */
\r
235 /* Structure that defines the COPY command line command, which copies a file. */
\r
236 static const CLI_Command_Definition_t xCOPY =
\r
238 "copy", /* The command string to type. */
\r
239 "\r\ncopy <source file> <dest file>:\r\n Copies <source file> to <dest file>\r\n",
\r
240 prvCOPYCommand, /* The function to run. */
\r
241 2 /* Two parameters are expected. */
\r
244 /* Structure that defines the CREATE command line command, which creates an
\r
246 static const CLI_Command_Definition_t xCREATE =
\r
248 "create", /* The command string to type. */
\r
249 "\r\ncreate <filename>:\r\n Creates an empty file\r\n",
\r
250 prvCREATECommand, /* The function to run. */
\r
251 1 /* One parameter is expected. */
\r
254 /* Structure that defines the MKDIR command line command, which creates an
\r
255 empty directory. */
\r
256 static const CLI_Command_Definition_t xMKDIR =
\r
258 "mkdir", /* The command string to type. */
\r
259 "\r\nmkdir <filename>:\r\n Creates an empty directory\r\n",
\r
260 prvMKDIRCommand, /* The function to run. */
\r
261 1 /* One parameter is expected. */
\r
264 /* Structure that defines the RENAME command line command, which renames a file. */
\r
265 static const CLI_Command_Definition_t xRENAME =
\r
267 "rename", /* The command string to type. */
\r
268 "\r\nrename <source file> <dest file>:\r\n Rename <source file> to <dest file>\r\n",
\r
269 prvRENAMECommand, /* The function to run. */
\r
270 2 /* Two parameters are expected. */
\r
273 /* Structure that defines the LINK command line command, which creates a hard
\r
275 static const CLI_Command_Definition_t xLINK =
\r
277 "link", /* The command string to type. */
\r
278 "\r\nlink <source file> <dest file>:\r\n Create hard link <dest file> pointing at <source file>\r\n",
\r
279 prvLINKCommand, /* The function to run. */
\r
280 2 /* Two parameters are expected. */
\r
283 /* Structure that defines the STAT command line command, which shows various
\r
284 information about a file. */
\r
285 static const CLI_Command_Definition_t xSTAT =
\r
287 "stat", /* The command string to type. */
\r
288 "\r\nstat <filename>:\r\n Show file information\r\n",
\r
289 prvSTATCommand, /* The function to run. */
\r
290 1 /* One parameter is expected. */
\r
293 /* Structure that defines the STATFS command line command, which shows various
\r
294 file system information. */
\r
295 static const CLI_Command_Definition_t xSTATFS =
\r
297 "statfs", /* The command string to type. */
\r
298 "\r\nstatfs:\r\n Show file system information.\r\n",
\r
299 prvSTATFSCommand, /* The function to run. */
\r
300 0 /* No parameters are expected. */
\r
303 /* Structure that defines the FORMAT command line command, which re-formats the
\r
305 static const CLI_Command_Definition_t xFORMAT =
\r
307 "format", /* The command string to type. */
\r
308 "\r\nformat:\r\n Re-formats the file system volume. ALL FILES WILL BE DELETED!\r\n",
\r
309 prvFORMATCommand, /* The function to run. */
\r
310 0 /* No parameters are expected. */
\r
313 /* Structure that defines the TRANSACT command line command, which commits a
\r
314 transaction point. */
\r
315 static const CLI_Command_Definition_t xTRANSACT =
\r
317 "transact", /* The command string to type. */
\r
318 "\r\ntransact:\r\n Commit a Reliance Edge transaction point\r\n",
\r
319 prvTRANSACTCommand, /* The function to run. */
\r
320 0 /* No parameters are expected. */
\r
323 /* Structure that defines the TRANSMASKGET command line command, which retrieves
\r
324 the current automatic transaction event mask. */
\r
325 static const CLI_Command_Definition_t xTRANSMASKGET =
\r
327 "transmaskget", /* The command string to type. */
\r
328 "\r\ntransmaskget:\r\n Retrieve the Reliance Edge automatic transaction mask\r\n",
\r
329 prvTRANSMASKGETCommand, /* The function to run. */
\r
330 0 /* No parameters are expected. */
\r
333 /* Structure that defines the TRANSMASKSET command line command, which sets the
\r
334 automatic transaction event mask. */
\r
335 static const CLI_Command_Definition_t xTRANSMASKSET =
\r
337 "transmaskset", /* The command string to type. */
\r
338 "\r\ntransmaskset <hex mask>:\r\n Set the Reliance Edge automatic transaction mask\r\n",
\r
339 prvTRANSMASKSETCommand, /* The function to run. */
\r
340 1 /* One parameter is expected. */
\r
343 /* Structure that defines the ABORT command line command, which rolls back
\r
344 changes which have not been transacted. */
\r
345 static const CLI_Command_Definition_t xABORT =
\r
347 "abort", /* The command string to type. */
\r
348 "\r\nabort:\r\n Roll back all changes not part of the last transaction point\r\n",
\r
349 prvABORTCommand, /* The function to run. */
\r
350 0 /* No parameters are expected. */
\r
353 /* Structure that defines the TEST-FS command line command, which executes some
\r
354 file system driver tests. */
\r
355 static const CLI_Command_Definition_t xTEST_FS =
\r
357 "test-fs", /* The command string to type. */
\r
358 "\r\ntest-fs:\r\n Executes file system tests. ALL FILES WILL BE DELETED!\r\n",
\r
359 prvTESTFSCommand, /* The function to run. */
\r
360 0 /* No parameters are expected. */
\r
363 /*-----------------------------------------------------------*/
\r
365 void vRegisterFileSystemCLICommands( void )
\r
367 /* Register all the command line commands defined immediately above. */
\r
368 FreeRTOS_CLIRegisterCommand( &xDIR );
\r
369 FreeRTOS_CLIRegisterCommand( &xTYPE );
\r
370 FreeRTOS_CLIRegisterCommand( &xAPPEND );
\r
371 FreeRTOS_CLIRegisterCommand( &xDEL );
\r
372 FreeRTOS_CLIRegisterCommand( &xCOPY );
\r
373 FreeRTOS_CLIRegisterCommand( &xCREATE );
\r
374 FreeRTOS_CLIRegisterCommand( &xMKDIR );
\r
375 FreeRTOS_CLIRegisterCommand( &xRENAME );
\r
376 FreeRTOS_CLIRegisterCommand( &xLINK );
\r
377 FreeRTOS_CLIRegisterCommand( &xSTAT );
\r
378 FreeRTOS_CLIRegisterCommand( &xSTATFS );
\r
379 FreeRTOS_CLIRegisterCommand( &xFORMAT );
\r
380 FreeRTOS_CLIRegisterCommand( &xTRANSACT );
\r
381 FreeRTOS_CLIRegisterCommand( &xTRANSMASKGET );
\r
382 FreeRTOS_CLIRegisterCommand( &xTRANSMASKSET );
\r
383 FreeRTOS_CLIRegisterCommand( &xABORT );
\r
384 FreeRTOS_CLIRegisterCommand( &xTEST_FS );
\r
386 /*-----------------------------------------------------------*/
\r
388 static BaseType_t prvDIRCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString )
\r
390 static REDDIR *pxDir = NULL;
\r
391 REDDIRENT *pxDirent;
\r
392 const char *pcParameter;
\r
393 BaseType_t xParameterStringLength, xReturn = pdFALSE;
\r
395 /* This assumes pcWriteBuffer is long enough. */
\r
396 ( void ) pcCommandString;
\r
398 /* Ensure the buffer leaves space for the \r\n. */
\r
399 configASSERT( xWriteBufferLen > ( strlen( cliNEW_LINE ) * 2 ) );
\r
400 xWriteBufferLen -= strlen( cliNEW_LINE );
\r
402 if( pxDir == NULL )
\r
404 /* Retrieve the directory to DIR. */
\r
405 pcParameter = FreeRTOS_CLIGetParameter
\r
407 pcCommandString, /* The command string itself. */
\r
408 1, /* Return the first parameter. */
\r
409 &xParameterStringLength /* Store the parameter string length. */
\r
412 /* Sanity check something was returned. */
\r
413 configASSERT( pcParameter );
\r
415 /* This is the first time this function has been executed since the Dir
\r
416 command was run. Open the directory. */
\r
417 pxDir = red_opendir( pcParameter );
\r
422 /* red_readdir() returns NULL either on error or upon reaching the
\r
423 end of the directory. Clear errno so these conditions can be
\r
426 pxDirent = red_readdir( pxDir );
\r
430 prvCreateFileInfoString( pcWriteBuffer, pxDirent );
\r
433 else if( red_errno == 0 )
\r
435 /* There are no more files. Close the directory. */
\r
436 red_closedir( pxDir );
\r
439 /* No string to return. */
\r
440 pcWriteBuffer[ 0 ] = 0x00;
\r
444 snprintf( pcWriteBuffer, xWriteBufferLen, "Error %d reading directory.", ( int ) red_errno );
\r
449 /* User-friendly messages for common errors. */
\r
450 switch( red_errno )
\r
453 snprintf( pcWriteBuffer, xWriteBufferLen, "Directory not found." );
\r
457 snprintf( pcWriteBuffer, xWriteBufferLen, "Directory not found or not a directory." );
\r
461 snprintf( pcWriteBuffer, xWriteBufferLen, "Error %d opening directory.", ( int ) red_errno );
\r
466 strcat( pcWriteBuffer, cliNEW_LINE );
\r
470 /*-----------------------------------------------------------*/
\r
472 static BaseType_t prvTYPECommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString )
\r
474 const char *pcParameter;
\r
475 BaseType_t xParameterStringLength, xReturn = pdTRUE;
\r
476 static int32_t lFildes = -1;
\r
478 int32_t lStatus, lBytesRead;
\r
479 size_t xColumns = 50U;
\r
481 /* Ensure there is always a null terminator after each character written. */
\r
482 memset( pcWriteBuffer, 0x00, xWriteBufferLen );
\r
484 /* Ensure the buffer leaves space for the \r\n. */
\r
485 configASSERT( xWriteBufferLen > ( strlen( cliNEW_LINE ) * 2 ) );
\r
486 xWriteBufferLen -= strlen( cliNEW_LINE );
\r
488 if( xWriteBufferLen < xColumns )
\r
490 /* Ensure the loop that uses xColumns as an end condition does not
\r
491 write off the end of the buffer. */
\r
492 xColumns = xWriteBufferLen;
\r
495 if( lFildes == -1 )
\r
497 /* The file has not been opened yet. Find the file name. */
\r
498 pcParameter = FreeRTOS_CLIGetParameter
\r
500 pcCommandString, /* The command string itself. */
\r
501 1, /* Return the first parameter. */
\r
502 &xParameterStringLength /* Store the parameter string length. */
\r
505 /* Sanity check something was returned. */
\r
506 configASSERT( pcParameter );
\r
508 /* Attempt to open the requested file. */
\r
509 lFildes = red_open( pcParameter, RED_O_RDONLY );
\r
510 if( lFildes == -1 )
\r
512 /* User-friendly messages for common errors. */
\r
513 switch( red_errno )
\r
517 snprintf( pcWriteBuffer, xWriteBufferLen, "File not found." );
\r
521 snprintf( pcWriteBuffer, xWriteBufferLen, "Error %d opening file.", ( int ) red_errno );
\r
527 /* Make sure this is a file, not a directory. */
\r
528 lStatus = red_fstat( lFildes, &finfo );
\r
531 if( RED_S_ISDIR( finfo.st_mode ) )
\r
533 snprintf( pcWriteBuffer, xWriteBufferLen, "Cannot TYPE a directory." );
\r
534 red_close( lFildes );
\r
540 snprintf( pcWriteBuffer, xWriteBufferLen, "Error %d querying file.", ( int ) red_errno );
\r
541 red_close( lFildes );
\r
547 if( lFildes != -1 )
\r
549 /* Read the next chunk of data from the file. */
\r
550 lBytesRead = red_read( lFildes, pcWriteBuffer, xColumns );
\r
552 if( lBytesRead < ( int32_t ) xColumns )
\r
554 /* Error or no more characters to return. */
\r
555 red_close( lFildes );
\r
560 if( lFildes == -1 )
\r
562 /* Either the file was not opened, or all the data from the file has
\r
563 been returned and the file is now closed. */
\r
567 strcat( pcWriteBuffer, cliNEW_LINE );
\r
571 /*-----------------------------------------------------------*/
\r
573 static BaseType_t prvAPPENDCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString )
\r
575 char *pcFileName = NULL;
\r
576 const char *pcCharacter = NULL, *pcLength;
\r
577 BaseType_t xParameterStringLength, xGoodParameters = pdTRUE;
\r
578 int32_t lFildes, lAppendLength = -1, lThisWrite, lTotalWritten, lBytesWritten;
\r
580 /* This function assumes xWriteBufferLen is large enough! */
\r
581 ( void ) xWriteBufferLen;
\r
583 /* Find the length to write. */
\r
584 pcLength = FreeRTOS_CLIGetParameter
\r
586 pcCommandString, /* The command string itself. */
\r
587 3, /* Return the third parameter. */
\r
588 &xParameterStringLength /* Store the parameter string length. */
\r
590 configASSERT( pcLength );
\r
592 /* Convert the string into a number. */
\r
593 lAppendLength = RedAtoI( pcLength );
\r
594 if( lAppendLength < 0 )
\r
596 strcpy( pcWriteBuffer, "Third parameter cannot be a negative number." );
\r
597 xGoodParameters = pdFALSE;
\r
600 if( xGoodParameters )
\r
602 /* Find the character to write. */
\r
603 pcCharacter = FreeRTOS_CLIGetParameter
\r
605 pcCommandString, /* The command string itself. */
\r
606 2, /* Return the second parameter. */
\r
607 &xParameterStringLength /* Store the parameter string length. */
\r
609 configASSERT( pcCharacter );
\r
611 if( xParameterStringLength != 1 )
\r
613 strcpy( pcWriteBuffer, "Second parameter must be a single character." );
\r
614 xGoodParameters = pdFALSE;
\r
618 if( xGoodParameters )
\r
620 /* Find the file name. */
\r
621 pcFileName = ( char * ) FreeRTOS_CLIGetParameter
\r
623 pcCommandString, /* The command string itself. */
\r
624 1, /* Return the first parameter. */
\r
625 &xParameterStringLength /* Store the parameter string length. */
\r
627 configASSERT( pcFileName );
\r
629 /* Terminate the string. */
\r
630 pcFileName[ xParameterStringLength ] = 0x00;
\r
633 if( xGoodParameters )
\r
635 /* Attempt to open the requested file. */
\r
636 lFildes = red_open( pcFileName, RED_O_WRONLY|RED_O_APPEND|RED_O_CREAT );
\r
638 if( lFildes == -1 )
\r
640 /* User-friendly messages for common errors. */
\r
641 switch( red_errno )
\r
645 strcpy( pcWriteBuffer, "Bad file path." );
\r
649 strcpy( pcWriteBuffer, "Cannot append to a directory." );
\r
653 sprintf( pcWriteBuffer, "Error %d opening file.", ( int ) red_errno );
\r
659 /* Put the requested character into the buffer. */
\r
660 memset( pcWriteBuffer, pcCharacter[0], xWriteBufferLen );
\r
662 /* Append the data. */
\r
663 for( lTotalWritten = 0; lTotalWritten < lAppendLength; lTotalWritten += lThisWrite )
\r
665 lThisWrite = lAppendLength - lTotalWritten;
\r
666 if( lThisWrite > ( int32_t ) xWriteBufferLen )
\r
668 lThisWrite = ( int32_t ) xWriteBufferLen;
\r
671 lBytesWritten = red_write( lFildes, pcWriteBuffer, lThisWrite );
\r
672 if( lBytesWritten == -1 )
\r
674 /* User-friendly messages for common errors. */
\r
675 switch( red_errno )
\r
678 strcpy( pcWriteBuffer, "Out of disk space." );
\r
682 sprintf( pcWriteBuffer, "Error %d writing to file.", ( int ) red_errno );
\r
688 else if( lBytesWritten != lThisWrite )
\r
690 /* Some data was written, but not all of it. This only
\r
691 happens when the disk is full or the file reached its
\r
692 maximum size. That latter is unlikely in this demo. */
\r
693 strcpy( pcWriteBuffer, "Out of disk space." );
\r
698 if( lTotalWritten == lAppendLength )
\r
700 strcpy( pcWriteBuffer, "Append successful." );
\r
703 red_close( lFildes );
\r
707 strcat( pcWriteBuffer, cliNEW_LINE );
\r
711 /*-----------------------------------------------------------*/
\r
713 static BaseType_t prvDELCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString )
\r
715 const char *pcParameter;
\r
716 BaseType_t xParameterStringLength;
\r
719 /* This function assumes xWriteBufferLen is large enough! */
\r
720 ( void ) xWriteBufferLen;
\r
722 /* Obtain the parameter string. */
\r
723 pcParameter = FreeRTOS_CLIGetParameter
\r
725 pcCommandString, /* The command string itself. */
\r
726 1, /* Return the first parameter. */
\r
727 &xParameterStringLength /* Store the parameter string length. */
\r
730 /* Sanity check something was returned. */
\r
731 configASSERT( pcParameter );
\r
733 /* Attempt to delete the file or directory. */
\r
734 lStatus = red_unlink( pcParameter );
\r
738 sprintf( pcWriteBuffer, "%s was deleted", pcParameter );
\r
742 /* User-friendly messages for common errors. */
\r
743 switch( red_errno )
\r
747 sprintf( pcWriteBuffer, "File not found." );
\r
750 case RED_ENOTEMPTY :
\r
751 sprintf( pcWriteBuffer, "Cannot remove directory: not empty." );
\r
755 sprintf( pcWriteBuffer, "Error %d deleting file.", ( int ) red_errno );
\r
760 strcat( pcWriteBuffer, cliNEW_LINE );
\r
764 /*-----------------------------------------------------------*/
\r
766 static BaseType_t prvCOPYCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString )
\r
768 char *pcSourceFile;
\r
769 const char *pcDestinationFile;
\r
770 BaseType_t xParameterStringLength;
\r
771 int32_t lSourceFildes, lDestinationFildes;
\r
773 /* Obtain the name of the destination file. */
\r
774 pcDestinationFile = FreeRTOS_CLIGetParameter
\r
776 pcCommandString, /* The command string itself. */
\r
777 2, /* Return the second parameter. */
\r
778 &xParameterStringLength /* Store the parameter string length. */
\r
781 /* Sanity check something was returned. */
\r
782 configASSERT( pcDestinationFile );
\r
784 /* Obtain the name of the source file. */
\r
785 pcSourceFile = ( char * ) FreeRTOS_CLIGetParameter
\r
787 pcCommandString, /* The command string itself. */
\r
788 1, /* Return the first parameter. */
\r
789 &xParameterStringLength /* Store the parameter string length. */
\r
792 /* Sanity check something was returned. */
\r
793 configASSERT( pcSourceFile );
\r
795 /* Terminate the string. */
\r
796 pcSourceFile[ xParameterStringLength ] = 0x00;
\r
798 /* See if the source file exists, openm it if it does. */
\r
799 lSourceFildes = red_open( pcSourceFile, RED_O_RDONLY );
\r
801 if( lSourceFildes == -1 )
\r
803 sprintf( pcWriteBuffer, "Source file does not exist" );
\r
807 /* Create the destination file, error if it already exists. */
\r
808 lDestinationFildes = red_open( pcDestinationFile, RED_O_CREAT|RED_O_EXCL|RED_O_WRONLY );
\r
810 if( lDestinationFildes == -1 )
\r
812 sprintf( pcWriteBuffer, "Error: Destination file already exists" );
\r
816 if( prvPerformCopy( lSourceFildes, lDestinationFildes, pcWriteBuffer, xWriteBufferLen ) == pdPASS )
\r
818 sprintf( pcWriteBuffer, "Copy made" );
\r
822 sprintf( pcWriteBuffer, "Error during copy" );
\r
825 red_close( lDestinationFildes );
\r
828 red_close( lSourceFildes );
\r
831 strcat( pcWriteBuffer, cliNEW_LINE );
\r
835 /*-----------------------------------------------------------*/
\r
837 static BaseType_t prvCREATECommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString )
\r
839 const char *pcParameter;
\r
840 BaseType_t xParameterStringLength;
\r
843 /* This function assumes xWriteBufferLen is large enough! */
\r
844 ( void ) xWriteBufferLen;
\r
846 /* Obtain the parameter string. */
\r
847 pcParameter = FreeRTOS_CLIGetParameter
\r
849 pcCommandString, /* The command string itself. */
\r
850 1, /* Return the first parameter. */
\r
851 &xParameterStringLength /* Store the parameter string length. */
\r
854 /* Sanity check something was returned. */
\r
855 configASSERT( pcParameter );
\r
857 /* Attempt to create the file. */
\r
858 lFildes = red_open( pcParameter, RED_O_CREAT|RED_O_EXCL|RED_O_RDWR );
\r
860 if( lFildes != -1 )
\r
862 sprintf( pcWriteBuffer, "%s was created", pcParameter );
\r
863 red_close( lFildes );
\r
867 /* User-friendly messages for common errors. */
\r
868 switch( red_errno )
\r
872 sprintf( pcWriteBuffer, "Bad file path." );
\r
876 sprintf( pcWriteBuffer, "File already exists." );
\r
880 sprintf( pcWriteBuffer, "Error %d creating file.", ( int ) red_errno );
\r
885 strcat( pcWriteBuffer, cliNEW_LINE );
\r
889 /*-----------------------------------------------------------*/
\r
891 static BaseType_t prvMKDIRCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString )
\r
893 const char *pcParameter;
\r
894 BaseType_t xParameterStringLength;
\r
897 /* This function assumes xWriteBufferLen is large enough! */
\r
898 ( void ) xWriteBufferLen;
\r
900 /* Obtain the parameter string. */
\r
901 pcParameter = FreeRTOS_CLIGetParameter
\r
903 pcCommandString, /* The command string itself. */
\r
904 1, /* Return the first parameter. */
\r
905 &xParameterStringLength /* Store the parameter string length. */
\r
908 /* Sanity check something was returned. */
\r
909 configASSERT( pcParameter );
\r
911 /* Attempt to create the file. */
\r
912 lStatus = red_mkdir( pcParameter );
\r
916 sprintf( pcWriteBuffer, "%s was created", pcParameter );
\r
920 /* User-friendly messages for common errors. */
\r
921 switch( red_errno )
\r
925 sprintf( pcWriteBuffer, "Bad file path." );
\r
929 sprintf( pcWriteBuffer, "Directory already exists." );
\r
933 sprintf( pcWriteBuffer, "Error %d creating directory.", ( int ) red_errno );
\r
938 strcat( pcWriteBuffer, cliNEW_LINE );
\r
942 /*-----------------------------------------------------------*/
\r
944 static BaseType_t prvRENAMECommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString )
\r
946 const char *pcDestinationFile;
\r
947 char *pcSourceFile;
\r
948 BaseType_t xParameterStringLength;
\r
951 /* This function assumes xWriteBufferLen is large enough! */
\r
952 ( void ) xWriteBufferLen;
\r
954 /* Obtain the name of the destination file. */
\r
955 pcDestinationFile = FreeRTOS_CLIGetParameter
\r
957 pcCommandString, /* The command string itself. */
\r
958 2, /* Return the second parameter. */
\r
959 &xParameterStringLength /* Store the parameter string length. */
\r
962 /* Sanity check something was returned. */
\r
963 configASSERT( pcDestinationFile );
\r
965 /* Obtain the name of the source file. */
\r
966 pcSourceFile = ( char * ) FreeRTOS_CLIGetParameter
\r
968 pcCommandString, /* The command string itself. */
\r
969 1, /* Return the first parameter. */
\r
970 &xParameterStringLength /* Store the parameter string length. */
\r
973 /* Sanity check something was returned. */
\r
974 configASSERT( pcSourceFile );
\r
976 /* Terminate the string. */
\r
977 pcSourceFile[ xParameterStringLength ] = 0x00;
\r
979 /* Attempt to rename the file. */
\r
980 lStatus = red_rename( pcSourceFile, pcDestinationFile );
\r
984 sprintf( pcWriteBuffer, "%s was renamed to %s", pcSourceFile, pcDestinationFile );
\r
988 /* User-friendly messages for common errors. */
\r
989 switch( red_errno )
\r
994 sprintf( pcWriteBuffer, "Bad file path." );
\r
997 /* This will only be seen if POSIX rename is disabled. */
\r
999 sprintf( pcWriteBuffer, "Destination already exists." );
\r
1003 sprintf( pcWriteBuffer, "Error %d renaming file.", ( int ) red_errno );
\r
1008 strcat( pcWriteBuffer, cliNEW_LINE );
\r
1012 /*-----------------------------------------------------------*/
\r
1014 static BaseType_t prvLINKCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString )
\r
1016 const char *pcDestinationFile;
\r
1017 char *pcSourceFile;
\r
1018 BaseType_t xParameterStringLength;
\r
1021 /* This function assumes xWriteBufferLen is large enough! */
\r
1022 ( void ) xWriteBufferLen;
\r
1024 /* Obtain the name of the destination file. */
\r
1025 pcDestinationFile = FreeRTOS_CLIGetParameter
\r
1027 pcCommandString, /* The command string itself. */
\r
1028 2, /* Return the second parameter. */
\r
1029 &xParameterStringLength /* Store the parameter string length. */
\r
1032 /* Sanity check something was returned. */
\r
1033 configASSERT( pcDestinationFile );
\r
1035 /* Obtain the name of the source file. */
\r
1036 pcSourceFile = ( char * ) FreeRTOS_CLIGetParameter
\r
1038 pcCommandString, /* The command string itself. */
\r
1039 1, /* Return the first parameter. */
\r
1040 &xParameterStringLength /* Store the parameter string length. */
\r
1043 /* Sanity check something was returned. */
\r
1044 configASSERT( pcSourceFile );
\r
1046 /* Terminate the string. */
\r
1047 pcSourceFile[ xParameterStringLength ] = 0x00;
\r
1049 /* Attempt to create the hard link. */
\r
1050 lStatus = red_link( pcSourceFile, pcDestinationFile );
\r
1052 if( lStatus == 0 )
\r
1054 sprintf( pcWriteBuffer, "%s was linked to %s", pcDestinationFile, pcSourceFile );
\r
1058 /* User-friendly messages for common errors. */
\r
1059 switch( red_errno )
\r
1061 case RED_ENOTDIR :
\r
1063 sprintf( pcWriteBuffer, "Bad file path." );
\r
1067 sprintf( pcWriteBuffer, "Cannot link a directory." );
\r
1071 sprintf( pcWriteBuffer, "Too many hard links." );
\r
1075 sprintf( pcWriteBuffer, "Error %d linking file.", ( int ) red_errno );
\r
1080 strcat( pcWriteBuffer, cliNEW_LINE );
\r
1084 /*-----------------------------------------------------------*/
\r
1086 static BaseType_t prvSTATCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString )
\r
1088 const char *pcParameter, *pcModeString;
\r
1089 BaseType_t xParameterStringLength;
\r
1091 int32_t lFildes, lStatus;
\r
1093 /* Ensure the buffer leaves space for the \r\n. */
\r
1094 configASSERT( xWriteBufferLen > ( strlen( cliNEW_LINE ) * 2 ) );
\r
1095 xWriteBufferLen -= strlen( cliNEW_LINE );
\r
1097 /* Find the file name. */
\r
1098 pcParameter = FreeRTOS_CLIGetParameter
\r
1100 pcCommandString, /* The command string itself. */
\r
1101 1, /* Return the first parameter. */
\r
1102 &xParameterStringLength /* Store the parameter string length. */
\r
1105 /* Sanity check something was returned. */
\r
1106 configASSERT( pcParameter );
\r
1108 /* Attempt to open the requested file. */
\r
1109 lFildes = red_open( pcParameter, RED_O_RDONLY );
\r
1110 if( lFildes == -1 )
\r
1112 /* User-friendly messages for common errors. */
\r
1113 switch( red_errno )
\r
1116 case RED_ENOTDIR :
\r
1117 snprintf( pcWriteBuffer, xWriteBufferLen, "File not found." );
\r
1121 snprintf( pcWriteBuffer, xWriteBufferLen, "Error %d opening file.", ( int ) red_errno );
\r
1127 lStatus = red_fstat( lFildes, &finfo );
\r
1128 if( lStatus == 0 )
\r
1130 if( RED_S_ISDIR( finfo.st_mode ) )
\r
1132 pcModeString = "dir";
\r
1136 pcModeString = "file";
\r
1139 snprintf( pcWriteBuffer, xWriteBufferLen, "ino=%lu mode=0x%04x(%s) nlink=%x size=%lu blocks=%lu",
\r
1140 ( unsigned long ) finfo.st_ino, ( unsigned ) finfo.st_mode, pcModeString,
\r
1141 ( unsigned ) finfo.st_nlink, (unsigned long) finfo.st_size, (unsigned long) finfo.st_blocks );
\r
1145 snprintf( pcWriteBuffer, xWriteBufferLen, "Error %d querying file.", ( int ) red_errno );
\r
1148 red_close( lFildes );
\r
1151 strcat( pcWriteBuffer, cliNEW_LINE );
\r
1155 /*-----------------------------------------------------------*/
\r
1157 static BaseType_t prvSTATFSCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString )
\r
1162 /* Avoid compiler warnings. */
\r
1163 ( void ) pcCommandString;
\r
1165 /* Ensure the buffer leaves space for the \r\n. */
\r
1166 configASSERT( xWriteBufferLen > ( strlen( cliNEW_LINE ) * 2 ) );
\r
1167 xWriteBufferLen -= strlen( cliNEW_LINE );
\r
1169 lStatus = red_statvfs( "", &fsinfo );
\r
1171 if( lStatus == -1 )
\r
1173 snprintf( pcWriteBuffer, xWriteBufferLen, "Error %d querying file system.", ( int ) red_errno );
\r
1177 snprintf( pcWriteBuffer, xWriteBufferLen,
\r
1178 "Block size: %lu\r\n"
\r
1179 "Block count: %lu\r\n"
\r
1180 "Free blocks: %lu\r\n"
\r
1181 "Inode count: %lu\r\n"
\r
1182 "Free inodes: %lu\r\n",
\r
1183 ( unsigned long ) fsinfo.f_bsize, ( unsigned long ) fsinfo.f_blocks,
\r
1184 ( unsigned long ) fsinfo.f_bfree, ( unsigned long ) fsinfo.f_files,
\r
1185 ( unsigned long ) fsinfo.f_ffree );
\r
1188 strcat( pcWriteBuffer, cliNEW_LINE );
\r
1192 /*-----------------------------------------------------------*/
\r
1194 static BaseType_t prvFORMATCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString )
\r
1198 /* Avoid compiler warnings. */
\r
1199 ( void ) pcCommandString;
\r
1201 /* This function assumes xWriteBufferLen is large enough! */
\r
1202 ( void ) xWriteBufferLen;
\r
1204 /* File system volumes cannot be formatted while mounted. */
\r
1205 lStatus = red_umount( "" );
\r
1206 if( lStatus == -1 )
\r
1208 sprintf( pcWriteBuffer, "Error %d during unmount.", ( int ) red_errno );
\r
1212 /* Re-format the file system volume. */
\r
1213 lStatus = red_format( "" );
\r
1215 if( lStatus == -1 )
\r
1217 sprintf( pcWriteBuffer, "Error %d during format.", ( int ) red_errno );
\r
1221 /* Mount again so that other commands will work properly. */
\r
1222 lStatus = red_mount( "" );
\r
1224 if( lStatus == -1 )
\r
1226 sprintf( pcWriteBuffer, "Error %d during mount.", ( int ) red_errno );
\r
1230 strcpy( pcWriteBuffer, "Format successful." );
\r
1235 strcat( pcWriteBuffer, cliNEW_LINE );
\r
1239 /*-----------------------------------------------------------*/
\r
1241 static BaseType_t prvTRANSACTCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString )
\r
1245 /* Avoid compiler warnings. */
\r
1246 ( void ) pcCommandString;
\r
1248 /* This function assumes xWriteBufferLen is large enough! */
\r
1249 ( void ) xWriteBufferLen;
\r
1251 /* Save the original transaction mask settings. */
\r
1252 lStatus = red_transact( "" );
\r
1254 if( lStatus == -1 )
\r
1256 sprintf( pcWriteBuffer, "Error %d during transaction point.", ( int ) red_errno );
\r
1260 strcpy( pcWriteBuffer, "Transaction point successful." );
\r
1263 strcat( pcWriteBuffer, cliNEW_LINE );
\r
1267 /*-----------------------------------------------------------*/
\r
1269 static BaseType_t prvTRANSMASKGETCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString )
\r
1271 uint32_t ulEventMask;
\r
1274 /* Avoid compiler warnings. */
\r
1275 ( void ) pcCommandString;
\r
1277 /* Ensure the buffer leaves space for the \r\n. */
\r
1278 configASSERT( xWriteBufferLen > ( strlen( cliNEW_LINE ) * 2 ) );
\r
1279 xWriteBufferLen -= strlen( cliNEW_LINE );
\r
1281 lStatus = red_gettransmask( "", &ulEventMask );
\r
1282 if( lStatus == -1 )
\r
1284 snprintf( pcWriteBuffer, xWriteBufferLen, "Error %d retrieving automatic transaction event mask.", ( int ) red_errno );
\r
1288 snprintf( pcWriteBuffer, xWriteBufferLen,
\r
1289 "Current automatic transaction event mask: 0x%04lx\r\n"
\r
1290 "RED_TRANSACT_UMOUNT (0x0001): %s\r\n"
\r
1291 "RED_TRANSACT_CREAT (0x0002): %s\r\n"
\r
1292 "RED_TRANSACT_UNLINK (0x0004): %s\r\n"
\r
1293 "RED_TRANSACT_MKDIR (0x0008): %s\r\n"
\r
1294 "RED_TRANSACT_RENAME (0x0010): %s\r\n"
\r
1295 "RED_TRANSACT_LINK (0x0020): %s\r\n"
\r
1296 "RED_TRANSACT_CLOSE (0x0040): %s\r\n"
\r
1297 "RED_TRANSACT_WRITE (0x0080): %s\r\n"
\r
1298 "RED_TRANSACT_FSYNC (0x0100): %s\r\n"
\r
1299 "RED_TRANSACT_TRUNCATE (0x0200): %s\r\n"
\r
1300 "RED_TRANSACT_VOLFULL (0x0400): %s\r\n",
\r
1301 ( unsigned long ) ulEventMask,
\r
1302 ( ulEventMask & RED_TRANSACT_UMOUNT ) ? "Enabled" : "Disabled",
\r
1303 ( ulEventMask & RED_TRANSACT_CREAT ) ? "Enabled" : "Disabled",
\r
1304 ( ulEventMask & RED_TRANSACT_UNLINK ) ? "Enabled" : "Disabled",
\r
1305 ( ulEventMask & RED_TRANSACT_MKDIR ) ? "Enabled" : "Disabled",
\r
1306 ( ulEventMask & RED_TRANSACT_RENAME ) ? "Enabled" : "Disabled",
\r
1307 ( ulEventMask & RED_TRANSACT_LINK ) ? "Enabled" : "Disabled",
\r
1308 ( ulEventMask & RED_TRANSACT_CLOSE ) ? "Enabled" : "Disabled",
\r
1309 ( ulEventMask & RED_TRANSACT_WRITE ) ? "Enabled" : "Disabled",
\r
1310 ( ulEventMask & RED_TRANSACT_FSYNC ) ? "Enabled" : "Disabled",
\r
1311 ( ulEventMask & RED_TRANSACT_TRUNCATE ) ? "Enabled" : "Disabled",
\r
1312 ( ulEventMask & RED_TRANSACT_VOLFULL ) ? "Enabled" : "Disabled" );
\r
1315 strcat( pcWriteBuffer, cliNEW_LINE );
\r
1319 /*-----------------------------------------------------------*/
\r
1321 static BaseType_t prvTRANSMASKSETCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString )
\r
1323 const char *pcParameter;
\r
1324 BaseType_t xParameterStringLength;
\r
1325 uint32_t ulEventMask;
\r
1328 /* Ensure the buffer leaves space for the \r\n. */
\r
1329 configASSERT( xWriteBufferLen > ( strlen( cliNEW_LINE ) * 2 ) );
\r
1330 xWriteBufferLen -= strlen( cliNEW_LINE );
\r
1332 /* Obtain the parameter string. */
\r
1333 pcParameter = FreeRTOS_CLIGetParameter
\r
1335 pcCommandString, /* The command string itself. */
\r
1336 1, /* Return the first parameter. */
\r
1337 &xParameterStringLength /* Store the parameter string length. */
\r
1340 /* Sanity check something was returned. */
\r
1341 configASSERT( pcParameter );
\r
1343 if( ( pcParameter[0] == '0' ) && ( ( pcParameter[1] == 'x' ) || ( pcParameter[1] == 'X' ) ) )
\r
1348 /* Convert the argument into a value. */
\r
1349 RedHtoUL( pcParameter, &ulEventMask );
\r
1351 /* Set the new transaction mask. */
\r
1352 lStatus = red_settransmask( "", ulEventMask );
\r
1353 if( lStatus == -1 )
\r
1355 /* User-friendly messages for common errors. */
\r
1356 switch( red_errno )
\r
1359 snprintf( pcWriteBuffer, xWriteBufferLen, "Invalid bits in transaction mask." );
\r
1363 snprintf( pcWriteBuffer, xWriteBufferLen, "Error %d setting transaction mask.", ( int ) red_errno );
\r
1369 snprintf( pcWriteBuffer, xWriteBufferLen,
\r
1370 "Successfully set automatic transaction mask. Enabled events:\r\n"
\r
1371 "RED_TRANSACT_UMOUNT (0x0001): %s\r\n"
\r
1372 "RED_TRANSACT_CREAT (0x0002): %s\r\n"
\r
1373 "RED_TRANSACT_UNLINK (0x0004): %s\r\n"
\r
1374 "RED_TRANSACT_MKDIR (0x0008): %s\r\n"
\r
1375 "RED_TRANSACT_RENAME (0x0010): %s\r\n"
\r
1376 "RED_TRANSACT_LINK (0x0020): %s\r\n"
\r
1377 "RED_TRANSACT_CLOSE (0x0040): %s\r\n"
\r
1378 "RED_TRANSACT_WRITE (0x0080): %s\r\n"
\r
1379 "RED_TRANSACT_FSYNC (0x0100): %s\r\n"
\r
1380 "RED_TRANSACT_TRUNCATE (0x0200): %s\r\n"
\r
1381 "RED_TRANSACT_VOLFULL (0x0400): %s\r\n",
\r
1382 ( ulEventMask & RED_TRANSACT_UMOUNT ) ? "Enabled" : "Disabled",
\r
1383 ( ulEventMask & RED_TRANSACT_CREAT ) ? "Enabled" : "Disabled",
\r
1384 ( ulEventMask & RED_TRANSACT_UNLINK ) ? "Enabled" : "Disabled",
\r
1385 ( ulEventMask & RED_TRANSACT_MKDIR ) ? "Enabled" : "Disabled",
\r
1386 ( ulEventMask & RED_TRANSACT_RENAME ) ? "Enabled" : "Disabled",
\r
1387 ( ulEventMask & RED_TRANSACT_LINK ) ? "Enabled" : "Disabled",
\r
1388 ( ulEventMask & RED_TRANSACT_CLOSE ) ? "Enabled" : "Disabled",
\r
1389 ( ulEventMask & RED_TRANSACT_WRITE ) ? "Enabled" : "Disabled",
\r
1390 ( ulEventMask & RED_TRANSACT_FSYNC ) ? "Enabled" : "Disabled",
\r
1391 ( ulEventMask & RED_TRANSACT_TRUNCATE ) ? "Enabled" : "Disabled",
\r
1392 ( ulEventMask & RED_TRANSACT_VOLFULL ) ? "Enabled" : "Disabled" );
\r
1395 strcat( pcWriteBuffer, cliNEW_LINE );
\r
1399 /*-----------------------------------------------------------*/
\r
1401 static BaseType_t prvABORTCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString )
\r
1403 uint32_t ulEventMask;
\r
1406 /* Avoid compiler warnings. */
\r
1407 ( void ) pcCommandString;
\r
1409 /* This function assumes xWriteBufferLen is large enough! */
\r
1410 ( void ) xWriteBufferLen;
\r
1412 /* Save the original transaction mask settings. */
\r
1413 lStatus = red_gettransmask( "", &ulEventMask );
\r
1415 if( lStatus == -1 )
\r
1417 sprintf( pcWriteBuffer, "Error %d querying transaction mask.", ( int ) red_errno );
\r
1421 /* Make it so that red_umount() will not automatically commit a new
\r
1422 transaction point. */
\r
1423 lStatus = red_settransmask( "", ulEventMask & ~( ( uint32_t ) RED_TRANSACT_UMOUNT ) );
\r
1425 if( lStatus == -1 )
\r
1427 sprintf( pcWriteBuffer, "Error %d setting transaction mask.", ( int ) red_errno );
\r
1431 /* Unmount. Since red_umount() will not transact, all changes which
\r
1432 were not already transacted are rolled back. */
\r
1433 lStatus = red_umount( "" );
\r
1435 if( lStatus == -1 )
\r
1437 sprintf( pcWriteBuffer, "Error %d during unmount.", ( int ) red_errno );
\r
1441 /* Mount. Mount always starts from the last transaction point. */
\r
1442 lStatus = red_mount( "" );
\r
1444 if( lStatus == -1 )
\r
1446 sprintf( pcWriteBuffer, "Error %d during mount.", ( int ) red_errno );
\r
1450 strcpy( pcWriteBuffer, "Working state changes succesfully aborted." );
\r
1454 /* Restore the original transaction mask settings. */
\r
1455 red_settransmask( "", ulEventMask );
\r
1459 strcat( pcWriteBuffer, cliNEW_LINE );
\r
1463 /*-----------------------------------------------------------*/
\r
1465 static BaseType_t prvTESTFSCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString )
\r
1467 UBaseType_t uxOriginalPriority;
\r
1468 FSSTRESSPARAM param;
\r
1470 /* Avoid compiler warnings. */
\r
1471 ( void ) xWriteBufferLen;
\r
1472 ( void ) pcCommandString;
\r
1474 /* Limitations in the interaction with the Windows TCP/IP stack require
\r
1475 the command console to run at the idle priority. Raise the priority for
\r
1476 the duration of the tests to ensure there are not multiple switches to the
\r
1477 idle task as in the simulated environment the idle task hook function may
\r
1478 include a (relatively) long delay. */
\r
1479 uxOriginalPriority = uxTaskPriorityGet( NULL );
\r
1480 vTaskPrioritySet( NULL, configMAX_PRIORITIES - 1 );
\r
1482 /* Delete all files to avoid inteferring with the test. */
\r
1487 FsstressDefaultParams(¶m);
\r
1488 param.fVerbose = pdTRUE;
\r
1489 param.ulNops = 10000;
\r
1491 FsstressStart(¶m);
\r
1493 /* Clean up after the test. */
\r
1498 /* Reset back to the original priority. */
\r
1499 vTaskPrioritySet( NULL, uxOriginalPriority );
\r
1501 sprintf( pcWriteBuffer, "%s", "Test results were sent to Windows console" );
\r
1502 strcat( pcWriteBuffer, cliNEW_LINE );
\r
1506 /*-----------------------------------------------------------*/
\r
1508 static BaseType_t prvPerformCopy( int32_t lSourceFildes,
\r
1509 int32_t lDestinationFiledes,
\r
1510 char *pxWriteBuffer,
\r
1511 size_t xWriteBufferLen )
\r
1513 int32_t lBytesRead;
\r
1514 BaseType_t xReturn = pdPASS;
\r
1516 /* Assuming both files are at offset zero. */
\r
1520 /* Read the next block of data. */
\r
1521 lBytesRead = red_read( lSourceFildes, pxWriteBuffer, xWriteBufferLen );
\r
1522 if( lBytesRead <= 0 )
\r
1524 if( lBytesRead == -1)
\r
1526 /* Error reading from file. */
\r
1531 /* No error: reached end of file, time to stop. */
\r
1537 /* Write the block of data to the end of the file. */
\r
1538 if( red_write( lDestinationFiledes, pxWriteBuffer, lBytesRead ) != lBytesRead )
\r
1547 /*-----------------------------------------------------------*/
\r
1549 static void prvCreateFileInfoString( char *pcBuffer, REDDIRENT *pxDirent )
\r
1551 const char *pcFile = "file", *pcDirectory = "directory";
\r
1552 const char *pcAttrib;
\r
1554 /* Point pcAttrib to a string that describes the file. */
\r
1555 if( RED_S_ISDIR(pxDirent->d_stat.st_mode) )
\r
1557 pcAttrib = pcDirectory;
\r
1561 pcAttrib = pcFile;
\r
1564 /* Create a string that includes the file name, the file size and the
\r
1565 attributes string. */
\r
1566 sprintf( pcBuffer, "%s [%s] [size=%d]", pxDirent->d_name, pcAttrib, pxDirent->d_stat.st_size );
\r