📄 shell.c
字号:
/* * * Instantatiate a new terminal shell. * * Author: * * WORK: fernando.ruiz@ctv.es * HOME: correo@fernando-ruiz.com * * Thanks at: * Chris John * * $Id: shell.c,v 1.7.2.1 2003/02/14 20:09:11 joel Exp $ */#ifdef HAVE_CONFIG_H#include "config.h"#endif#include <stdio.h>#include <time.h>#include <rtems.h>#include <rtems/error.h>#include <rtems/libio.h>#include <rtems/libio_.h> #include <rtems/system.h> #include <rtems/shell.h>#include <termios.h>#include <string.h>#include <stdlib.h>#include <ctype.h>#include <sys/stat.h>#include <unistd.h>#include <errno.h>#include <pwd.h>/* ----------------------------------------------- * * This is a stupidity but is cute. * ----------------------------------------------- */rtems_unsigned32 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]);}/* ************************************************************** * common linked list of shell commands. * Because the help report is very long * I have a topic for each command. * Help list the topics * help [topic] list the commands for the topic * help [command] help for the command * Can you see help rtems monitor report? * ************************************************************** */struct shell_topic_tt;typedef struct shell_topic_tt shell_topic_t;struct shell_topic_tt { char * topic; shell_topic_t * next;};static shell_cmd_t * shell_first_cmd;static shell_topic_t * shell_first_topic;/* ----------------------------------------------- * * Using Chain I can reuse the rtems code. * I am more comfortable with this, sorry. * ----------------------------------------------- */shell_topic_t * shell_lookup_topic(char * topic) { shell_topic_t * shell_topic; shell_topic=shell_first_topic; while (shell_topic) { if (!strcmp(shell_topic->topic,topic)) return shell_topic; shell_topic=shell_topic->next; }; return (shell_topic_t *) NULL;}/* ----------------------------------------------- */shell_topic_t * shell_add_topic(char * topic) { shell_topic_t * current,*aux; if (!shell_first_topic) { aux=malloc(sizeof(shell_topic_t)); aux->topic=topic; aux->next=(shell_topic_t*)NULL; return shell_first_topic=aux; } else { current=shell_first_topic; if (!strcmp(topic,current->topic)) return current; while (current->next) { if (!strcmp(topic,current->next->topic)) return current->next; current=current->next; }; aux=malloc(sizeof(shell_topic_t)); aux->topic=topic; aux->next=(shell_topic_t*)NULL; current->next=aux; return aux; };}/* ----------------------------------------------- */shell_cmd_t * shell_lookup_cmd(char * cmd) { shell_cmd_t * shell_cmd; shell_cmd=shell_first_cmd; while (shell_cmd) { if (!strcmp(shell_cmd->name,cmd)) return shell_cmd; shell_cmd=shell_cmd->next; }; return (shell_cmd_t *) NULL;}/* ----------------------------------------------- */shell_cmd_t * shell_add_cmd(char * cmd, char * topic, char * usage, shell_command_t command) { int shell_help(int argc,char * argv[]); shell_cmd_t * shell_cmd,*shell_pvt; if (!shell_first_cmd) { shell_first_cmd=(shell_cmd_t *) malloc(sizeof(shell_cmd_t)); shell_first_cmd->name ="help"; shell_first_cmd->topic ="help"; shell_first_cmd->usage ="help [topic] # list of usage of commands"; shell_first_cmd->command=shell_help; shell_first_cmd->alias =(shell_cmd_t *) NULL; shell_first_cmd->next =(shell_cmd_t *) NULL; shell_add_topic(shell_first_cmd->topic); register_cmds(); }; if (!cmd) return (shell_cmd_t *) NULL; if (!command) return (shell_cmd_t *) NULL; shell_cmd=(shell_cmd_t *) malloc(sizeof(shell_cmd_t)); shell_cmd->name =cmd; shell_cmd->topic =topic; shell_cmd->usage =usage; shell_cmd->command=command; shell_cmd->alias =(shell_cmd_t *) NULL; shell_cmd->next =(shell_cmd_t *) NULL; shell_add_topic(shell_cmd->topic); shell_pvt=shell_first_cmd; while (shell_pvt->next) shell_pvt=shell_pvt->next; return shell_pvt->next=shell_cmd;}/* ----------------------------------------------- * * you can make an alias for every command. * ----------------------------------------------- */shell_cmd_t * shell_alias_cmd(char * cmd, char * alias) { shell_cmd_t * shell_cmd,* shell_aux; shell_aux=(shell_cmd_t *) NULL; if (alias) { if ((shell_aux=shell_lookup_cmd(alias))!=NULL) { return NULL; }; if ((shell_cmd=shell_lookup_cmd(cmd))!=NULL) { shell_aux=shell_add_cmd(alias,shell_cmd->topic, shell_cmd->usage,shell_cmd->command); if (shell_aux) shell_aux->alias=shell_cmd; }; }; return shell_aux;}/* ----------------------------------------------- * * Poor but enough.. * TODO: Redirection capture. "" evaluate, ... C&S welcome. * ----------------------------------------------- */int shell_make_args(char * cmd, int * pargc, char * argv[]) { int argc=0; while ((cmd=strtok(cmd," \t\r\n"))!=NULL) { argv[argc++]=cmd; cmd=(char*)NULL; }; argv[argc]=(char*)NULL; return *pargc=argc;}/* ----------------------------------------------- * * show the help for one command. * ----------------------------------------------- */int shell_help_cmd(shell_cmd_t * shell_cmd) { char * pc; int col,line; printf("%-10.10s -",shell_cmd->name); col=12; line=1; if (shell_cmd->alias) { printf("is an <alias> for command '%s'",shell_cmd->alias->name); } else if (shell_cmd->usage) { pc=shell_cmd->usage; while (*pc) { switch(*pc) { case '\r':break; case '\n':putchar('\n'); col=0; break; default :putchar(*pc); col++; break; }; pc++; if(col>78) { /* What daring... 78?*/ if (*pc) { putchar('\n'); col=0; }; }; if (!col && *pc) { printf(" "); col=12;line++; }; }; }; puts(""); return line;}/* ----------------------------------------------- * * show the help. The first command implemented. * Can you see the header of routine? Known? * The same with all the commands.... * ----------------------------------------------- */int shell_help(int argc,char * argv[]) { int col,line,arg; shell_topic_t *topic; shell_cmd_t * shell_cmd=shell_first_cmd; if (argc<2) { 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=printf(" %s",topic->topic); } else { if ((col+strlen(topic->topic)+2)>78){ printf("\n"); col=printf(" %s",topic->topic); } else { col+=printf(", %s",topic->topic); }; }; topic=topic->next; }; printf("\n"); return 1; }; line=0; for (arg=1;arg<argc;arg++) { if (line>16) { 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) { printf("help: topic or cmd '%s' not found. Try <help> alone for a list\n",argv[arg]); line++; } else { line+=shell_help_cmd(shell_cmd); } continue; }; 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) { printf("Press any key to continue...");getchar(); printf("\n"); line=0; }; shell_cmd=shell_cmd->next; }; }; puts(""); return 0;}/* ----------------------------------------------- * * TODO: Add improvements. History, edit vi or emacs, ... * ----------------------------------------------- */int shell_scanline(char * line,int size,FILE * in,FILE * out) { int c,col; col=0; if (*line) { col=strlen(line); if (out) fprintf(out,"%s",line); }; tcdrain(fileno(in )); if (out) tcdrain(fileno(out)); for (;;) { line[col]=0; c=fgetc(in); switch (c) { case 0x04:/*Control-d*/ if (col) break; case EOF :return 0; case '\n':break; case '\f':if (out) fputc('\f',out); case 0x03:/*Control-C*/ line[0]=0; case '\r':if (out) fputc('\n',out); 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; default :if (!iscntrl(c)) { if (col<size-1) { line[col++]=c; if (out) fputc(c,out); } else { if (out) fputc('\a',out); }; } else { if (out) if (c=='\a') fputc('\a',out); }; break; }; };}/* ----------------------------------------------- * * - The shell TASK * Poor but enough.. * TODO: Redirection. Tty Signals. ENVVARs. Shell language. * ----------------------------------------------- */shell_env_t global_shell_env , * current_shell_env=&global_shell_env; extern char **environ; void cat_file(FILE * out,char * name) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -