source: rtems/testsuites/samples/fileio/init.c

Last change on this file was 99d6172, checked in by Zenon <zenon.hans.taneka@…>, on Nov 7, 2018 at 12:50:38 AM

Correct minor spelling and grammar errors

This work was performed as a GCI 2018 task.

  • Property mode set to 100644
File size: 27.9 KB
Line 
1/*
2 *  COPYRIGHT (c) 1989-2012.
3 *  On-Line Applications Research Corporation (OAR).
4 *
5 *  The license and distribution terms for this file may be
6 *  found in the file LICENSE in this distribution or at
7 *  http://www.rtems.org/license/LICENSE.
8 */
9
10#ifdef HAVE_CONFIG_H
11#include "config.h"
12#endif
13
14#define CONFIGURE_INIT
15#include "system.h"
16#include <sys/param.h>
17#include <crypt.h>
18#include <stdio.h>
19#include <string.h>
20#include <unistd.h>
21#include <stdlib.h>
22#include <errno.h>
23#include <rtems.h>
24#include <fcntl.h>
25#include <inttypes.h>
26#include <rtems/error.h>
27#include <rtems/dosfs.h>
28#include <ctype.h>
29#include <rtems/bdpart.h>
30#include <rtems/libcsupport.h>
31#include <rtems/fsmount.h>
32#include <rtems/ramdisk.h>
33#include <rtems/nvdisk.h>
34#include <rtems/nvdisk-sram.h>
35#include <rtems/shell.h>
36
37const char rtems_test_name[] = "FILE I/O";
38
39#if FILEIO_BUILD
40
41/**
42 * Let the IO system allocation the next available major number.
43 */
44#define RTEMS_DRIVER_AUTO_MAJOR (0)
45
46/**
47 * The NV Device descriptor. For this test it is just DRAM.
48 */
49rtems_nvdisk_device_desc rtems_nv_heap_device_descriptor[] =
50{
51  {
52    flags:  0,
53    base:   0,
54    size:   (size_t) 1024 * 1024,
55    nv_ops: &rtems_nvdisk_sram_handlers
56  }
57};
58
59/**
60 * The NV Disk configuration.
61 */
62const rtems_nvdisk_config rtems_nvdisk_configuration[] =
63{
64  {
65    block_size:         512,
66    device_count:       1,
67    devices:            &rtems_nv_heap_device_descriptor[0],
68    flags:              0,
69    info_level:         0
70  }
71};
72
73/**
74 * The number of NV Disk configurations.
75 */
76uint32_t rtems_nvdisk_configuration_size = 1;
77
78/*
79 * Table of FAT file systems that will be mounted
80 * with the "fsmount" function.
81 * See cpukit/libmisc/fsmount for definition of fields
82 */
83fstab_t fs_table[] = {
84  {
85    "/dev/hda1","/mnt/hda1", "dosfs",
86    RTEMS_FILESYSTEM_READ_WRITE,
87    FSMOUNT_MNT_OK | FSMOUNT_MNTPNT_CRTERR | FSMOUNT_MNT_FAILED,
88    0
89  },
90  {
91    "/dev/hda2","/mnt/hda2", "dosfs",
92    RTEMS_FILESYSTEM_READ_WRITE,
93    FSMOUNT_MNT_OK | FSMOUNT_MNTPNT_CRTERR | FSMOUNT_MNT_FAILED,
94    0
95  },
96  {
97    "/dev/hda3","/mnt/hda3", "dosfs",
98    RTEMS_FILESYSTEM_READ_WRITE,
99    FSMOUNT_MNT_OK | FSMOUNT_MNTPNT_CRTERR | FSMOUNT_MNT_FAILED,
100    0
101  },
102  {
103    "/dev/hda4","/mnt/hda4", "dosfs",
104    RTEMS_FILESYSTEM_READ_WRITE,
105    FSMOUNT_MNT_OK | FSMOUNT_MNTPNT_CRTERR | FSMOUNT_MNT_FAILED,
106    0
107  },
108  {
109    "/dev/hdc1","/mnt/hdc1", "dosfs",
110    RTEMS_FILESYSTEM_READ_WRITE,
111    FSMOUNT_MNT_OK | FSMOUNT_MNTPNT_CRTERR | FSMOUNT_MNT_FAILED,
112    0
113  },
114  {
115    "/dev/hdc2","/mnt/hdc2", "dosfs",
116    RTEMS_FILESYSTEM_READ_WRITE,
117    FSMOUNT_MNT_OK | FSMOUNT_MNTPNT_CRTERR | FSMOUNT_MNT_FAILED,
118    0
119  },
120  {
121    "/dev/hdc3","/mnt/hdc3", "dosfs",
122    RTEMS_FILESYSTEM_READ_WRITE,
123    FSMOUNT_MNT_OK | FSMOUNT_MNTPNT_CRTERR | FSMOUNT_MNT_FAILED,
124    0
125  },
126  {
127    "/dev/hdc4","/mnt/hdc4", "dosfs",
128    RTEMS_FILESYSTEM_READ_WRITE,
129    FSMOUNT_MNT_OK | FSMOUNT_MNTPNT_CRTERR | FSMOUNT_MNT_FAILED,
130    0
131  }
132};
133
134#define USE_SHELL
135
136#ifdef USE_SHELL
137
138static int
139shell_nvdisk_trace (int argc, char* argv[])
140{
141  const char* driver;
142  int         level;
143
144  if (argc != 3)
145  {
146    printf ("error: invalid number of options\n");
147    return 1;
148  }
149
150  driver = argv[1];
151  level  = strtoul (argv[2], 0, 0);
152 
153  int fd = open (driver, O_WRONLY, 0);
154  if (fd < 0)
155  {
156    printf ("error: driver open failed: %s\n", strerror (errno));
157    return 1;
158  }
159 
160  if (ioctl (fd, RTEMS_NVDISK_IOCTL_INFO_LEVEL, level) < 0)
161  {
162    printf ("error: driver set level failed: %s\n", strerror (errno));
163    return 1;
164  }
165 
166  close (fd);
167 
168  return 0;
169}
170
171static int
172shell_nvdisk_erase (int argc, char* argv[])
173{
174  const char* driver = NULL;
175  int         arg;
176  int         fd;
177 
178  for (arg = 1; arg < argc; arg++)
179  {
180    if (argv[arg][0] == '-')
181    {
182      printf ("error: invalid option: %s\n", argv[arg]);
183      return 1;
184    }
185    else
186    {
187      if (!driver)
188        driver = argv[arg];
189      else
190      {
191        printf ("error: only one driver name allowed: %s\n", argv[arg]);
192        return 1;
193      }
194    }
195  }
196 
197  printf ("erase nv disk: %s\n", driver);
198 
199  fd = open (driver, O_WRONLY, 0);
200  if (fd < 0)
201  {
202    printf ("error: nvdisk driver open failed: %s\n", strerror (errno));
203    return 1;
204  }
205 
206  if (ioctl (fd, RTEMS_NVDISK_IOCTL_ERASE_DISK) < 0)
207  {
208    printf ("error: nvdisk driver erase failed: %s\n", strerror (errno));
209    return 1;
210  }
211 
212  close (fd);
213 
214  printf ("nvdisk erased successful\n");
215
216  return 0;
217}
218
219static int
220shell_bdbuf_trace (int argc, char* argv[])
221{
222#if RTEMS_BDBUF_TRACE
223  extern bool rtems_bdbuf_tracer;
224  rtems_bdbuf_tracer = !rtems_bdbuf_tracer;
225  printf ("bdbuf trace: %d\n", rtems_bdbuf_tracer);
226#else
227  printf ("bdbuf trace disabled. Rebuild with enabled.\n");
228#endif
229  return 0;
230}
231
232static int
233disk_test_set_block_size (rtems_disk_device *dd, size_t size)
234{
235  return dd->ioctl (dd, RTEMS_BLKIO_SETBLKSIZE, &size);
236}
237
238static int
239disk_test_write_blocks (const char *name, int start, int count, size_t size)
240{
241  int                 block;
242  uint32_t*           ip;
243  uint32_t            value = 0;
244  int                 i;
245  rtems_bdbuf_buffer* bd;
246  rtems_status_code   sc;
247  int                 rv = 0;
248  rtems_disk_device*  dd;
249  int                 fd;
250
251  fd = open(name, O_RDWR);
252  if (fd < 0) {
253    printf ("error: cannot open disk\n");
254    rv = 1;
255  }
256
257  if (rv == 0 && rtems_disk_fd_get_disk_device(fd, &dd) != 0)
258  {
259    printf ("error: cannot obtain disk\n");
260    rv = 1;
261  }
262
263  if (fd >= 0 && close (fd) != 0)
264  {
265    printf ("error: close disk failed\n");
266    rv = 1;
267  }
268
269  if (rv == 0 && disk_test_set_block_size (dd, size) < 0)
270  {
271    printf ("error: set block size failed: %s\n", strerror (errno));
272    rv = 1;
273  }
274
275  for (block = start; rv == 0 && block < (start + count); block++)
276  {
277    sc = rtems_bdbuf_read (dd, block, &bd);
278    if (sc == RTEMS_SUCCESSFUL)
279    {
280      ip = (uint32_t*) bd->buffer;
281      for (i = 0; i < (size / sizeof (uint32_t)); i++, ip++, value++)
282        *ip = (size << 16) | value;
283
284      sc = rtems_bdbuf_release_modified (bd);
285      if (sc != RTEMS_SUCCESSFUL)
286      {
287        printf ("error: release block %d bd failed: %s\n",
288                block, rtems_status_text (sc));
289        rv = 1;
290      }
291    }
292    else
293    {
294      printf ("error: get block %d bd failed: %s\n",
295              block, rtems_status_text (sc));
296      rv = 1;
297    }
298  }
299
300  return rv;
301}
302
303static int
304disk_test_block_sizes (int argc, char *argv[])
305{
306  char* name;
307  int   start;
308  int   count;
309  int   size;
310
311  if (argc != (4 + 1))
312  {
313    printf ("error: need to supply a device path, start, block and size\n");
314    return 1;
315  }
316
317  name = argv[1];
318
319  start = strtoul (argv[2], 0, 0);
320  count = strtoul (argv[3], 0, 0);
321  size  = strtoul (argv[4], 0, 0);
322
323  return disk_test_write_blocks (name, start, count, size);
324}
325
326static uint32_t
327parse_size_arg (const char* arg)
328{
329  uint32_t size;
330  uint32_t scalar = 1;
331
332  size = strtoul (arg, 0, 0);
333  switch (arg[strlen (arg) - 1])
334  {
335    case 'b':
336      scalar = 1;
337      break;
338    case 'M':
339      scalar = 1024000;
340      break;
341    case 'm':
342      scalar = 1000000;
343      break;
344    case 'K':
345      scalar = 1024;
346      break;
347    case 'k':
348      scalar = 1000;
349      break;
350    default:
351      printf ("error: invalid scalar (b,M/m/K/k): %c\n", arg[strlen (arg) - 1]);
352      return 0;
353  }
354  return size * scalar;
355}
356
357static int
358create_ramdisk (int argc, char *argv[])
359{
360  rtems_status_code         sc;
361  int                       arg;
362  uint32_t                  size = 524288;
363  uint32_t                  block_size = 512;
364  uint32_t                  block_count;
365
366  for (arg = 0; arg < argc; ++arg)
367  {
368    if (argv[arg][0] == '-')
369    {
370      switch (argv[arg][1])
371      {
372        case 's':
373          ++arg;
374          if (arg == argc)
375          {
376            printf ("error: -s needs a size\n");
377            return 1;
378          }
379          size = parse_size_arg (argv[arg]);
380          if (size == 0)
381            return 1;
382          break;
383        case 'b':
384          ++arg;
385          if (arg == argc)
386          {
387            printf ("error: -b needs a size\n");
388            return 1;
389          }
390          block_size = parse_size_arg (argv[arg]);
391          if (size == 0)
392            return 1;
393          break;
394        default:
395          printf ("error: invalid option: %s\n", argv[arg]);
396          return 1;
397      }
398    }
399  }
400
401  block_count = size / block_size;
402
403  /*
404   * Register the RAM Disk driver.
405   */
406  printf ("Register RAM Disk Driver [blocks=%" PRIu32 \
407          " block-size=%" PRIu32 "]:",
408          block_count,
409          block_size);
410
411  sc = ramdisk_register(block_size, block_count, false, "/dev/rda");
412  if (sc != RTEMS_SUCCESSFUL)
413  {
414    printf ("error: ramdisk driver not initialised: %s\n",
415            rtems_status_text (sc));
416    return 1;
417  }
418
419  printf ("successful\n");
420
421  return 0;
422}
423
424static int
425create_nvdisk (int argc, char *argv[])
426{
427  rtems_status_code         sc;
428  int                       arg;
429  uint32_t                  size = 0;
430#if ADD_WHEN_NVDISK_HAS_CHANGED
431  uint32_t                  block_size = 0;
432#endif
433 
434  for (arg = 0; arg < argc; ++arg)
435  {
436    if (argv[arg][0] == '-')
437    {
438      switch (argv[arg][1])
439      {
440        case 's':
441          ++arg;
442          if (arg == argc)
443          {
444            printf ("error: -s needs a size\n");
445            return 1;
446          }
447          size = parse_size_arg (argv[arg]);
448          if (size == 0)
449            return 1;
450          break;
451#if ADD_WHEN_NVDISK_HAS_CHANGED
452        case 'b':
453          ++arg;
454          if (arg == argc)
455          {
456            printf ("error: -b needs a size\n");
457            return 1;
458          }
459          block_size = parse_size_arg (argv[arg]);
460          if (size == 0)
461            return 1;
462          break;
463#endif
464        default:
465          printf ("error: invalid option: %s\n", argv[arg]);
466          return 1;
467      }
468    }
469  }
470
471#if ADD_WHEN_NVDISK_HAS_CHANGED
472  if (block_size)
473    rtems_nvdisk_configuration[0].block_size = block_size;
474#endif
475  if (size)
476    rtems_nv_heap_device_descriptor[0].size = size;
477   
478  /*
479   * For our test we do not have any static RAM or EEPROM devices so
480   * we allocate the memory from the heap.
481   */
482  rtems_nv_heap_device_descriptor[0].base =
483    malloc (rtems_nv_heap_device_descriptor[0].size);
484
485  if (!rtems_nv_heap_device_descriptor[0].base)
486  {
487    printf ("error: no memory for NV disk\n");
488    return 1;
489  }
490 
491  /*
492   * Register the RAM Disk driver.
493   */
494  printf ("Register NV Disk Driver [size=%" PRIu32 \
495          " block-size=%" PRIu32"]:",
496          rtems_nv_heap_device_descriptor[0].size,
497          rtems_nvdisk_configuration[0].block_size);
498
499  sc = rtems_nvdisk_initialize (0, 0, NULL);
500  if (sc != RTEMS_SUCCESSFUL)
501  {
502    printf ("error: nvdisk driver not initialised: %s\n",
503            rtems_status_text (sc));
504    return 1;
505  }
506 
507  printf ("successful\n");
508
509  return 0;
510}
511
512static void writeFile(
513  const char *name,
514  mode_t      mode,
515  const char *contents
516)
517{
518  int sc;
519  sc = setuid(0);
520  if ( sc ) {
521    printf( "setuid failed: %s: %s\n", name, strerror(errno) );
522  }
523
524  rtems_shell_write_file( name, contents );
525
526  sc = chmod ( name, mode );
527  if ( sc ) {
528    printf( "chmod %s: %s\n", name, strerror(errno) );
529  }
530}
531
532#define writeScript( _name, _contents ) \
533        writeFile( _name, 0777, _contents )
534
535static void fileio_start_shell(void)
536{
537  int sc;
538
539  sc = mkdir("/scripts", 0777);
540  if ( sc ) {
541    printf( "mkdir /scripts: %s:\n", strerror(errno) );
542  }
543
544  sc = mkdir("/etc", 0777);
545  if ( sc ) {
546    printf( "mkdir /etc: %s:\n", strerror(errno) );
547  }
548
549  sc = mkdir("/chroot", 0777);
550  if ( sc ) {
551    printf( "mkdir /chroot: %s:\n", strerror(errno) );
552  }
553
554  printf(
555    "Creating /etc/passwd and group with four useable accounts:\n"
556    "  root/pwd\n"
557    "  test/pwd\n"
558    "  rtems/NO PASSWORD\n"
559    "  chroot/NO PASSWORD\n"
560    "Only the root user has access to all available commands.\n"
561  );
562
563  writeFile(
564    "/etc/passwd",
565    0644,
566    "root:$6$$FuPOhnllx6lhW2qqlnmWvZQLJ8Thr/09I7ESTdb9VbnTOn5.65"
567      "/Vh2Mqa6FoKXwT0nHS/O7F0KfrDc6Svb/sH.:0:0:root::/:/bin/sh\n"
568    "rtems::1:1:RTEMS Application::/:/bin/sh\n"
569    "test:$1$$oPu1Xt2Pw0ngIc7LyDHqu1:2:2:test account::/:/bin/sh\n"
570    "tty:*:3:3:tty owner::/:/bin/false\n"
571    "chroot::4:2:chroot account::/chroot:/bin/sh\n"
572  );
573  writeFile(
574    "/etc/group",
575    0644,
576    "root:x:0:root\n"
577    "rtems:x:1:rtems\n"
578    "test:x:2:test\n"
579    "tty:x:3:tty\n"
580  );
581
582  writeScript(
583    "/scripts/js",
584    "#! joel\n"
585    "\n"
586    "date\n"
587    "echo Script successfully ran\n"
588    "date\n"
589    "stackuse\n"
590  );
591
592  writeScript(
593    "/scripts/j1",
594    "#! joel -s 20480 -t JESS\n"
595    "stackuse\n"
596  );
597
598  rtems_shell_write_file(
599    "/scripts/j2",
600    "echo j2 TEST FILE\n"
601    "echo j2   SHOULD BE non-executable AND\n"
602    "echo j2   DOES NOT have the magic first line\n"
603  );
604
605  rtems_shell_add_cmd ("mkrd", "files",
606                       "Create a RAM disk driver", create_ramdisk);
607  rtems_shell_add_cmd ("mknvd", "files",
608                       "Create a NV disk driver", create_nvdisk);
609  rtems_shell_add_cmd ("nverase", "misc",
610                       "nverase driver", shell_nvdisk_erase);
611  rtems_shell_add_cmd ("nvtrace", "misc",
612                       "nvtrace driver level", shell_nvdisk_trace);
613  rtems_shell_add_cmd ("bdbuftrace", "files",
614                       "bdbuf trace toggle", shell_bdbuf_trace);
615  rtems_shell_add_cmd ("td", "files",
616                       "Test disk", disk_test_block_sizes);
617#if RTEMS_RFS_TRACE
618  rtems_shell_add_cmd ("rfs", "files",
619                       "RFS trace",
620                       rtems_rfs_trace_shell_command);
621#endif
622#if RTEMS_RFS_RTEMS_TRACE
623  rtems_shell_add_cmd ("rrfs", "files",
624                       "RTEMS RFS trace",
625                       rtems_rfs_rtems_trace_shell_command);
626#endif
627
628  printf(" =========================\n");
629  printf(" starting shell\n");
630  printf(" =========================\n");
631  rtems_shell_init(
632    "SHLL",                          /* task_name */
633    RTEMS_MINIMUM_STACK_SIZE * 4,    /* task_stacksize */
634    100,                             /* task_priority */
635    "/dev/foobar",                   /* devname */
636    /* device is currently ignored by the shell if it is not a pty */
637    false,                           /* forever */
638    true,                            /* wait */
639    rtems_shell_login_check          /* login */
640  );
641}
642#endif /* USE_SHELL */
643
644static void fileio_print_free_heap(void)
645{
646  printf("--- unused dynamic memory: %lu bytes ---\n",
647         (unsigned long) malloc_free_space());
648}
649
650
651static void fileio_part_table_initialize(void)
652{
653  char devname[64];
654  rtems_status_code rc;
655
656  printf(" =========================\n");
657  printf(" Initialize partition table\n");
658  printf(" =========================\n");
659  fileio_print_free_heap();
660  printf(" Enter device to initialize ==>");
661  fflush(stdout);
662  fgets(devname,sizeof(devname)-1,stdin);
663  while (devname[strlen(devname)-1] == '\n') {
664    devname[strlen(devname)-1] = '\0';
665  }
666  /*
667   * call function
668   */
669  rc = rtems_bdpart_register_from_disk(devname);
670  printf("result = %d\n",rc);
671  fileio_print_free_heap();
672}
673
674static void fileio_fsmount(void)
675{
676  rtems_status_code rc;
677
678  printf(" =========================\n");
679  printf(" Process fsmount table\n");
680  printf(" =========================\n");
681  fileio_print_free_heap();
682  /*
683   * call function
684   */
685  rc = rtems_fsmount( fs_table,
686                      sizeof(fs_table)/sizeof(fs_table[0]),
687                      NULL);
688  printf("result = %d\n",rc);
689  fileio_print_free_heap();
690}
691
692static void fileio_list_file(void)
693{
694  char fname[1024];
695  char *buf_ptr = NULL;
696  ssize_t   flen = 0;
697  int fd = -1;
698  ssize_t n;
699  size_t buf_size = 100;
700
701  rtems_interval start_tick,curr_tick,ticks_per_sec;
702
703  printf(" =========================\n");
704  printf(" LIST FILE ...            \n");
705  printf(" =========================\n");
706  fileio_print_free_heap();
707  printf(" Enter filename to list ==>");
708  fflush(stdout);
709  fgets(fname,sizeof(fname)-1,stdin);
710  while (fname[strlen(fname)-1] == '\n') {
711    fname[strlen(fname)-1] = '\0';
712  }
713  /*
714   * allocate buffer of given size
715   */
716  if (buf_size > 0) {
717    buf_ptr = malloc(buf_size);
718  }
719
720  if (buf_ptr != NULL) {
721    printf("\n Trying to open file \"%s\" for read\n",fname);
722    fd = open(fname,O_RDONLY);
723    if (fd < 0) {
724      printf("*** file failed to open, errno = %d(%s)\n",errno,strerror(errno));
725    }
726  }
727
728  if (fd >= 0) {
729    start_tick = rtems_clock_get_ticks_since_boot();
730    do {
731      n = read(fd,buf_ptr,buf_size);
732      if (n > 0) {
733        write(1,buf_ptr,(size_t) n);
734        flen += n;
735      }
736    } while (n > 0);
737
738    curr_tick = rtems_clock_get_ticks_since_boot();
739
740    printf("\n ******** End of file reached, flen = %zd\n",flen);
741    close(fd);
742
743    ticks_per_sec = rtems_clock_get_ticks_per_second();
744    printf("time elapsed for read:  %g seconds\n",
745           ((double)curr_tick-start_tick)/ticks_per_sec);
746  }
747  /*
748   * free buffer
749   */
750  if (buf_ptr != NULL) {
751    free(buf_ptr);
752  }
753  fileio_print_free_heap();
754}
755
756/*
757 * convert a size string (like 34K or 12M) to actual byte count
758 */
759static bool fileio_str2size(const char *str,uint32_t   *res_ptr)
760{
761  bool failed = false;
762  unsigned long size;
763  unsigned char suffix = ' ';
764
765  if (1 > sscanf(str,"%lu%c",&size,&suffix)) {
766    failed = true;
767  }
768  else if (toupper((int)suffix) == 'K') {
769    size *= 1024;
770  }
771  else if (toupper((int)suffix) == 'M') {
772    size *= 1024UL*1024UL;
773  }
774  else if (isalpha((int)suffix)) {
775    failed = true;
776  }
777
778  if (!failed) {
779    *res_ptr = size;
780  }
781  return failed;
782}
783
784static void fileio_write_file(void)
785{
786  char fname[1024];
787  char tmp_str[32];
788  uint32_t   file_size = 0;
789  uint32_t   buf_size  = 0;
790  size_t curr_pos,bytes_to_copy;
791  int fd = -1;
792  ssize_t n;
793  rtems_interval start_tick,curr_tick,ticks_per_sec;
794  char *bufptr = NULL;
795  bool failed = false;
796  static const char write_test_string[] =
797    "The quick brown fox jumps over the lazy dog\n";
798  static const char write_block_string[] =
799    "\n----- end of write buffer ------\n";
800
801  printf(" =========================\n");
802  printf(" WRITE FILE ...           \n");
803  printf(" =========================\n");
804  fileio_print_free_heap();
805  /*
806   * get number of ticks per second
807   */
808  ticks_per_sec = rtems_clock_get_ticks_per_second();
809
810  /*
811   * get path to file to write
812   */
813  if (!failed) {
814    printf("Enter path/filename ==>");
815    fflush(stdout);
816    fgets(fname,sizeof(fname)-1,stdin);
817    while (fname[strlen(fname)-1] == '\n') {
818      fname[strlen(fname)-1] = '\0';
819    }
820    if (0 == strlen(fname)) {
821      printf("*** no filename entered, aborted\n");
822      failed = true;
823    }
824  }
825  /*
826   * get total file size to write
827   */
828  if (!failed) {
829    printf("use suffix K for Kbytes, M for Mbytes or no suffix for bytes:\n"
830           "Enter filesize to write ==>");
831    fflush(stdout);
832    fgets(tmp_str,sizeof(tmp_str)-1,stdin);
833    failed = fileio_str2size(tmp_str,&file_size);
834    if (failed) {
835      printf("*** illegal file size, aborted\n");
836    }
837  }
838  /*
839   * get block size to write
840   */
841  if (!failed) {
842    printf("use suffix K for Kbytes, M for Mbytes or no suffix for bytes:\n"
843           "Enter block size to use for write calls ==>");
844    fflush(stdout);
845    fgets(tmp_str,sizeof(tmp_str)-1,stdin);
846    failed = fileio_str2size(tmp_str,&buf_size);
847    if (failed) {
848      printf("*** illegal block size, aborted\n");
849    }
850  }
851
852  /*
853   * allocate buffer
854   */
855  if (!failed) {
856    printf("... allocating %lu bytes of buffer for write data\n",
857           (unsigned long)buf_size);
858    bufptr = malloc(buf_size+1); /* extra space for terminating NUL char */
859    if (bufptr == NULL) {
860      printf("*** malloc failed, aborted\n");
861      failed = true;
862    }
863  }
864  /*
865   * fill buffer with test pattern
866   */
867  if (!failed) {
868    printf("... filling buffer with write data\n");
869    curr_pos = 0;
870    /*
871     * fill buffer with test string
872     */
873    while (curr_pos < buf_size) {
874      bytes_to_copy = MIN(buf_size-curr_pos,
875                          sizeof(write_test_string)-1);
876      memcpy(bufptr+curr_pos,write_test_string,bytes_to_copy);
877      curr_pos += bytes_to_copy;
878    }
879    /*
880     * put "end" mark at end of buffer
881     */
882    bytes_to_copy = sizeof(write_block_string)-1;
883    if (buf_size >= bytes_to_copy) {
884      memcpy(bufptr+buf_size-bytes_to_copy,
885             write_block_string,
886             bytes_to_copy);
887    }
888  }
889  /*
890   * create file
891   */
892  if (!failed) {
893    printf("... creating file \"%s\"\n",fname);
894    fd = open(fname,O_WRONLY | O_CREAT | O_TRUNC,S_IREAD|S_IWRITE);
895    if (fd < 0) {
896      printf("*** file create failed, errno = %d(%s)\n",errno,strerror(errno));
897      failed = true;
898    }
899  }
900  /*
901   * write file
902   */
903  if (!failed) {
904    printf("... writing to file\n");
905    start_tick = rtems_clock_get_ticks_since_boot();
906    curr_pos = 0;
907    do {
908      bytes_to_copy = buf_size;
909      do {
910        n = write(fd,
911          bufptr + (buf_size-bytes_to_copy),
912                  MIN(bytes_to_copy,file_size-curr_pos));
913        if (n > 0) {
914          bytes_to_copy -= (size_t) n;
915          curr_pos      += (size_t) n;
916        }
917      } while ((bytes_to_copy > 0)  && (n > 0));
918    } while ((file_size > curr_pos) && (n > 0));
919    curr_tick = rtems_clock_get_ticks_since_boot();
920    if (n < 0) {
921      failed = true;
922      printf("*** file write failed, "
923             "%lu bytes written, "
924             "errno = %d(%s)\n",
925             (unsigned long)curr_pos,errno,strerror(errno));
926    }
927    else {
928      printf("time elapsed for write:  %g seconds\n",
929             ((double)curr_tick-start_tick)/ticks_per_sec);
930      printf("write data rate: %g KBytes/second\n",
931             (((double)file_size) / 1024.0 /
932              (((double)curr_tick-start_tick)/ticks_per_sec)));
933    }
934  }
935  if (fd >= 0) {
936    printf("... closing file\n");
937    close(fd);
938  }
939  if (bufptr != NULL) {
940    printf("... deallocating buffer\n");
941    free(bufptr);
942    bufptr = NULL;
943  }
944  printf("\n ******** End of file write\n");
945  fileio_print_free_heap();
946}
947
948static void fileio_read_file(void)
949{
950  char fname[1024];
951  char tmp_str[32];
952  uint32_t   buf_size  = 0;
953  size_t curr_pos;
954  int fd = -1;
955  ssize_t n;
956  rtems_interval start_tick,curr_tick,ticks_per_sec;
957  char *bufptr = NULL;
958  bool failed = false;
959
960  printf(" =========================\n");
961  printf(" READ FILE ...            \n");
962  printf(" =========================\n");
963  fileio_print_free_heap();
964  /*
965   * get number of ticks per second
966   */
967  ticks_per_sec = rtems_clock_get_ticks_per_second();
968
969  /*
970   * get path to file to read
971   */
972  if (!failed) {
973    printf("Enter path/filename ==>");
974    fflush(stdout);
975    fgets(fname,sizeof(fname)-1,stdin);
976    while (fname[strlen(fname)-1] == '\n') {
977      fname[strlen(fname)-1] = '\0';
978    }
979    if (0 == strlen(fname)) {
980      printf("*** no filename entered, aborted\n");
981      failed = true;
982    }
983  }
984  /*
985   * get block size to read
986   */
987  if (!failed) {
988    printf("use suffix K for Kbytes, M for Mbytes or no suffix for bytes:\n"
989           "Enter block size to use for read calls ==>");
990    fflush(stdout);
991    fgets(tmp_str,sizeof(tmp_str)-1,stdin);
992    failed = fileio_str2size(tmp_str,&buf_size);
993    if (failed) {
994      printf("*** illegal block size, aborted\n");
995    }
996  }
997
998  /*
999   * allocate buffer
1000   */
1001  if (!failed) {
1002    printf("... allocating %lu bytes of buffer for write data\n",
1003           (unsigned long)buf_size);
1004    bufptr = malloc(buf_size+1); /* extra space for terminating NUL char */
1005    if (bufptr == NULL) {
1006      printf("*** malloc failed, aborted\n");
1007      failed = true;
1008    }
1009  }
1010  /*
1011   * open file
1012   */
1013  if (!failed) {
1014    printf("... opening file \"%s\"\n",fname);
1015    fd = open(fname,O_RDONLY);
1016    if (fd < 0) {
1017      printf("*** failed to open file, errno = %d(%s)\n",errno,strerror(errno));
1018      failed = true;
1019    }
1020  }
1021  /*
1022   * read file
1023   */
1024  if (!failed) {
1025    printf("... reading from file\n");
1026    start_tick = rtems_clock_get_ticks_since_boot();
1027    curr_pos = 0;
1028    do {
1029      n = read(fd,
1030               bufptr,
1031               buf_size);
1032      if (n > 0) {
1033        curr_pos      += (size_t) n;
1034      }
1035    } while (n > 0);
1036    curr_tick = rtems_clock_get_ticks_since_boot();
1037    if (n < 0) {
1038      failed = true;
1039      printf("*** file read failed, "
1040             "%lu bytes read, "
1041             "errno = %d(%s)\n",
1042             (unsigned long)curr_pos,errno,strerror(errno));
1043    }
1044    else {
1045      printf("%lu bytes read\n",
1046             (unsigned long)curr_pos);
1047      printf("time elapsed for read:  %g seconds\n",
1048             ((double)curr_tick-start_tick)/ticks_per_sec);
1049      printf("read data rate: %g KBytes/second\n",
1050             (((double)curr_pos) / 1024.0 /
1051              (((double)curr_tick-start_tick)/ticks_per_sec)));
1052    }
1053  }
1054  if (fd >= 0) {
1055    printf("... closing file\n");
1056    close(fd);
1057  }
1058  if (bufptr != NULL) {
1059    printf("... deallocating buffer\n");
1060    free(bufptr);
1061    bufptr = NULL;
1062  }
1063  printf("\n ******** End of file read\n");
1064  fileio_print_free_heap();
1065
1066}
1067
1068static void fileio_menu (void)
1069{
1070  char inbuf[10];
1071
1072  /*
1073   * Wait for characters from console terminal
1074   */
1075  for (;;) {
1076    printf(" =========================\n");
1077    printf(" RTEMS FILE I/O Test Menu \n");
1078    printf(" =========================\n");
1079    printf("   p -> part_table_initialize\n");
1080    printf("   f -> mount all disks in fs_table\n");
1081    printf("   l -> list  file\n");
1082    printf("   r -> read  file\n");
1083    printf("   w -> write file\n");
1084#ifdef USE_SHELL
1085    printf("   s -> start shell\n");
1086#endif
1087    printf("   Enter your selection ==>");
1088    fflush(stdout);
1089
1090    inbuf[0] = '\0';
1091    fgets(inbuf,sizeof(inbuf),stdin);
1092    switch (inbuf[0]) {
1093    case 'l':
1094      fileio_list_file ();
1095      break;
1096    case 'r':
1097      fileio_read_file ();
1098      break;
1099    case 'w':
1100      fileio_write_file ();
1101      break;
1102    case 'p':
1103      fileio_part_table_initialize ();
1104      break;
1105    case 'f':
1106      fileio_fsmount ();
1107      break;
1108#ifdef USE_SHELL
1109    case 's':
1110      fileio_start_shell ();
1111      break;
1112#endif
1113    default:
1114      printf("Selection `%c` not implemented\n",inbuf[0]);
1115      break;
1116    }
1117
1118  }
1119  exit (0);
1120}
1121
1122/*
1123 * RTEMS File Menu Task
1124 */
1125static rtems_task
1126fileio_task (rtems_task_argument ignored)
1127{
1128  fileio_menu();
1129}
1130
1131static void
1132notification (int fd, int seconds_remaining, void *arg)
1133{
1134  printf(
1135    "Press any key to start file I/O sample (%is remaining)\n",
1136    seconds_remaining
1137  );
1138}
1139
1140/*
1141 * RTEMS Startup Task
1142 */
1143rtems_task
1144Init (rtems_task_argument ignored)
1145{
1146  rtems_name Task_name;
1147  rtems_id   Task_id;
1148  rtems_status_code status;
1149
1150  TEST_BEGIN();
1151
1152  crypt_add_format(&crypt_md5_format);
1153  crypt_add_format(&crypt_sha512_format);
1154
1155  status = rtems_shell_wait_for_input(
1156    STDIN_FILENO,
1157    20,
1158    notification,
1159    NULL
1160  );
1161  if (status == RTEMS_SUCCESSFUL) {
1162    Task_name = rtems_build_name('F','M','N','U');
1163
1164    status = rtems_task_create(
1165      Task_name, 1, RTEMS_MINIMUM_STACK_SIZE * 2,
1166      RTEMS_DEFAULT_MODES ,
1167      RTEMS_FLOATING_POINT | RTEMS_DEFAULT_ATTRIBUTES, &Task_id
1168    );
1169    directive_failed( status, "create" ); 
1170
1171    status = rtems_task_start( Task_id, fileio_task, 1 );
1172    directive_failed( status, "start" ); 
1173
1174    rtems_task_exit();
1175  } else {
1176    TEST_END();
1177
1178    rtems_test_exit( 0 );
1179  }
1180}
1181
1182#if defined(USE_SHELL)
1183/*
1184 *  RTEMS Shell Configuration -- Add a command and an alias for it
1185 */
1186
1187static int main_usercmd(int argc, char **argv)
1188{
1189  int i;
1190  printf( "UserCommand: argc=%d\n", argc );
1191  for (i=0 ; i<argc ; i++ )
1192    printf( "argv[%d]= %s\n", i, argv[i] );
1193  return 0;
1194}
1195
1196static rtems_shell_cmd_t Shell_USERCMD_Command = {
1197  "usercmd",                                       /* name */
1198  "usercmd n1 [n2 [n3...]]     # echo arguments",  /* usage */
1199  "user",                                          /* topic */
1200  main_usercmd,                                    /* command */
1201  NULL,                                            /* alias */
1202  NULL                                             /* next */
1203};
1204
1205static rtems_shell_alias_t Shell_USERECHO_Alias = {
1206  "usercmd",                 /* command */
1207  "userecho"                 /* alias */
1208};
1209
1210
1211#define CONFIGURE_SHELL_USER_COMMANDS &Shell_USERCMD_Command
1212#define CONFIGURE_SHELL_USER_ALIASES &Shell_USERECHO_Alias
1213#define CONFIGURE_SHELL_COMMANDS_INIT
1214#define CONFIGURE_SHELL_COMMANDS_ALL
1215#define CONFIGURE_SHELL_MOUNT_MSDOS
1216#define CONFIGURE_SHELL_MOUNT_RFS
1217#define CONFIGURE_SHELL_DEBUGRFS
1218
1219#include <rtems/shellconfig.h>
1220#endif
1221
1222#else
1223/*
1224 * RTEMS Startup Task
1225 */
1226rtems_task
1227Init (rtems_task_argument ignored)
1228{
1229  puts( "\n\n*** FILE I/O SAMPLE AND TEST ***" );
1230  puts( "\n\n*** NOT ENOUGH MEMORY TO BUILD AND RUN ***" );
1231}
1232#endif
Note: See TracBrowser for help on using the repository browser.