source: rtems/cpukit/libmisc/shell/shell.c @ b2b143f4

4.104.114.84.95
Last change on this file since b2b143f4 was b2b143f4, checked in by Joel Sherrill <joel.sherrill@…>, on 03/05/04 at 17:58:51

2004-03-05 Joel Sherrill <joel@…>

  • libblock/src/bdbuf.c, libblock/src/ramdisk.c, libcsupport/src/newlibc.c, libcsupport/src/sync.c, libmisc/cpuuse/cpuuse.c, libmisc/monitor/mon-symbols.c, libmisc/shell/cmds.c, libmisc/shell/shell.c, libnetworking/kern/kern_sysctl.c, libnetworking/lib/ftpfs.c, libnetworking/lib/tftpDriver.c, libnetworking/libc/gethostbydns.c, libnetworking/libc/gethostbyht.c, libnetworking/libc/gethostnamadr.c, libnetworking/libc/getnetbyht.c, libnetworking/libc/getnetnamadr.c, libnetworking/libc/inet_addr.c, libnetworking/libc/linkaddr.c, libnetworking/libc/map_v4v6.c, libnetworking/libc/ns_print.c, libnetworking/libc/ns_ttl.c, libnetworking/libc/nsap_addr.c, libnetworking/libc/rcmd.c, libnetworking/libc/res_debug.c, libnetworking/libc/res_mkupdate.c, libnetworking/libc/res_query.c, libnetworking/libc/res_send.c, libnetworking/libc/res_update.c, libnetworking/net/radix.c, libnetworking/rtems/mkrootfs.c, librpc/src/rpc/clnt_perror.c, librpc/src/rpc/rtems_rpc.c, librpc/src/rpc/svc.c, sapi/include/confdefs.h, score/macros/rtems/score/chain.inl, score/src/objectidtoname.c:
  • Property mode set to 100644
