source: rtems/testsuites/samples/fileio/init.c @ 558a5f48

4.104.115
Last change on this file since 558a5f48 was 558a5f48, checked in by Chris Johns <chrisj@…>, on 06/02/10 at 00:47:15

2010-06-02 Chris Johns <chrisj@…>

  • fileio/init.c: Update to new mount API.
  • iostream/init.cc: Hack to work around confdefs.h in C++.
  • iostream/system.h: Add comment about base miniIMFS.
  • Property mode set to 100644
File size: 17.9 KB
Line 
1/*  Init
2 *
3 *  This routine is the initialization task for this test program.
4 *  It is called from init_exec and has the responsibility for creating
5 *  and starting the tasks that make up the test.  If the time of day
6 *  clock is required for the test, it should also be set to a known
7 *  value by this function.
8 *
9 *  Input parameters:  NONE
10 *
11 *  Output parameters:  NONE
12 *
13 *  COPYRIGHT (c) 1989-2009.
14 *  On-Line Applications Research Corporation (OAR).
15 *
16 *  The license and distribution terms for this file may be
17 *  found in the file LICENSE in this distribution or at
18 *  http://www.rtems.com/license/LICENSE.
19 *
20 *  $Id$
21 */
22
23#define CONFIGURE_INIT
24#include "system.h"
25#include <stdio.h>
26#include <string.h>
27#include <unistd.h>
28#include <stdlib.h>
29#include <errno.h>
30#include <rtems.h>
31#include <fcntl.h>
32#include <rtems/error.h>
33#include <rtems/dosfs.h>
34#include <ctype.h>
35#include <rtems/bdpart.h>
36#include <rtems/libcsupport.h>
37#include <rtems/fsmount.h>
38
39#if FILEIO_BUILD
40/*
41 * Table of FAT file systems that will be mounted
42 * with the "fsmount" function.
43 * See cpukit/libmisc/fsmount for definition of fields
44 */
45fstab_t fs_table[] = {
46  {
47    "/dev/hda1","/mnt/hda1", "dosfs",
48    RTEMS_FILESYSTEM_READ_WRITE,
49    FSMOUNT_MNT_OK | FSMOUNT_MNTPNT_CRTERR | FSMOUNT_MNT_FAILED,
50    0
51  },
52  {
53    "/dev/hda2","/mnt/hda2", "dosfs",
54    RTEMS_FILESYSTEM_READ_WRITE,
55    FSMOUNT_MNT_OK | FSMOUNT_MNTPNT_CRTERR | FSMOUNT_MNT_FAILED,
56    0
57  },
58  {
59    "/dev/hda3","/mnt/hda3", "dosfs",
60    RTEMS_FILESYSTEM_READ_WRITE,
61    FSMOUNT_MNT_OK | FSMOUNT_MNTPNT_CRTERR | FSMOUNT_MNT_FAILED,
62    0
63  },
64  {
65    "/dev/hda4","/mnt/hda4", "dosfs",
66    RTEMS_FILESYSTEM_READ_WRITE,
67    FSMOUNT_MNT_OK | FSMOUNT_MNTPNT_CRTERR | FSMOUNT_MNT_FAILED,
68    0
69  },
70  {
71    "/dev/hdc1","/mnt/hdc1", "dosfs",
72    RTEMS_FILESYSTEM_READ_WRITE,
73    FSMOUNT_MNT_OK | FSMOUNT_MNTPNT_CRTERR | FSMOUNT_MNT_FAILED,
74    0
75  },
76  {
77    "/dev/hdc2","/mnt/hdc2", "dosfs",
78    RTEMS_FILESYSTEM_READ_WRITE,
79    FSMOUNT_MNT_OK | FSMOUNT_MNTPNT_CRTERR | FSMOUNT_MNT_FAILED,
80    0
81  },
82  {
83    "/dev/hdc3","/mnt/hdc3", "dosfs",
84    RTEMS_FILESYSTEM_READ_WRITE,
85    FSMOUNT_MNT_OK | FSMOUNT_MNTPNT_CRTERR | FSMOUNT_MNT_FAILED,
86    0
87  },
88  {
89    "/dev/hdc4","/mnt/hdc4", "dosfs",
90    RTEMS_FILESYSTEM_READ_WRITE,
91    FSMOUNT_MNT_OK | FSMOUNT_MNTPNT_CRTERR | FSMOUNT_MNT_FAILED,
92    0
93  }
94};
95
96#define MIN(a,b) (((a) > (b)) ? (b) : (a))
97
98#define USE_SHELL
99
100#ifdef USE_SHELL
101#include <rtems/shell.h>
102
103static void writeFile(
104  const char *name,
105  mode_t      mode,
106  const char *contents
107)
108{
109  int sc;
110  sc = setuid(0);
111  if ( sc ) {
112    printf( "setuid failed: %s: %s\n", name, strerror(errno) );
113  }
114
115  rtems_shell_write_file( name, contents );
116
117  sc = chmod ( name, mode );
118  if ( sc ) {
119    printf( "chmod %s: %s\n", name, strerror(errno) );
120  }
121}
122
123#define writeScript( _name, _contents ) \
124        writeFile( _name, 0777, _contents )
125
126static void fileio_start_shell(void)
127{
128  int sc;
129
130  sc = mkdir("/scripts", 0777);
131  if ( sc ) {
132    printf( "mkdir /scripts: %s:\n", strerror(errno) );
133  }
134
135  sc = mkdir("/etc", 0777);
136  if ( sc ) {
137    printf( "mkdir /etc: %s:\n", strerror(errno) );
138  }
139
140  printf(
141    "Creating /etc/passwd and group with three useable accounts\n"
142    "root/pwd , test/pwd, rtems/NO PASSWORD"
143  );
144
145  writeFile(
146    "/etc/passwd",
147    0644,
148    "root:7QR4o148UPtb.:0:0:root::/:/bin/sh\n"
149    "rtems:*:1:1:RTEMS Application::/:/bin/sh\n"
150    "test:8Yy.AaxynxbLI:2:2:test account::/:/bin/sh\n"
151    "tty:!:3:3:tty owner::/:/bin/false\n"
152  );
153  writeFile(
154    "/etc/group",
155    0644,
156    "root:x:0:root\n"
157    "rtems:x:1:rtems\n"
158    "test:x:2:test\n"
159    "tty:x:3:tty\n"
160  );
161
162  writeScript(
163    "/scripts/js",
164    "#! joel\n"
165    "\n"
166    "date\n"
167    "echo Script successfully ran\n"
168    "date\n"
169    "stackuse\n"
170  );
171
172  writeScript(
173    "/scripts/j1",
174    "#! joel -s 20480 -t JESS\n"
175    "stackuse\n"
176  );
177
178  rtems_shell_write_file(
179    "/scripts/j2",
180    "echo j2 TEST FILE\n"
181    "echo j2   SHOULD BE non-executable AND\n"
182    "echo j2   DOES NOT have the magic first line\n"
183  );
184
185  printf(" =========================\n");
186  printf(" starting shell\n");
187  printf(" =========================\n");
188  rtems_shell_init(
189    "SHLL",                          /* task_name */
190    RTEMS_MINIMUM_STACK_SIZE * 4,    /* task_stacksize */
191    100,                             /* task_priority */
192    "/dev/console",                  /* devname */
193    false,                           /* forever */
194    true,                            /* wait */
195    rtems_shell_login_check          /* login */
196  );
197}
198#endif /* USE_SHELL */
199
200static void fileio_print_free_heap(void)
201{
202  printf("--- unused dynamic memory: %lu bytes ---\n",
203         (unsigned long) malloc_free_space());
204}
205
206
207static void fileio_part_table_initialize(void)
208{
209  char devname[64];
210  rtems_status_code rc;
211
212  printf(" =========================\n");
213  printf(" Initialize partition table\n");
214  printf(" =========================\n");
215  fileio_print_free_heap();
216  printf(" Enter device to initialize ==>");
217  fflush(stdout);
218  fgets(devname,sizeof(devname)-1,stdin);
219  while (devname[strlen(devname)-1] == '\n') {
220    devname[strlen(devname)-1] = '\0';
221  }
222  /*
223   * call function
224   */
225  rc = rtems_bdpart_register_from_disk(devname);
226  printf("result = %d\n",rc);
227  fileio_print_free_heap();
228}
229
230static void fileio_fsmount(void)
231{
232  rtems_status_code rc;
233
234  printf(" =========================\n");
235  printf(" Process fsmount table\n");
236  printf(" =========================\n");
237  fileio_print_free_heap();
238  /*
239   * call function
240   */
241  rc = rtems_fsmount( fs_table,
242                      sizeof(fs_table)/sizeof(fs_table[0]),
243                      NULL);
244  printf("result = %d\n",rc);
245  fileio_print_free_heap();
246}
247
248static void fileio_list_file(void)
249{
250  char fname[1024];
251  char *buf_ptr = NULL;
252  ssize_t   flen = 0;
253  int fd = -1;
254  ssize_t n;
255  size_t buf_size = 100;
256
257  rtems_interval start_tick,curr_tick,ticks_per_sec;
258
259  printf(" =========================\n");
260  printf(" LIST FILE ...            \n");
261  printf(" =========================\n");
262  fileio_print_free_heap();
263  printf(" Enter filename to list ==>");
264  fflush(stdout);
265  fgets(fname,sizeof(fname)-1,stdin);
266  while (fname[strlen(fname)-1] == '\n') {
267    fname[strlen(fname)-1] = '\0';
268  }
269  /*
270   * allocate buffer of given size
271   */
272  if (buf_size > 0) {
273    buf_ptr = malloc(buf_size);
274  }
275
276  if (buf_ptr != NULL) {
277    printf("\n Trying to open file \"%s\" for read\n",fname);
278    fd = open(fname,O_RDONLY);
279    if (fd < 0) {
280      printf("*** file open failed, errno = %d(%s)\n",errno,strerror(errno));
281    }
282  }
283
284  if (fd >= 0) {
285    rtems_clock_get (RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &start_tick);
286    do {
287      n = read(fd,buf_ptr,buf_size);
288      if (n > 0) {
289        write(1,buf_ptr,(size_t) n);
290        flen += n;
291      }
292    } while (n > 0);
293
294    rtems_clock_get (RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &curr_tick);
295
296    printf("\n ******** End of file reached, flen = %zd\n",flen);
297    close(fd);
298
299    ticks_per_sec = rtems_clock_get_ticks_per_second();
300    printf("time elapsed for read:  %g seconds\n",
301           ((double)curr_tick-start_tick)/ticks_per_sec);
302  }
303  /*
304   * free buffer
305   */
306  if (buf_ptr != NULL) {
307    free(buf_ptr);
308  }
309  fileio_print_free_heap();
310}
311
312/*
313 * convert a size string (like 34K or 12M) to actual byte count
314 */
315static bool fileio_str2size(const char *str,uint32_t   *res_ptr)
316{
317  bool failed = false;
318  unsigned long size;
319  unsigned char suffix = ' ';
320
321  if (1 > sscanf(str,"%lu%c",&size,&suffix)) {
322    failed = true;
323  }
324  else if (toupper((int)suffix) == 'K') {
325    size *= 1024;
326  }
327  else if (toupper((int)suffix) == 'M') {
328    size *= 1024UL*1024UL;
329  }
330  else if (isalpha((int)suffix)) {
331    failed = true;
332  }
333
334  if (!failed) {
335    *res_ptr = size;
336  }
337  return failed;
338}
339
340static void fileio_write_file(void)
341{
342  char fname[1024];
343  char tmp_str[32];
344  uint32_t   file_size = 0;
345  uint32_t   buf_size  = 0;
346  size_t curr_pos,bytes_to_copy;
347  int fd = -1;
348  ssize_t n;
349  rtems_interval start_tick,curr_tick,ticks_per_sec;
350  char *bufptr = NULL;
351  bool failed = false;
352  static const char write_test_string[] =
353    "The quick brown fox jumps over the lazy dog\n";
354  static const char write_block_string[] =
355    "\n----- end of write buffer ------\n";
356
357  printf(" =========================\n");
358  printf(" WRITE FILE ...           \n");
359  printf(" =========================\n");
360  fileio_print_free_heap();
361  /*
362   * get number of ticks per second
363   */
364  ticks_per_sec = rtems_clock_get_ticks_per_second();
365
366  /*
367   * get path to file to write
368   */
369  if (!failed) {
370    printf("Enter path/filename ==>");
371    fflush(stdout);
372    fgets(fname,sizeof(fname)-1,stdin);
373    while (fname[strlen(fname)-1] == '\n') {
374      fname[strlen(fname)-1] = '\0';
375    }
376    if (0 == strlen(fname)) {
377      printf("*** no filename entered, aborted\n");
378      failed = true;
379    }
380  }
381  /*
382   * get total file size to write
383   */
384  if (!failed) {
385    printf("use suffix K for Kbytes, M for Mbytes or no suffix for bytes:\n"
386           "Enter filesize to write ==>");
387    fflush(stdout);
388    fgets(tmp_str,sizeof(tmp_str)-1,stdin);
389    failed = fileio_str2size(tmp_str,&file_size);
390    if (failed) {
391      printf("*** illegal file size, aborted\n");
392    }
393  }
394  /*
395   * get block size to write
396   */
397  if (!failed) {
398    printf("use suffix K for Kbytes, M for Mbytes or no suffix for bytes:\n"
399           "Enter block size to use for write calls ==>");
400    fflush(stdout);
401    fgets(tmp_str,sizeof(tmp_str)-1,stdin);
402    failed = fileio_str2size(tmp_str,&buf_size);
403    if (failed) {
404      printf("*** illegal block size, aborted\n");
405    }
406  }
407
408  /*
409   * allocate buffer
410   */
411  if (!failed) {
412    printf("... allocating %lu bytes of buffer for write data\n",
413           (unsigned long)buf_size);
414    bufptr = malloc(buf_size+1); /* extra space for terminating NUL char */
415    if (bufptr == NULL) {
416      printf("*** malloc failed, aborted\n");
417      failed = true;
418    }
419  }
420  /*
421   * fill buffer with test pattern
422   */
423  if (!failed) {
424    printf("... filling buffer with write data\n");
425    curr_pos = 0;
426    /*
427     * fill buffer with test string
428     */
429    while (curr_pos < buf_size) {
430      bytes_to_copy = MIN(buf_size-curr_pos,
431                          sizeof(write_test_string)-1);
432      memcpy(bufptr+curr_pos,write_test_string,bytes_to_copy);
433      curr_pos += bytes_to_copy;
434    }
435    /*
436     * put "end" mark at end of buffer
437     */
438    bytes_to_copy = sizeof(write_block_string)-1;
439    if (buf_size >= bytes_to_copy) {
440      memcpy(bufptr+buf_size-bytes_to_copy,
441             write_block_string,
442             bytes_to_copy);
443    }
444  }
445  /*
446   * create file
447   */
448  if (!failed) {
449    printf("... creating file \"%s\"\n",fname);
450    fd = open(fname,O_WRONLY | O_CREAT | O_TRUNC,S_IREAD|S_IWRITE);
451    if (fd < 0) {
452      printf("*** file create failed, errno = %d(%s)\n",errno,strerror(errno));
453      failed = true;
454    }
455  }
456  /*
457   * write file
458   */
459  if (!failed) {
460    printf("... writing to file\n");
461    rtems_clock_get (RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &start_tick);
462    curr_pos = 0;
463    do {
464      bytes_to_copy = buf_size;
465      do {
466        n = write(fd,
467          bufptr + (buf_size-bytes_to_copy),
468                  MIN(bytes_to_copy,file_size-curr_pos));
469        if (n > 0) {
470          bytes_to_copy -= (size_t) n;
471          curr_pos      += (size_t) n;
472        }
473      } while ((bytes_to_copy > 0)  && (n > 0));
474    } while ((file_size > curr_pos) && (n > 0));
475    rtems_clock_get (RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &curr_tick);
476    if (n < 0) {
477      failed = true;
478      printf("*** file write failed, "
479             "%lu bytes written, "
480             "errno = %d(%s)\n",
481             (unsigned long)curr_pos,errno,strerror(errno));
482    }
483    else {
484      printf("time elapsed for write:  %g seconds\n",
485             ((double)curr_tick-start_tick)/ticks_per_sec);
486      printf("write data rate: %g KBytes/second\n",
487             (((double)file_size) / 1024.0 /
488              (((double)curr_tick-start_tick)/ticks_per_sec)));
489    }
490  }
491  if (fd >= 0) {
492    printf("... closing file\n");
493    close(fd);
494  }
495  if (bufptr != NULL) {
496    printf("... deallocating buffer\n");
497    free(bufptr);
498    bufptr = NULL;
499  }
500  printf("\n ******** End of file write\n");
501  fileio_print_free_heap();
502}
503
504static void fileio_read_file(void)
505{
506  char fname[1024];
507  char tmp_str[32];
508  uint32_t   buf_size  = 0;
509  size_t curr_pos;
510  int fd = -1;
511  ssize_t n;
512  rtems_interval start_tick,curr_tick,ticks_per_sec;
513  char *bufptr = NULL;
514  bool failed = false;
515
516  printf(" =========================\n");
517  printf(" READ FILE ...            \n");
518  printf(" =========================\n");
519  fileio_print_free_heap();
520  /*
521   * get number of ticks per second
522   */
523  ticks_per_sec = rtems_clock_get_ticks_per_second();
524
525  /*
526   * get path to file to read
527   */
528  if (!failed) {
529    printf("Enter path/filename ==>");
530    fflush(stdout);
531    fgets(fname,sizeof(fname)-1,stdin);
532    while (fname[strlen(fname)-1] == '\n') {
533      fname[strlen(fname)-1] = '\0';
534    }
535    if (0 == strlen(fname)) {
536      printf("*** no filename entered, aborted\n");
537      failed = true;
538    }
539  }
540  /*
541   * get block size to read
542   */
543  if (!failed) {
544    printf("use suffix K for Kbytes, M for Mbytes or no suffix for bytes:\n"
545           "Enter block size to use for read calls ==>");
546    fflush(stdout);
547    fgets(tmp_str,sizeof(tmp_str)-1,stdin);
548    failed = fileio_str2size(tmp_str,&buf_size);
549    if (failed) {
550      printf("*** illegal block size, aborted\n");
551    }
552  }
553
554  /*
555   * allocate buffer
556   */
557  if (!failed) {
558    printf("... allocating %lu bytes of buffer for write data\n",
559           (unsigned long)buf_size);
560    bufptr = malloc(buf_size+1); /* extra space for terminating NUL char */
561    if (bufptr == NULL) {
562      printf("*** malloc failed, aborted\n");
563      failed = true;
564    }
565  }
566  /*
567   * open file
568   */
569  if (!failed) {
570    printf("... opening file \"%s\"\n",fname);
571    fd = open(fname,O_RDONLY);
572    if (fd < 0) {
573      printf("*** file open failed, errno = %d(%s)\n",errno,strerror(errno));
574      failed = true;
575    }
576  }
577  /*
578   * read file
579   */
580  if (!failed) {
581    printf("... reading from file\n");
582    rtems_clock_get (RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &start_tick);
583    curr_pos = 0;
584    do {
585      n = read(fd,
586               bufptr,
587               buf_size);
588      if (n > 0) {
589        curr_pos      += (size_t) n;
590      }
591    } while (n > 0);
592    rtems_clock_get (RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &curr_tick);
593    if (n < 0) {
594      failed = true;
595      printf("*** file read failed, "
596             "%lu bytes read, "
597             "errno = %d(%s)\n",
598             (unsigned long)curr_pos,errno,strerror(errno));
599    }
600    else {
601      printf("%lu bytes read\n",
602             (unsigned long)curr_pos);
603      printf("time elapsed for read:  %g seconds\n",
604             ((double)curr_tick-start_tick)/ticks_per_sec);
605      printf("read data rate: %g KBytes/second\n",
606             (((double)curr_pos) / 1024.0 /
607              (((double)curr_tick-start_tick)/ticks_per_sec)));
608    }
609  }
610  if (fd >= 0) {
611    printf("... closing file\n");
612    close(fd);
613  }
614  if (bufptr != NULL) {
615    printf("... deallocating buffer\n");
616    free(bufptr);
617    bufptr = NULL;
618  }
619  printf("\n ******** End of file read\n");
620  fileio_print_free_heap();
621
622}
623
624static void fileio_menu (void)
625{
626  char inbuf[10];
627
628  /*
629   * Wait for characters from console terminal
630   */
631  for (;;) {
632    printf(" =========================\n");
633    printf(" RTEMS FILE I/O Test Menu \n");
634    printf(" =========================\n");
635    printf("   p -> part_table_initialize\n");
636    printf("   f -> mount all disks in fs_table\n");
637    printf("   l -> list  file\n");
638    printf("   r -> read  file\n");
639    printf("   w -> write file\n");
640#ifdef USE_SHELL
641    printf("   s -> start shell\n");
642#endif
643    printf("   Enter your selection ==>");
644    fflush(stdout);
645
646    inbuf[0] = '\0';
647    fgets(inbuf,sizeof(inbuf),stdin);
648    switch (inbuf[0]) {
649    case 'l':
650      fileio_list_file ();
651      break;
652    case 'r':
653      fileio_read_file ();
654      break;
655    case 'w':
656      fileio_write_file ();
657      break;
658    case 'p':
659      fileio_part_table_initialize ();
660      break;
661    case 'f':
662      fileio_fsmount ();
663      break;
664#ifdef USE_SHELL
665    case 's':
666      fileio_start_shell ();
667      break;
668#endif
669    default:
670      printf("Selection `%c` not implemented\n",inbuf[0]);
671      break;
672    }
673
674  }
675  exit (0);
676}
677
678/*
679 * RTEMS File Menu Task
680 */
681static rtems_task
682fileio_task (rtems_task_argument ignored)
683{
684  fileio_menu();
685}
686
687/*
688 * RTEMS Startup Task
689 */
690rtems_task
691Init (rtems_task_argument ignored)
692{
693  rtems_name Task_name;
694  rtems_id   Task_id;
695  rtems_status_code status;
696
697  puts( "\n\n*** FILE I/O SAMPLE AND TEST ***" );
698
699  Task_name = rtems_build_name('F','M','N','U');
700
701  status = rtems_task_create(
702    Task_name, 1, RTEMS_MINIMUM_STACK_SIZE * 2,
703    RTEMS_DEFAULT_MODES ,
704    RTEMS_FLOATING_POINT | RTEMS_DEFAULT_ATTRIBUTES, &Task_id
705  );
706
707  status = rtems_task_start( Task_id, fileio_task, 1 );
708
709  status = rtems_task_delete( RTEMS_SELF );
710}
711
712#if defined(USE_SHELL)
713/*
714 *  RTEMS Shell Configuration -- Add a command and an alias for it
715 */
716
717static int main_usercmd(int argc, char **argv)
718{
719  int i;
720  printf( "UserCommand: argc=%d\n", argc );
721  for (i=0 ; i<argc ; i++ )
722    printf( "argv[%d]= %s\n", i, argv[i] );
723  return 0;
724}
725
726static rtems_shell_cmd_t Shell_USERCMD_Command = {
727  "usercmd",                                       /* name */
728  "usercmd n1 [n2 [n3...]]     # echo arguments",  /* usage */
729  "user",                                          /* topic */
730  main_usercmd,                                    /* command */
731  NULL,                                            /* alias */
732  NULL                                             /* next */
733};
734
735static rtems_shell_alias_t Shell_USERECHO_Alias = {
736  "usercmd",                 /* command */
737  "userecho"                 /* alias */
738};
739
740
741#define CONFIGURE_SHELL_USER_COMMANDS &Shell_USERCMD_Command
742#define CONFIGURE_SHELL_USER_ALIASES &Shell_USERECHO_Alias
743#define CONFIGURE_SHELL_COMMANDS_INIT
744#define CONFIGURE_SHELL_COMMANDS_ALL
745#define CONFIGURE_SHELL_MOUNT_MSDOS
746#define CONFIGURE_SHELL_MOUNT_RFS
747#define CONFIGURE_SHELL_DEBUGRFS
748
749#include <rtems/shellconfig.h>
750#endif
751
752#else
753/*
754 * RTEMS Startup Task
755 */
756rtems_task
757Init (rtems_task_argument ignored)
758{
759  puts( "\n\n*** FILE I/O SAMPLE AND TEST ***" );
760  puts( "\n\n*** NOT ENOUGH MEMORY TO BUILD AND RUN ***" );
761}
762#endif
Note: See TracBrowser for help on using the repository browser.