From 6dd411aa14c471b5657e3b53098ee13d772bc626 Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Fri, 9 Nov 2007 21:39:21 +0000 Subject: 2007-11-09 Joel Sherrill * libmisc/shell/shell.c, libmisc/shell/shell.h: Much cleanup but much of the focus was on the beginning stages of making the login checker pluggable just like the shell. --- cpukit/libmisc/shell/shell.c | 774 +++++++++++++++++++++++-------------------- cpukit/libmisc/shell/shell.h | 35 +- 2 files changed, 442 insertions(+), 367 deletions(-) (limited to 'cpukit/libmisc') diff --git a/cpukit/libmisc/shell/shell.c b/cpukit/libmisc/shell/shell.c index 5a67d5dd24..cd2dc7c899 100644 --- a/cpukit/libmisc/shell/shell.c +++ b/cpukit/libmisc/shell/shell.c @@ -39,9 +39,9 @@ * This is a stupidity but is cute. * ----------------------------------------------- */ uint32_t new_rtems_name(char * rtems_name) { - static char b[5]; - sprintf(b,"%-4.4s",rtems_name); - return rtems_build_name(b[0],b[1],b[2],b[3]); + static char b[5]; + sprintf(b,"%-4.4s",rtems_name); + return rtems_build_name(b[0],b[1],b[2],b[3]); } /* ************************************************************** * common linked list of shell commands. @@ -57,13 +57,16 @@ struct shell_topic_tt; typedef struct shell_topic_tt shell_topic_t; struct shell_topic_tt { - char * topic; - shell_topic_t * next; + char * topic; + shell_topic_t * next; }; static shell_cmd_t * shell_first_cmd; static shell_topic_t * shell_first_topic; + +shell_env_t *shell_init_env(shell_env_t *); + /* ----------------------------------------------- * * Using Chain I can reuse the rtems code. * I am more comfortable with this, sorry. @@ -111,8 +114,8 @@ shell_cmd_t * shell_lookup_cmd(char * cmd) { } /* ----------------------------------------------- */ shell_cmd_t * shell_add_cmd(char * cmd, - char * topic, - char * usage, + char * topic, + char * usage, shell_command_t command) { int shell_help(int argc,char * argv[]); shell_cmd_t * shell_cmd,*shell_pvt; @@ -153,7 +156,7 @@ shell_cmd_t * shell_alias_cmd(char * cmd, char * alias) { }; if ((shell_cmd=shell_lookup_cmd(cmd))!=NULL) { shell_aux=shell_add_cmd(alias,shell_cmd->topic, - shell_cmd->usage,shell_cmd->command); + shell_cmd->usage,shell_cmd->command); if (shell_aux) shell_aux->alias=shell_cmd; }; }; @@ -164,8 +167,8 @@ shell_cmd_t * shell_alias_cmd(char * cmd, char * alias) { * TODO: Redirection capture. "" evaluate, ... C&S welcome. * ----------------------------------------------- */ int shell_make_args(char * cmd, - int * pargc, - char * argv[]) { + int * pargc, + char * argv[]) { int argc=0; while ((cmd=strtok(cmd," \t\r\n"))!=NULL) { argv[argc++]=cmd; @@ -180,11 +183,11 @@ int shell_make_args(char * cmd, int shell_help_cmd(shell_cmd_t * shell_cmd) { char * pc; int col,line; - fprintf(stdout,"%-10.10s -",shell_cmd->name); + printf("%-10.10s -",shell_cmd->name); col=12; line=1; if (shell_cmd->alias) { - fprintf(stdout,"is an for command '%s'",shell_cmd->alias->name); + printf("is an for command '%s'",shell_cmd->alias->name); } else if (shell_cmd->usage) { pc=shell_cmd->usage; @@ -206,7 +209,7 @@ int shell_help_cmd(shell_cmd_t * shell_cmd) { }; }; if (!col && *pc) { - fprintf(stdout," "); + printf(" "); col=12;line++; }; }; @@ -224,51 +227,53 @@ int shell_help(int argc,char * argv[]) { shell_topic_t *topic; shell_cmd_t * shell_cmd=shell_first_cmd; if (argc<2) { - fprintf(stdout,"help: ('r' repeat last cmd - 'e' edit last cmd)\n" + printf("help: ('r' repeat last cmd - 'e' edit last cmd)\n" " TOPIC? The topics are\n"); topic=shell_first_topic; col=0; while (topic) { if (!col){ - col=fprintf(stdout," %s",topic->topic); + col=printf(" %s",topic->topic); } else { if ((col+strlen(topic->topic)+2)>78){ - fprintf(stdout,"\n"); - col=fprintf(stdout," %s",topic->topic); + printf("\n"); + col=printf(" %s",topic->topic); } else { - col+=fprintf(stdout,", %s",topic->topic); + col+=printf(", %s",topic->topic); }; }; topic=topic->next; }; - fprintf(stdout,"\n"); + printf("\n"); return 1; }; line=0; for (arg=1;arg16) { - fprintf(stdout,"Press any key to continue...");getchar(); - fprintf(stdout,"\n"); + printf("Press any key to continue...");getchar(); + printf("\n"); line=0; }; topic=shell_lookup_topic(argv[arg]); if (!topic){ if ((shell_cmd=shell_lookup_cmd(argv[arg]))==NULL) { - fprintf(stdout,"help: topic or cmd '%s' not found. Try alone for a list\n",argv[arg]); + printf("help: topic or cmd '%s' not found. Try alone for a list\n", + argv[arg]); line++; } else { line+=shell_help_cmd(shell_cmd); } continue; }; - fprintf(stdout,"help: list for the topic '%s'\n",argv[arg]); + printf("help: list for the topic '%s'\n",argv[arg]); line++; while (shell_cmd) { if (!strcmp(topic->topic,shell_cmd->topic)) line+=shell_help_cmd(shell_cmd); if (line>16) { - fprintf(stdout,"Press any key to continue...");getchar(); - fprintf(stdout,"\n"); + printf("Press any key to continue..."); + getchar(); + printf("\n"); line=0; }; shell_cmd=shell_cmd->next; @@ -287,45 +292,45 @@ int shell_scanline(char * line,int size,FILE * in,FILE * out) { col=strlen(line); if (out) fprintf(out,"%s",line); }; - tcdrain(fileno(in )); + tcdrain(fileno(in)); if (out) tcdrain(fileno(out)); for (;;) { line[col]=0; - c=fgetc(in); + c = fgetc(in); switch (c) { case 0x04:/*Control-d*/ - if (col) break; + if (col) break; case EOF :return 0; case '\n':break; case '\f':if (out) fputc('\f',out); case 0x03:/*Control-C*/ - line[0]=0; + line[0]=0; case '\r':if (out) fputc('\n',out); - return 1; + return 1; case 127: case '\b':if (col) { - if (out) { - fputc('\b',out); - fputc(' ',out); - fputc('\b',out); - }; - col--; - } else { - if (out) fputc('\a',out); - }; - break; + if (out) { + fputc('\b',out); + fputc(' ',out); + fputc('\b',out); + }; + col--; + } else { + if (out) fputc('\a',out); + }; + break; default :if (!iscntrl(c)) { - if (coleuid= - rtems_current_user_env->egid=0; - if (out) { - if((current_shell_env->devname[5]!='p')|| - (current_shell_env->devname[6]!='t')|| - (current_shell_env->devname[7]!='y')) { - fd=fopen("/etc/issue","r"); - if (fd) { - while ((c=fgetc(fd))!=EOF) { - if (c=='@') { - switch(c=fgetc(fd)) { - case 'L':fprintf(out,"%s",current_shell_env->devname); - break; - case 'B':fprintf(out,"0"); - break; + FILE *fd; + int c; + time_t t; + int times; + char name[128]; + char pass[128]; + struct passwd *passwd; + + init_issue(); + setuid(0); + setgid(0); + rtems_current_user_env->euid = + rtems_current_user_env->egid =0; + + if (out) { + if ((current_shell_env->devname[5]!='p')|| + (current_shell_env->devname[6]!='t')|| + (current_shell_env->devname[7]!='y')) { + fd = fopen("/etc/issue","r"); + if (fd) { + while ((c=fgetc(fd))!=EOF) { + if (c=='@') { + switch(c=fgetc(fd)) { + case 'L': + fprintf(out,"%s",current_shell_env->devname); + break; + case 'B': + fprintf(out,"0"); + break; case 'T': - case 'D':time(&t); - fprintf(out,"%s",ctime(&t)); - break; - case 'S':fprintf(out,"RTEMS"); - break; - case 'V':fprintf(out,"%s\n%s",_RTEMS_version,_Copyright_Notice); - break; - case '@':fprintf(out,"@"); - break; - default :fprintf(out,"@%c",c); - break; - }; - } else - if (c=='\\') { - switch(c=fgetc(fd)) { - case '\\':fprintf(out,"\\"); - break; - case 'b':fprintf(out,"\b"); break; - case 'f':fprintf(out,"\f"); break; - case 'n':fprintf(out,"\n"); break; - case 'r':fprintf(out,"\r"); break; - case 's':fprintf(out," "); break; - case 't':fprintf(out,"\t"); break; - case '@':fprintf(out,"@"); break; - }; - } else { - fputc(c,out); - }; - }; - fclose(fd); - } - } else { - fd=fopen("/etc/issue.net","r"); - if (fd) { - while ((c=fgetc(fd))!=EOF) { - if (c=='%') { - switch(c=fgetc(fd)) { - case 't':fprintf(out,"%s",current_shell_env->devname); - break; - case 'h':fprintf(out,"0"); - break; - case 'D':fprintf(out," "); - break; - case 'd':time(&t); - fprintf(out,"%s",ctime(&t)); - break; - case 's':fprintf(out,"RTEMS"); - break; - case 'm':fprintf(out,"(" CPU_NAME "/" CPU_MODEL_NAME ")"); - break; - case 'r':fprintf(out,_RTEMS_version); - break; - case 'v':fprintf(out,"%s\n%s",_RTEMS_version,_Copyright_Notice); - break; - case '%':fprintf(out,"%%"); - break; - default :fprintf(out,"%%%c",c); - break; - }; - } else { - fputc(c,out); - }; - }; - fclose(fd); - } - }; - }; - times=0; - strcpy(name,""); - strcpy(pass,""); - for (;;) { - times++; - if (times>3) break; - if (out) fprintf(out,"\nlogin: "); - if (!shell_scanline(name,sizeof(name),in,out )) break; - if (out) fprintf(out,"Password: "); - if (!shell_scanline(pass,sizeof(pass),in,NULL)) break; - if (out) fprintf(out,"\n"); - if ((passwd=getpwnam(name))) { - if (strcmp(passwd->pw_passwd,"!")) { /* valid user */ - setuid(passwd->pw_uid); - setgid(passwd->pw_gid); - rtems_current_user_env->euid= - rtems_current_user_env->egid=0; - chown(current_shell_env->devname,passwd->pw_uid,0); - rtems_current_user_env->euid=passwd->pw_uid; - rtems_current_user_env->egid=passwd->pw_gid; - if (!strcmp(passwd->pw_passwd,"*")) { - /* /etc/shadow */ - return 0; - } else { - /* crypt() */ - return 0; - }; - }; - }; - if (out) fprintf(out,"Login incorrect\n"); - strcpy(name,""); - strcpy(pass,""); - }; - return -1; + case 'D': + time(&t); + fprintf(out,"%s",ctime(&t)); + break; + case 'S': + fprintf(out,"RTEMS"); + break; + case 'V': + fprintf(out,"%s\n%s",_RTEMS_version,_Copyright_Notice); + break; + case '@': + fprintf(out,"@"); + break; + default : + fprintf(out,"@%c",c); + break; + } + } else if (c=='\\') { + switch(c=fgetc(fd)) { + case '\\': fprintf(out,"\\"); break; + case 'b': fprintf(out,"\b"); break; + case 'f': fprintf(out,"\f"); break; + case 'n': fprintf(out,"\n"); break; + case 'r': fprintf(out,"\r"); break; + case 's': fprintf(out," "); break; + case 't': fprintf(out,"\t"); break; + case '@': fprintf(out,"@"); break; + } + } else { + fputc(c,out); + } + } + fclose(fd); + } + } else { + fd = fopen("/etc/issue.net","r"); + if (fd) { + while ((c=fgetc(fd))!=EOF) { + if (c=='%') { + switch(c=fgetc(fd)) { + case 't': + fprintf(out,"%s",current_shell_env->devname); + break; + case 'h': + fprintf(out,"0"); + break; + case 'D': + fprintf(out," "); + break; + case 'd': + time(&t); + fprintf(out,"%s",ctime(&t)); + break; + case 's': + fprintf(out,"RTEMS"); + break; + case 'm': + fprintf(out,"(" CPU_NAME "/" CPU_MODEL_NAME ")"); + break; + case 'r': + fprintf(out,_RTEMS_version); + break; + case 'v': + fprintf(out,"%s\n%s",_RTEMS_version,_Copyright_Notice); + break; + case '%':fprintf(out,"%%"); + break; + default: + fprintf(out,"%%%c",c); + break; + } + } else { + fputc(c,out); + } + } + fclose(fd); + } + } + } + + times=0; + strcpy(name,""); + strcpy(pass,""); + for (;;) { + times++; + if (times>3) break; + if (out) fprintf(out,"\nlogin: "); + if (!shell_scanline(name,sizeof(name),in,out )) break; + if (out) fprintf(out,"Password: "); + if (!shell_scanline(pass,sizeof(pass),in,NULL)) break; + if (out) fprintf(out,"\n"); + if ((passwd=getpwnam(name))) { + if (strcmp(passwd->pw_passwd,"!")) { /* valid user */ + setuid(passwd->pw_uid); + setgid(passwd->pw_gid); + rtems_current_user_env->euid = + rtems_current_user_env->egid =0; + chown(current_shell_env->devname,passwd->pw_uid,0); + rtems_current_user_env->euid = passwd->pw_uid; + rtems_current_user_env->egid = passwd->pw_gid; + if (!strcmp(passwd->pw_passwd,"*")) { + /* /etc/shadow */ + return 0; + } else { + /* crypt() */ + return 0; + } + } + } + if (out) + fprintf(out,"Login incorrect\n"); + strcpy(name,""); + strcpy(pass,""); + } + return -1; } -rtems_task shell_shell(rtems_task_argument task_argument) { +#if 0 +void shell_print_env( + shell_env_t * shell_env +) +{ + if ( !shell_env ) { + printk( "shell_env is NULL\n" ); + return; + } + printk( "shell_env=%p\n" + "shell_env->magic=0x%08x\t" + "shell_env->devname=%s\n" + "shell_env->taskname=%s\t" + "shell_env->tcflag=%d\n" + "shell_env->exit_shell=%d\t" + "shell_env->forever=%d\n", + shell_env->magic, + shell_env->devname, + ((shell_env->taskname) ? shell_env->taskname : "NOT SET"), + shell_env->tcflag, + shell_env->exit_shell, + shell_env->forever + ); +} +#endif +rtems_task shell_shell(rtems_task_argument task_argument) +{ shell_env_t * shell_env =(shell_env_t*) task_argument; - shell_cmd_t * shell_cmd; - - rtems_status_code sc; - - struct termios term; - char * devname; - char curdir[256]; - char cmd[256]; - char last_cmd[256]; /* to repeat 'r' */ - int argc; - char * argv[128]; + shell_shell_loop( shell_env ); + rtems_task_delete( RTEMS_SELF ); +} - sc=rtems_task_variable_add(RTEMS_SELF,(void*)¤t_shell_env,free); - if (sc!=RTEMS_SUCCESSFUL) { - rtems_error(sc,"rtems_task_variable_add(current_shell_env):"); - rtems_task_delete(RTEMS_SELF); - }; - current_shell_env=shell_env; +rtems_boolean shell_shell_loop( + shell_env_t *shell_env_arg +) +{ + shell_env_t *shell_env; + shell_cmd_t *shell_cmd; + rtems_status_code sc; + struct termios term; + char curdir[256]; + char cmd[256]; + char last_cmd[256]; /* to repeat 'r' */ + int argc; + char *argv[128]; - sc=rtems_libio_set_private_env(); - if (sc!=RTEMS_SUCCESSFUL) { - rtems_error(sc,"rtems_libio_set_private_env():"); - rtems_task_delete(RTEMS_SELF); + sc = rtems_task_variable_add(RTEMS_SELF,(void*)¤t_shell_env,free); + if (sc != RTEMS_SUCCESSFUL) { + rtems_error(sc,"rtems_task_variable_add(current_shell_env):"); + return FALSE; }; - - devname=shell_env->devname; + shell_env = + current_shell_env = shell_init_env( shell_env_arg ); + setuid(0); setgid(0); - rtems_current_user_env->euid= - rtems_current_user_env->egid=0; - - /* - * newlib delays the creation of default stdio 'til the - * first I/O operation, therefore we must perform dummy - * operations before we redirect stdio - */ - ftell(stdin); - ftell(stdout); - ftell(stderr); - - stdin =fopen(devname,"r+"); - - if (!stdin) { - fprintf(stderr,"shell:unable to open stdin.%s:%s\n",devname,strerror(errno)); - rtems_task_delete(RTEMS_SELF); - }; + rtems_current_user_env->euid = + rtems_current_user_env->egid = 0; + setvbuf(stdin,NULL,_IONBF,0); /* Not buffered*/ - /* make a raw terminal,Linux MANuals */ + /* make a raw terminal,Linux Manuals */ if (tcgetattr (fileno(stdin), &term)>=0) { term.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON); term.c_oflag &= ~OPOST; @@ -569,123 +603,157 @@ rtems_task shell_shell(rtems_task_argument task_argument) { term.c_cc[VMIN] = 1; term.c_cc[VTIME] = 0; if (tcsetattr (fileno(stdin), TCSADRAIN, &term) < 0) { - fprintf(stderr,"shell:cannot set terminal attributes(%s)\n",devname); - }; - stdout=fopen(devname,"r+"); - if (!stdout) { - fprintf(stderr,"shell:unable to open stdout.%s:%s\n",devname,strerror(errno)); + fprintf(stderr, + "shell:cannot set terminal attributes(%s)\n",shell_env->devname); }; setvbuf(stdout,NULL,_IONBF,0); /* Not buffered*/ - stderr=fopen(devname,"r+"); - if (!stderr) { - fprintf(stdout,"shell:unable to open stderr.%s:%s\n",devname,strerror(errno)); - }; - /* when the future user environment runs ok - * a freopen() reopens the terminals. Now this don't work - * (sorry but you can't use because FILENO_STDIN!=0. Better fileno(stdin)) - */ - }; + } + shell_add_cmd(NULL,NULL,NULL,NULL); /* init the chain list*/ do { - /* Set again root user and root filesystem, side effect of set_priv..*/ - sc=rtems_libio_set_private_env(); - if (sc!=RTEMS_SUCCESSFUL) { - rtems_error(sc,"rtems_libio_set_private_env():"); - rtems_task_delete(RTEMS_SELF); - }; - if (!shell_login(stdin,stdout)) { - cat_file(stdout,"/etc/motd"); - strcpy(last_cmd,""); - strcpy(cmd,""); - fprintf(stdout,"\n" - "RTEMS SHELL (Ver.1.0-FRC):%s. "__DATE__". 'help' to list commands.\n",devname); - chdir("/"); /* XXX: chdir to getpwent homedir */ - shell_env->exit_shell=FALSE; - for (;;) { - /* Prompt section */ - /* XXX: show_prompt user adjustable */ - getcwd(curdir,sizeof(curdir)); - fprintf(stdout,"%s [%s] %c ",shell_env->taskname,curdir,geteuid()?'$':'#'); - /* getcmd section */ - if (!shell_scanline(cmd,sizeof(cmd),stdin,stdout)) break; /*EOF*/ - /* evaluate cmd section */ - if (!strcmp(cmd,"e")) { /* edit last command */ - strcpy(cmd,last_cmd); - continue; - } else - if (!strcmp(cmd,"r")) { /* repeat last command */ - strcpy(cmd,last_cmd); - } else - if (strcmp(cmd,"")) { /* only for get a new prompt */ - strcpy(last_cmd,cmd); - }; - /* exec cmd section */ - /* TODO: - * To avoid user crash catch the signals. - * Open a new stdio files with posibility of redirection * - * Run in a new shell task background. (unix &) - * Resuming. A little bash. - */ - if (shell_make_args(cmd,&argc,argv)) { - if ((shell_cmd=shell_lookup_cmd(argv[0]))!=NULL) { - shell_env->errorlevel=shell_cmd->command(argc,argv); - } else { - fprintf(stdout,"shell:%s command not found\n",argv[0]); - shell_env->errorlevel=-1; - }; - }; - /* end exec cmd section */ - if (shell_env->exit_shell) break; - cmd[0]=0; - }; - fprintf(stdout,"\nGoodbye from RTEMS SHELL :-(\n"); - }; + /* Set again root user and root filesystem, side effect of set_priv..*/ + sc = rtems_libio_set_private_env(); + if (sc != RTEMS_SUCCESSFUL) { + rtems_error(sc,"rtems_libio_set_private_env():"); + return FALSE; + } + if (!shell_login(stdin,stdout)) { + cat_file(stdout,"/etc/motd"); + strcpy(last_cmd,""); + strcpy(cmd,""); + printf("\n" + "RTEMS SHELL (Ver.1.0-FRC):%s. "__DATE__". 'help' to list commands.\n", + shell_env->devname); + chdir("/"); /* XXX: chdir to getpwent homedir */ + shell_env->exit_shell=FALSE; + for (;;) { + /* Prompt section */ + /* XXX: show_prompt user adjustable */ + getcwd(curdir,sizeof(curdir)); + printf( "%s%s[%s] %c ", + ((shell_env->taskname) ? shell_env->taskname : ""), + ((shell_env->taskname) ? " " : ""), + curdir, + geteuid()?'$':'#' + ); + /* getcmd section */ + if (!shell_scanline(cmd,sizeof(cmd),stdin,stdout)) { + break; /*EOF*/ + } + + /* evaluate cmd section */ + if (!strcmp(cmd,"e")) { /* edit last command */ + strcpy(cmd,last_cmd); + continue; + } else if (!strcmp(cmd,"r")) { /* repeat last command */ + strcpy(cmd,last_cmd); + } else if (!strcmp(cmd,"bye")) { /* exit to telnetd */ + printf("Shell exiting\n" ); + return TRUE; + } else if (!strcmp(cmd,"exit")) { /* exit application */ + printf("System shutting down at user request\n" ); + exit(0); + } else if (!strcmp(cmd,"")) { /* only for get a new prompt */ + strcpy(last_cmd,cmd); + } + + /* exec cmd section */ + /* TODO: + * To avoid user crash catch the signals. + * Open a new stdio files with posibility of redirection * + * Run in a new shell task background. (unix &) + * Resuming. A little bash. + */ + if (shell_make_args(cmd,&argc,argv)) { + if ((shell_cmd=shell_lookup_cmd(argv[0]))!=NULL) { + shell_env->errorlevel=shell_cmd->command(argc,argv); + } else { + printf("shell:%s command not found\n",argv[0]); + shell_env->errorlevel=-1; + } + } + /* end exec cmd section */ + + if (shell_env->exit_shell) + break; + strcpy(last_cmd, cmd); + cmd[0]=0; + } + printf("\nGoodbye from RTEMS SHELL :-(\n"); + fflush( stdout ); + fflush( stderr ); + } } while (shell_env->forever); - fclose(stdin ); - fclose(stdout); - fclose(stderr); - rtems_task_delete(RTEMS_SELF); + return TRUE; } + /* ----------------------------------------------- */ -rtems_status_code shell_init (char * task_name, - uint32_t task_stacksize, - rtems_task_priority task_priority, - char * devname, - tcflag_t tcflag, - int forever) { - rtems_id task_id; - rtems_status_code sc; - shell_env_t * shell_env; - sc=rtems_task_create(new_rtems_name(task_name), - task_priority, - task_stacksize?task_stacksize:RTEMS_MINIMUM_STACK_SIZE, - RTEMS_DEFAULT_MODES, - RTEMS_LOCAL | RTEMS_FLOATING_POINT, - &task_id); - if (sc!=RTEMS_SUCCESSFUL) { - rtems_error(sc,"creating task %s in shell_init()",task_name); - return sc; - }; - shell_env=malloc(sizeof(shell_env_t)); - if (!shell_env) { - rtems_task_delete(task_id); - sc=RTEMS_NO_MEMORY; - rtems_error(sc,"allocating shell_env %s in shell_init()",task_name); - return sc; - }; - if (global_shell_env.magic!=new_rtems_name("SENV")) { - global_shell_env.magic =new_rtems_name("SENV"); - global_shell_env.devname ="/dev/console"; - global_shell_env.taskname ="GLOBAL"; - global_shell_env.tcflag =0; - global_shell_env.exit_shell=0; - global_shell_env.forever =TRUE; - }; - shell_env->magic =global_shell_env.magic; - shell_env->devname =devname; - shell_env->taskname =task_name; - shell_env->tcflag =tcflag; - shell_env->exit_shell=FALSE; - shell_env->forever =forever; - return rtems_task_start(task_id,shell_shell,(rtems_task_argument) shell_env); +rtems_status_code shell_init ( + char *task_name, + uint32_t task_stacksize, + rtems_task_priority task_priority, + char *devname, + tcflag_t tcflag, + int forever +) +{ + rtems_id task_id; + rtems_status_code sc; + shell_env_t *shell_env; + + sc = rtems_task_create( + new_rtems_name(task_name), + task_priority, + task_stacksize?task_stacksize:RTEMS_MINIMUM_STACK_SIZE, + RTEMS_DEFAULT_MODES, + RTEMS_LOCAL | RTEMS_FLOATING_POINT, + &task_id + ); + if (sc != RTEMS_SUCCESSFUL) { + rtems_error(sc,"creating task %s in shell_init()",task_name); + return sc; + } + + shell_env = shell_init_env( NULL ); + if ( !shell_env ) { + rtems_error(sc,"allocating shell_env %s in shell_init()",task_name); + return RTEMS_NO_MEMORY; + } + shell_env->devname = devname; + shell_env->taskname = task_name; + shell_env->tcflag = tcflag; + shell_env->exit_shell = FALSE; + shell_env->forever = forever; + + return rtems_task_start(task_id,shell_shell,(rtems_task_argument) shell_env); +} + +shell_env_t *shell_init_env( + shell_env_t *shell_env_arg +) +{ + shell_env_t *shell_env; + + shell_env = shell_env_arg; + + if ( !shell_env ) { + shell_env = malloc(sizeof(shell_env_t)); + if ( !shell_env ) + return NULL; + } + + if (global_shell_env.magic != new_rtems_name("SENV")) { + global_shell_env.magic = new_rtems_name("SENV"); + global_shell_env.devname = ""; + global_shell_env.taskname = "GLOBAL"; + global_shell_env.tcflag = 0; + global_shell_env.exit_shell = 0; + global_shell_env.forever = TRUE; + } + + *shell_env = global_shell_env; + shell_env->taskname = NULL; + shell_env->forever = FALSE; + + return shell_env; } diff --git a/cpukit/libmisc/shell/shell.h b/cpukit/libmisc/shell/shell.h index a662697d54..3cce16acb3 100644 --- a/cpukit/libmisc/shell/shell.h +++ b/cpukit/libmisc/shell/shell.h @@ -33,12 +33,12 @@ struct shell_cmd_tt ; typedef struct shell_cmd_tt shell_cmd_t; struct shell_cmd_tt { - char * name; - char * usage; - char * topic; - shell_command_t command; - shell_cmd_t * alias; - shell_cmd_t * next; + char *name; + char *usage; + char *topic; + shell_command_t command; + shell_cmd_t *alias; + shell_cmd_t *next; }; uint32_t new_rtems_name(char * rtems_name); @@ -69,15 +69,22 @@ int shell_scanline(char * line,int size,FILE * in,FILE * out) ; void cat_file(FILE * out,char *name); void write_file(char *name,char * content); -rtems_status_code shell_init(char * task_name , - uint32_t task_stacksize,/*0 default*/ - rtems_task_priority task_priority , - char * devname , - tcflag_t tcflag , - int forever ); +rtems_status_code shell_init( + char *task_name, + uint32_t task_stacksize, /*0 default*/ + rtems_task_priority task_priority, + char *devname, + tcflag_t tcflag, + int forever +); + +rtems_boolean shell_shell_loop( + shell_env_t *shell_env +); + +extern shell_env_t global_shell_env; +extern shell_env_t *current_shell_env; -extern shell_env_t global_shell_env, - * current_shell_env; /*--------*/ /* cmds.c */ /*--------*/ -- cgit v1.2.3