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

4.115
Last change on this file since fa028bb was fa028bb, checked in by Sebastian Huber <sebastian.huber@…>, on 11/17/14 at 10:55:27

shell: Do chroot() after successful login

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