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

4.115
Last change on this file since a32020ad was e313551, checked in by Ralf Corsepius <ralf.corsepius@…>, on 02/22/11 at 10:58:44

Add HAVE_CONFIG_H.

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