File size: 18.8 KB
Line 
1/*
2 *
3 *  Instantatiate a new terminal shell.
4 *
5 *  Author:
6 *
7 *   WORK: fernando.ruiz@ctv.es
8 *   HOME: correo@fernando-ruiz.com
9 *
10 *   Thanks at:
11 *    Chris John
12 *
13 *  $Id$
14 */
15#ifdef HAVE_CONFIG_H
16#include "config.h"
17#endif
18
19/* Since we compile with strict ANSI we need to undef it to get
20 * prototypes for extensions
21 */
22#undef __STRICT_ANSI__
23
24#include <stdio.h>
25#include <time.h>
26
27#include <rtems.h>
28#include <rtems/error.h>
29#include <rtems/libio.h>
30#include <rtems/libio_.h>
31#include <rtems/system.h>
32#include <rtems/shell.h>
33
34#include <termios.h>
35#include <string.h>
36#include <stdlib.h>
37#include <ctype.h>
38#include <sys/stat.h>
39#include <unistd.h>
40#include <errno.h>
41#include <pwd.h>
42
43/* ----------------------------------------------- *
44 * This is a stupidity but is cute.
45 * ----------------------------------------------- */
46rtems_unsigned32 new_rtems_name(char * rtems_name) {
47        static char b[5];
48        sprintf(b,"%-4.4s",rtems_name);
49        return rtems_build_name(b[0],b[1],b[2],b[3]);
50}
51/* **************************************************************
52 * common linked list of shell commands.
53 * Because the help report is very long
54 * I have a topic for each command.
55 * Help list the topics
56 * help [topic] list the commands for the topic
57 * help [command] help for the command
58 * Can you see help rtems monitor report?
59 * ************************************************************** */
60
61struct shell_topic_tt;
62typedef struct shell_topic_tt shell_topic_t;
63
64struct shell_topic_tt {
65        char * topic;
66        shell_topic_t * next;
67};
68
69
70static shell_cmd_t   * shell_first_cmd;
71static shell_topic_t * shell_first_topic;
72/* ----------------------------------------------- *
73 * Using Chain I can reuse the rtems code.
74 * I am more comfortable with this, sorry.
75 * ----------------------------------------------- */
76shell_topic_t * shell_lookup_topic(char * topic) {
77  shell_topic_t * shell_topic;
78  shell_topic=shell_first_topic;
79  while (shell_topic) {
80   if (!strcmp(shell_topic->topic,topic)) return shell_topic;
81   shell_topic=shell_topic->next;
82  };
83  return (shell_topic_t *) NULL;
84}
85/* ----------------------------------------------- */
86shell_topic_t * shell_add_topic(char * topic) {
87 shell_topic_t * current,*aux;
88 if (!shell_first_topic) {
89  aux=malloc(sizeof(shell_topic_t));   
90  aux->topic=topic;
91  aux->next=(shell_topic_t*)NULL;
92  return shell_first_topic=aux;
93 } else {
94  current=shell_first_topic;
95  if (!strcmp(topic,current->topic)) return current;
96  while (current->next) {
97   if (!strcmp(topic,current->next->topic)) return current->next;
98   current=current->next;
99  };
100  aux=malloc(sizeof(shell_topic_t));   
101  aux->topic=topic;
102  aux->next=(shell_topic_t*)NULL;
103  current->next=aux;
104  return aux;
105 };
106}
107/* ----------------------------------------------- */
108shell_cmd_t * shell_lookup_cmd(char * cmd) {
109  shell_cmd_t * shell_cmd;
110  shell_cmd=shell_first_cmd;
111  while (shell_cmd) {
112   if (!strcmp(shell_cmd->name,cmd)) return shell_cmd;
113   shell_cmd=shell_cmd->next;
114  };
115  return (shell_cmd_t *) NULL;
116}
117/* ----------------------------------------------- */
118shell_cmd_t * shell_add_cmd(char * cmd,
119                      char * topic,
120                      char * usage,
121                      shell_command_t command) {
122  int shell_help(int argc,char * argv[]);
123  shell_cmd_t * shell_cmd,*shell_pvt;
124  if (!shell_first_cmd) {
125   shell_first_cmd=(shell_cmd_t *) malloc(sizeof(shell_cmd_t));
126   shell_first_cmd->name   ="help";
127   shell_first_cmd->topic  ="help";
128   shell_first_cmd->usage  ="help [topic] # list of usage of commands";
129   shell_first_cmd->command=shell_help;
130   shell_first_cmd->alias  =(shell_cmd_t *) NULL;
131   shell_first_cmd->next   =(shell_cmd_t *) NULL;
132   shell_add_topic(shell_first_cmd->topic);
133   register_cmds();
134  };
135  if (!cmd)     return (shell_cmd_t *) NULL;
136  if (!command) return (shell_cmd_t *) NULL;
137  shell_cmd=(shell_cmd_t *) malloc(sizeof(shell_cmd_t));
138  shell_cmd->name   =cmd;
139  shell_cmd->topic  =topic;
140  shell_cmd->usage  =usage;
141  shell_cmd->command=command;
142  shell_cmd->alias  =(shell_cmd_t *) NULL;
143  shell_cmd->next   =(shell_cmd_t *) NULL;
144  shell_add_topic(shell_cmd->topic);
145  shell_pvt=shell_first_cmd;
146  while (shell_pvt->next) shell_pvt=shell_pvt->next;
147  return shell_pvt->next=shell_cmd;
148}
149/* ----------------------------------------------- *
150 * you can make an alias for every command.
151 * ----------------------------------------------- */
152shell_cmd_t * shell_alias_cmd(char * cmd, char * alias) {
153  shell_cmd_t * shell_cmd,* shell_aux;
154  shell_aux=(shell_cmd_t *) NULL;
155  if (alias) {
156   if ((shell_aux=shell_lookup_cmd(alias))!=NULL) {
157    return NULL;
158   };
159   if ((shell_cmd=shell_lookup_cmd(cmd))!=NULL) {
160    shell_aux=shell_add_cmd(alias,shell_cmd->topic,
161                            shell_cmd->usage,shell_cmd->command);
162    if (shell_aux) shell_aux->alias=shell_cmd;
163   };
164  };
165  return shell_aux;
166}
167/* ----------------------------------------------- *
168 * Poor but enough..
169 * TODO: Redirection capture. "" evaluate, ... C&S welcome.
170 * ----------------------------------------------- */
171int shell_make_args(char * cmd,
172                 int  * pargc,
173                 char * argv[]) {
174  int argc=0;
175  while ((cmd=strtok(cmd," \t\r\n"))!=NULL) {
176    argv[argc++]=cmd;
177    cmd=(char*)NULL;
178   };
179  argv[argc]=(char*)NULL;
180  return *pargc=argc;
181}
182/* ----------------------------------------------- *
183 * show the help for one command.
184 * ----------------------------------------------- */
185int shell_help_cmd(shell_cmd_t * shell_cmd) {
186  char * pc;
187  int    col,line;
188  printf("%-10.10s -",shell_cmd->name);
189  col=12;
190  line=1;
191  if (shell_cmd->alias) {
192   printf("is an <alias> for command '%s'",shell_cmd->alias->name);
193  } else
194  if (shell_cmd->usage) {
195   pc=shell_cmd->usage;
196   while (*pc) {
197    switch(*pc) {
198     case '\r':break;
199     case '\n':putchar('\n');
200               col=0;
201               break;
202     default  :putchar(*pc);
203               col++;
204               break;
205    };
206    pc++;           
207    if(col>78) { /* What daring... 78?*/
208     if (*pc) {
209      putchar('\n');
210      col=0;
211     };
212    };
213    if (!col && *pc) {
214      printf("            ");
215      col=12;line++;
216    }; 
217   };
218  };
219  puts("");
220  return line;
221}
222/* ----------------------------------------------- *
223 * show the help. The first command implemented.
224 * Can you see the header of routine? Known?
225 * The same with all the commands....
226 * ----------------------------------------------- */
227int shell_help(int argc,char * argv[]) {
228  int col,line,arg;     
229  shell_topic_t *topic;
230  shell_cmd_t * shell_cmd=shell_first_cmd;
231  if (argc<2) {
232   printf("help: ('r' repeat last cmd - 'e' edit last cmd)\n"     
233          "  TOPIC? The topics are\n");   
234   topic=shell_first_topic;
235   col=0;
236   while (topic) {
237    if (!col){
238     col=printf("   %s",topic->topic);
239    } else {
240     if ((col+strlen(topic->topic)+2)>78){
241      printf("\n");
242      col=printf("   %s",topic->topic);
243     } else {
244      col+=printf(", %s",topic->topic);
245     };
246    };
247    topic=topic->next;
248   };
249   printf("\n");
250   return 1;
251  };
252  line=0;
253  for (arg=1;arg<argc;arg++) {
254   if (line>16) {
255    printf("Press any key to continue...");getchar();
256    printf("\n");
257    line=0;
258   };
259   topic=shell_lookup_topic(argv[arg]);
260   if (!topic){
261    if ((shell_cmd=shell_lookup_cmd(argv[arg]))==NULL) {
262     printf("help: topic or cmd '%s' not found. Try <help> alone for a list\n",argv[arg]);
263     line++;
264    } else {
265     line+=shell_help_cmd(shell_cmd);
266    }
267    continue;
268   };
269   printf("help: list for the topic '%s'\n",argv[arg]);
270   line++;
271   while (shell_cmd) {
272    if (!strcmp(topic->topic,shell_cmd->topic))
273     line+=shell_help_cmd(shell_cmd);
274    if (line>16) {
275     printf("Press any key to continue...");getchar();
276     printf("\n");
277     line=0;
278    };
279    shell_cmd=shell_cmd->next;
280   };
281  };
282  puts("");
283  return 0;
284}
285/* ----------------------------------------------- *
286 * TODO: Add improvements. History, edit vi or emacs, ...
287 * ----------------------------------------------- */
288int shell_scanline(char * line,int size,FILE * in,FILE * out) {
289  int c,col;
290  col=0;
291  if (*line) {
292   col=strlen(line);     
293   if (out) fprintf(out,"%s",line);
294  };
295  tcdrain(fileno(in ));
296  if (out) tcdrain(fileno(out));
297  for (;;) {
298   line[col]=0;   
299   c=fgetc(in);
300   switch (c) {
301    case 0x04:/*Control-d*/
302              if (col) break;
303    case EOF :return 0;
304    case '\n':break;
305    case '\f':if (out) fputc('\f',out);
306    case 0x03:/*Control-C*/
307              line[0]=0;
308    case '\r':if (out) fputc('\n',out);
309              return 1;
310    case  127:
311    case '\b':if (col) {
312               if (out) {
313                fputc('\b',out);
314                fputc(' ',out);
315                fputc('\b',out);
316               };
317               col--;
318              } else {
319               if (out) fputc('\a',out);
320              };
321              break;
322    default  :if (!iscntrl(c)) {
323                if (col<size-1) {
324                 line[col++]=c;
325                 if (out) fputc(c,out);
326                } else {
327                  if (out) fputc('\a',out);
328                };
329              } else {
330                if (out)
331                 if (c=='\a') fputc('\a',out);
332              };
333              break;
334   };
335  };
336}
337/* ----------------------------------------------- *
338 * - The shell TASK                               
339 * Poor but enough..
340 * TODO: Redirection. Tty Signals. ENVVARs. Shell language.
341 * ----------------------------------------------- */
342shell_env_t global_shell_env ,
343          * current_shell_env=&global_shell_env;
344
345extern char **environ;   
346
347void cat_file(FILE * out,char * name) {
348        FILE * fd;
349        int c;
350        if (out) {
351          fd=fopen(name,"r");
352          if (fd) {
353           while ((c=fgetc(fd))!=EOF) fputc(c,out);
354           fclose(fd);
355          };
356        }; 
357}
358
359void write_file(char * name,char * content) {
360        FILE * fd;
361        fd=fopen(name,"w");
362        if (fd) {
363         fwrite(content,1,strlen(content),fd);
364         fclose(fd);
365        }; 
366}
367
368void init_issue(void) {
369 static char issue_inited=FALSE;
370 struct stat buf;
371 if (issue_inited) return;
372 issue_inited=TRUE;
373 getpwnam("root"); /* dummy call to init /etc dir */
374 if (stat("/etc/issue",&buf))
375  write_file("/etc/issue",
376             "Welcome to @V\\n"
377             "Login into @S(@L)\\n");
378 if (stat("/etc/issue.net",&buf))
379  write_file("/etc/issue.net",
380             "Welcome to %v\n"
381             "running on %m\n");
382}
383
384int shell_login(FILE * in,FILE * out) {
385        FILE * fd;
386        int c;
387        time_t t;
388        int times;
389        char name[128];
390        char pass[128];
391        struct passwd * passwd;
392        init_issue();
393        setuid(0);
394        setgid(0);
395        rtems_current_user_env->euid=
396        rtems_current_user_env->egid=0;
397        if (out) {
398         if((current_shell_env->devname[5]!='p')||
399            (current_shell_env->devname[6]!='t')||
400            (current_shell_env->devname[7]!='y')) {
401          fd=fopen("/etc/issue","r");
402          if (fd) {
403           while ((c=fgetc(fd))!=EOF) {
404            if (c=='@')  {
405             switch(c=fgetc(fd)) {
406              case 'L':fprintf(out,"%s",current_shell_env->devname);
407                      break;
408              case 'B':fprintf(out,"0");
409                      break;
410              case 'T':
411              case 'D':time(&t);
412                      fprintf(out,"%s",ctime(&t));
413                      break;
414              case 'S':fprintf(out,"RTEMS");
415                      break;
416              case 'V':fprintf(out,"%s\n%s",_RTEMS_version,_Copyright_Notice);
417                      break;
418              case '@':fprintf(out,"@");
419                      break;
420              default :fprintf(out,"@%c",c);
421                      break;
422             };
423            } else
424            if (c=='\\')  {
425             switch(c=fgetc(fd)) {
426              case '\\':fprintf(out,"\\");
427                      break;
428              case 'b':fprintf(out,"\b"); break;
429              case 'f':fprintf(out,"\f"); break;
430              case 'n':fprintf(out,"\n"); break;
431              case 'r':fprintf(out,"\r"); break;
432              case 's':fprintf(out," "); break;
433              case 't':fprintf(out,"\t"); break;
434              case '@':fprintf(out,"@"); break;
435             };
436            } else {
437             fputc(c,out);                             
438            };
439           };
440           fclose(fd);
441          }
442         } else { 
443          fd=fopen("/etc/issue.net","r");
444          if (fd) {
445           while ((c=fgetc(fd))!=EOF) {
446            if (c=='%')  {
447             switch(c=fgetc(fd)) {
448              case 't':fprintf(out,"%s",current_shell_env->devname);
449                      break;
450              case 'h':fprintf(out,"0");
451                      break;
452              case 'D':fprintf(out," ");
453                      break;
454              case 'd':time(&t);
455                      fprintf(out,"%s",ctime(&t));
456                      break;
457              case 's':fprintf(out,"RTEMS");
458                      break;
459              case 'm':fprintf(out,"(" CPU_NAME "/" CPU_MODEL_NAME ")");
460                      break;
461              case 'r':fprintf(out,_RTEMS_version);
462                      break;
463              case 'v':fprintf(out,"%s\n%s",_RTEMS_version,_Copyright_Notice);
464                      break;
465              case '%':fprintf(out,"%%");
466                      break;
467              default :fprintf(out,"%%%c",c);
468                      break;
469             };
470            } else {
471             fputc(c,out);                             
472            };
473           };
474           fclose(fd);
475          }
476         };
477        };
478        times=0;
479        strcpy(name,"");
480        strcpy(pass,"");
481        for (;;) {
482                times++;
483                if (times>3) break;
484                if (out) fprintf(out,"\nlogin: ");
485                if (!shell_scanline(name,sizeof(name),in,out )) break;
486                if (out) fprintf(out,"Password: ");
487                if (!shell_scanline(pass,sizeof(pass),in,NULL)) break;
488                if (out) fprintf(out,"\n");
489                if ((passwd=getpwnam(name))) {
490                 if (strcmp(passwd->pw_passwd,"!")) { /* valid user */
491                  setuid(passwd->pw_uid);                       
492                  setgid(passwd->pw_gid);                       
493                  rtems_current_user_env->euid=
494                  rtems_current_user_env->egid=0;
495                  chown(current_shell_env->devname,passwd->pw_uid,0);
496                  rtems_current_user_env->euid=passwd->pw_uid;                 
497                  rtems_current_user_env->egid=passwd->pw_gid;                 
498                  if (!strcmp(passwd->pw_passwd,"*")) {
499                   /* /etc/shadow */
500                   return 0;
501                  } else {
502                   /* crypt() */
503                   return 0;
504                  };
505                 };
506                };
507                if (out) fprintf(out,"Login incorrect\n");
508                strcpy(name,"");
509                strcpy(pass,"");
510        };
511        return -1;
512}
513
514rtems_task shell_shell(rtems_task_argument task_argument) {
515
516  shell_env_t * shell_env =(shell_env_t*) task_argument;
517  shell_cmd_t * shell_cmd;
518
519  rtems_status_code sc;
520
521  struct termios term; 
522  char * devname;
523
524  char curdir[256];
525  char cmd[256];
526  char last_cmd[256]; /* to repeat 'r' */
527  int  argc;
528  char * argv[128];
529
530  sc=rtems_task_variable_add(RTEMS_SELF,(void*)&current_shell_env,free);
531  if (sc!=RTEMS_SUCCESSFUL) {
532   rtems_error(sc,"rtems_task_variable_add(current_shell_env):");       
533   rtems_task_delete(RTEMS_SELF);
534  };
535
536  current_shell_env=shell_env; 
537 
538  sc=rtems_libio_set_private_env();
539  if (sc!=RTEMS_SUCCESSFUL) {
540   rtems_error(sc,"rtems_libio_set_private_env():");     
541   rtems_task_delete(RTEMS_SELF);
542  };
543
544
545  devname=shell_env->devname;
546  setuid(0);
547  setgid(0);
548  rtems_current_user_env->euid=
549  rtems_current_user_env->egid=0;
550
551  stdin =fopen(devname,"r+");
552   
553  if (!stdin) {
554   fprintf(stderr,"shell:unable to open stdin.%s:%s\n",devname,strerror(errno));
555   rtems_task_delete(RTEMS_SELF);
556  };
557  setvbuf(stdin,NULL,_IONBF,0); /* Not buffered*/
558  /* make a raw terminal,Linux MANuals */
559  if (tcgetattr (fileno(stdin), &term)>=0) {
560   term.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
561   term.c_oflag &= ~OPOST;
562   term.c_oflag |= (OPOST|ONLCR); /* But with cr+nl on output */
563   term.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
564   term.c_cflag  = CLOCAL | CREAD |(shell_env->tcflag);
565   term.c_cc[VMIN]  = 1;
566   term.c_cc[VTIME] = 0;
567   if (tcsetattr (fileno(stdin), TCSADRAIN, &term) < 0) {
568     fprintf(stderr,"shell:cannot set terminal attributes(%s)\n",devname);
569   };
570   stdout=fopen(devname,"r+");
571   if (!stdout) {
572    fprintf(stderr,"shell:unable to open stdout.%s:%s\n",devname,strerror(errno));
573   };
574   setvbuf(stdout,NULL,_IONBF,0); /* Not buffered*/
575   stderr=fopen(devname,"r+");
576   if (!stderr) {
577    printf("shell:unable to open stderr.%s:%s\n",devname,strerror(errno));
578   };
579   /* when the future user environment runs ok
580    * a freopen() reopens the terminals. Now this don't work
581    * (sorry but you can't use because FILENO_STDIN!=0. Better fileno(stdin))
582    */
583  };
584  shell_add_cmd(NULL,NULL,NULL,NULL); /* init the chain list*/
585  do {
586   /* Set again root user and root filesystem, side effect of set_priv..*/       
587  sc=rtems_libio_set_private_env();
588  if (sc!=RTEMS_SUCCESSFUL) {
589   rtems_error(sc,"rtems_libio_set_private_env():");     
590   rtems_task_delete(RTEMS_SELF);
591  };
592  if (!shell_login(stdin,stdout))  {
593   cat_file(stdout,"/etc/motd");
594   strcpy(last_cmd,"");
595   strcpy(cmd,"");
596   printf("\n"
597          "RTEMS SHELL (Ver.1.0-FRC):%s. "__DATE__". 'help' to list commands.\n",devname);
598   chdir("/"); /* XXX: chdir to getpwent homedir */
599   shell_env->exit_shell=FALSE;
600   for (;;) {
601    /* Prompt section */         
602    /* XXX: show_prompt user adjustable */
603    getcwd(curdir,sizeof(curdir));
604    printf("%s [%s] %c ",shell_env->taskname,curdir,geteuid()?'$':'#');
605    /* getcmd section */         
606    if (!shell_scanline(cmd,sizeof(cmd),stdin,stdout)) break; /*EOF*/
607    /* evaluate cmd section */   
608    if (!strcmp(cmd,"e")) {  /* edit last command */
609     strcpy(cmd,last_cmd);
610     continue;
611    } else
612    if (!strcmp(cmd,"r")) {  /* repeat last command */
613     strcpy(cmd,last_cmd);
614    } else
615    if (strcmp(cmd,"")) { /* only for get a new prompt */
616     strcpy(last_cmd,cmd);
617    };
618    /* exec cmd section */       
619    /* TODO:
620     *  To avoid user crash catch the signals.
621     *  Open a new stdio files with posibility of redirection *
622     *  Run in a new shell task background. (unix &)
623     *  Resuming. A little bash.
624     */   
625    if (shell_make_args(cmd,&argc,argv)) {
626     if ((shell_cmd=shell_lookup_cmd(argv[0]))!=NULL) {
627      shell_env->errorlevel=shell_cmd->command(argc,argv);
628     } else {
629      printf("shell:%s command not found\n",argv[0]);
630      shell_env->errorlevel=-1;
631     };
632    };
633    /* end exec cmd section */   
634    if (shell_env->exit_shell)  break;
635    cmd[0]=0;
636   };
637   printf("\nGoodbye from RTEMS SHELL :-(\n");
638  };
639  } while (shell_env->forever);
640  fclose(stdin );
641  fclose(stdout);
642  fclose(stderr);
643  rtems_task_delete(RTEMS_SELF);
644}
645/* ----------------------------------------------- */
646rtems_status_code   shell_init (char * task_name,
647                                rtems_unsigned32    task_stacksize,
648                                rtems_task_priority task_priority,
649                                char * devname,
650                                tcflag_t tcflag,
651                                int forever) {
652 rtems_id task_id;
653 rtems_status_code sc;
654 shell_env_t * shell_env;
655 sc=rtems_task_create(new_rtems_name(task_name),
656                     task_priority,
657                     task_stacksize?task_stacksize:RTEMS_MINIMUM_STACK_SIZE,
658                     RTEMS_DEFAULT_MODES,
659                     RTEMS_LOCAL | RTEMS_FLOATING_POINT,
660                     &task_id);
661 if (sc!=RTEMS_SUCCESSFUL) {
662  rtems_error(sc,"creating task %s in shell_init()",task_name); 
663  return sc;
664 };
665 shell_env=malloc(sizeof(shell_env_t));
666 if (!shell_env) {
667  rtems_task_delete(task_id);
668  sc=RTEMS_NO_MEMORY;   
669  rtems_error(sc,"allocating shell_env %s in shell_init()",task_name);   
670  return sc;
671 };
672 if (global_shell_env.magic!=new_rtems_name("SENV")) {
673  global_shell_env.magic     =new_rtems_name("SENV");
674  global_shell_env.devname   ="/dev/console";
675  global_shell_env.taskname  ="GLOBAL";
676  global_shell_env.tcflag    =0;
677  global_shell_env.exit_shell=0;
678  global_shell_env.forever   =TRUE;
679 };
680 shell_env->magic     =global_shell_env.magic;
681 shell_env->devname   =devname;
682 shell_env->taskname  =task_name;
683 shell_env->tcflag    =tcflag;
684 shell_env->exit_shell=FALSE;
685 shell_env->forever   =forever;
686 return rtems_task_start(task_id,shell_shell,(rtems_task_argument) shell_env);
687}
Note: See TracBrowser for help on using the repository browser.