shell.h

Go to the documentation of this file.
00001 #include <stdio.h>
00002 #include <string.h>
00003 #include <stdlib.h>
00004 #include <signal.h>
00005 #include <unistd.h>
00006 #include <sys/wait.h>
00007 #include <sys/types.h>
00008 #include <sys/stat.h>
00009 #include <fcntl.h>
00010 
00011 #define TRUE 1
00012 #define FALSE 0
00013 #define lowbyte(w) ((w) & 0377)
00014 #define highbyte(w) lowbyte((w) >>8)
00015 
00016 typedef short BOOLEAN;
00017 
00018 #define MAXVAR 50
00019 
00020 static struct varslot {
00021      char *name;
00022      char *val;
00023      BOOLEAN  exported;
00024    }sym[MAXVAR];
00025 
00026 extern char **environ;
00027 
00028 char *malloc(), *realloc();
00029 
00030 static BOOLEAN assign(char **p, char *s)  /* initialize name or value */
00031 {
00032     int size;
00033  
00034     size = strlen(s) +1;
00035     if (*p == NULL) {
00036        if(( *p = malloc(size)) == NULL)
00037           return(FALSE);
00038      }
00039     else if (( *p = realloc(*p, size)) == NULL)
00040          return(FALSE);
00041     strcpy (*p, s);
00042     return(TRUE);
00043 }
00044  
00045 
00046 BOOLEAN EVexport(char *name)  /*set variable to be exported */
00047 {
00048     struct varslot *v;
00049     static struct varslot *find( );
00050 
00051     if ( (v=find(name) ) == NULL)
00052           return(FALSE);
00053     if (v->name == NULL)
00054          if(!assign(&v->name, name) ||!assign(&v->val, ""))
00055           return(FALSE);
00056     v->exported = TRUE;
00057     return(TRUE);
00058   }
00059 
00060 
00061 static struct varslot *find(char *name)  /*find symbol table entry*/
00062 {
00063 
00064    int i;
00065    struct varslot *v;
00066 
00067    v = NULL;
00068    for(i=0;i<MAXVAR;i++)
00069       if( sym[i].name == NULL){
00070           if ( v == NULL) v = &sym[i];
00071         }
00072       else if (strcmp(sym[i].name, name) == 0){
00073                v = &sym[i];
00074                break;
00075              }
00076     return(v);
00077  }
00078 
00079 BOOLEAN EVset(char *name, char *val)/*add name & valude to enviromnemt*/
00080 {
00081     struct varslot *v;
00082 
00083     if (( v=find(name)) == NULL)
00084          return(FALSE);
00085     return(assign(&v ->name, name)&& assign(&v->val, val));
00086   }
00087 
00088 
00089 BOOLEAN EVinit() /* initialize symbol table from environment */
00090 {
00091     int i ,namelen;
00092     char name[100];
00093 
00094     for (i=0; environ[i] != NULL; i++){
00095        namelen = strcspn(environ[i] ,"=");
00096        strncpy(name,environ[i],namelen);
00097        name[namelen ]='\0';
00098        if (!EVset (name,&environ[i][namelen +1])|| !EVexport (name))
00099            return(FALSE);
00100     }
00101     return(TRUE);
00102 }
00103 
00104 
00105 char *EVget(char *name) /* get value of variable */
00106 {
00107    struct varslot *v;
00108   
00109    if (( v=find(name) ) == NULL || v->name ==NULL)
00110          return(NULL);
00111    return( v->val);
00112 }
00113 
00114 void fatal(char *msg)   /* print wrror message and terminate */
00115 {
00116    fprintf(stderr, "ERROR:%s\n", msg);
00117    exit(1);
00118  }
00119 
00120 void syserr (char *msg)/* print system callerror message and terminate*/
00121 {
00122    extern int errno, sys_nerr;
00123    extern char *sys_errlist[];
00124   
00125    fprintf(stderr, "ERROR: %s (%d", msg,errno);
00126    if ( errno > 0 && errno < sys_nerr )
00127       fprintf(stderr, ";%s)\n",sys_errlist[errno]);
00128    else
00129       fprintf(stderr, ")\n");
00130    exit(1);
00131  }
00132 
00133 
00134 BOOLEAN EVupdate() /* build environment from symbol table */
00135 {
00136      int i, envi, nvlen;
00137      struct varslot *v;
00138      static BOOLEAN updated = FALSE;
00139 
00140      if ( !updated)
00141         if((environ = (char **)malloc((MAXVAR +1) *sizeof(char *)))
00142               == NULL)
00143             return(FALSE);
00144      envi =0;
00145      for(i=0; i<MAXVAR;i++){
00146          v = &sym[i];
00147          if (v->name ==NULL || !v->exported)
00148            continue;
00149          nvlen = strlen(v->name) + strlen(v->val) +2;
00150          if(!updated){
00151             if ((environ[envi] = malloc(nvlen)) ==NULL)
00152                 return(FALSE);
00153           }
00154          else if( (environ[envi] = realloc(environ[envi],nvlen)) ==NULL)
00155                 return(FALSE);
00156          sprintf(environ[envi], "%s=%s", v->name, v->val);
00157          envi++;
00158      }
00159      environ[envi] = NULL;
00160      updated = TRUE;
00161      return(TRUE);
00162 }
00163  
00164 
00165 
00166 void EVprint()  /* printf environment */
00167 {
00168   int i;
00169  
00170   for(i=0;i<MAXVAR;i++)
00171       if(sym[i].name !=NULL)
00172         printf("%3s %s=%s\n", sym[i].exported?"[E]":"",
00173               sym[i].name, sym[i].val);
00174 }
00175 
00176 void asg(int argc,char *argv[]) /* assignment command*/
00177 {
00178 
00179    char *name, *val, *strtok();
00180 
00181    if (argc != 1)
00182        printf("Extra args\n");
00183    else{
00184        name = strtok(argv[0], "=");
00185        val = strtok(NULL, "\1");  /* get all that's left*/
00186        if (!EVset(name, val))
00187           printf("Cannot assign\n");
00188      }
00189  }
00190 
00191 void set (int argc,char *argv[] ) /*set command */
00192 {
00193    if( argc!=1)
00194      printf("Extra args\n");
00195    else
00196      EVprint();
00197  }
00198 
00199 
00200 void export(int argc,char *argv[])  /*export command */
00201 {
00202   int i;
00203   
00204   if (argc ==1){
00205     set(argc, argv);
00206     return;
00207   }
00208   for(i=1; i<argc;i++)
00209     if(!EVexport (argv[i])) {
00210         printf("Cannot export %s\n", argv[i]);
00211         return;
00212       }
00213 }
00214 
00215 
00216 void statusprt (int pid,int status) /* interrupt status code */
00217 {
00218      int code;
00219      static char *sigmsg[] = {
00220         "",
00221         "Hangup",
00222         "Interrupt",
00223         "Quit",
00224         "Illegal instruction",
00225         "Trace trap",
00226         "IOT instruction",
00227         "EMT instruction",
00228         "Floating point exception",
00229         "Kill",
00230         "Bus error",
00231         "Segmentation violation",
00232         "Bad arg to system call",
00233         "Write on pipe",
00234         "Alarm clock",
00235         "Terminate signal", 
00236         "User signal 1",
00237         "User signal 2",
00238         "Death of child",
00239         "Power fail",
00240       };
00241      
00242     if (status != 0 && pid != 0)
00243            printf("Process %d :", pid);
00244     if (lowbyte(status) == 0){
00245            if (( code = highbyte (status)) !=0)
00246                printf("Exit code %d\n", code);
00247          }
00248     else{
00249         if((code = status & 00177) <=MAXSIG)
00250            printf("%s", sigmsg[code]);
00251         else 
00252            printf("Signal #%d", code);
00253         if (( status & 0200) == 0200)
00254              printf("-core dumped");
00255         printf("\n");
00256       }
00257    }
00258 
00259 
00260 static void (*entryint)(), (*entryquit)();
00261 
00262 void ignoresig() /* ignore interrupt and quit  */
00263 {
00264    static BOOLEAN first = TRUE;
00265 
00266    if(first) {
00267         first = FALSE;
00268         entryint = signal(SIGINT, SIG_IGN);
00269         entryquit = signal(SIGQUIT, SIG_IGN);
00270         if( entryint == SIG_ERR || entryquit == SIG_ERR )
00271             syserr("signal");
00272       }
00273 
00274     else if (signal(SIGINT, SIG_IGN) ==  SIG_ERR ||  
00275           signal(SIGQUIT, SIG_IGN) == SIG_ERR)
00276                syserr("signal");
00277    }
00278 
00279 void entrysig() /* restore interrupt and quit  */
00280 { 
00281      if(signal (SIGINT, entryint) == SIG_ERR || 
00282         signal(SIGQUIT, entryquit) == SIG_ERR)
00283             syserr("signal");
00284    }
00285 
00286 void catchsigs () /* catch signals  */
00287 {
00288      void cleanup();
00289      static void setsig( );
00290 
00291      setsig(SIGHUP, cleanup);
00292      setsig(SIGINT, cleanup);
00293      setsig(SIGQUIT,cleanup);
00294      setsig(SIGTERM,cleanup);
00295    }
00296 
00297 static void setsig(sig, fcn) /* set signal  if defaulted */
00298 int sig;
00299 void (*fcn)();
00300 {
00301     if(signal(sig, SIG_IGN) == SIG_ERR) syserr("signal");
00302     else if(signal(sig,SIG_IGN)== SIG_IGN) return;
00303     else if(signal(sig,SIG_IGN)==  SIG_DFL){
00304           if( signal(sig, fcn)==SIG_ERR)syserr("signal");
00305         }
00306     else
00307          fatal("signal already caught!");
00308    
00309  }
00310 
00311 void cleanup(int sig)  /* clean up and terminate */
00312 {
00313     
00314     if( signal(sig, SIG_IGN) == SIG_ERR)
00315         syserr("signal");
00316  
00317     switch (sig) {
00318     case SIGHUP:
00319          fprintf(stderr, "Hangup.\n");
00320          break;
00321     case SIGINT:
00322          fprintf(stderr, "Interrupt.\n");
00323          break;
00324     case SIGQUIT:
00325          fprintf(stderr, "Quit.\n");
00326     }
00327     exit(1);
00328 }           
00329 
00330 typedef enum { T_WORD, T_BAR,T_AMP, T_SEMI, T_GT, T_GTGT, T_LT,
00331                          T_NL, T_EOF } TOKEN;
00332 static TOKEN gettoken (char *word)
00333 {
00334    enum { NEUTRAL, GTGT ,INQUOTE, INWORD } state = NEUTRAL;
00335    int c;
00336    char  *w;
00337 
00338    w = word;
00339    while (( c=getchar ())!=EOF){
00340      switch (state) {
00341        case NEUTRAL:
00342        switch (c){
00343               case ';':
00344                  return(T_SEMI); 
00345               case '&':
00346                  return(T_AMP); 
00347               case '|':
00348                  return(T_BAR); 
00349               case '<':
00350                  return(T_LT); 
00351               case '\n':
00352                  return(T_NL); 
00353               case ' ':
00354               case '\t':
00355                  continue; 
00356               case '>':
00357                  state=GTGT;
00358                  continue;
00359               case '"':
00360                  state=INQUOTE;
00361                  continue; 
00362               default:
00363                  state=INWORD;
00364                  *w++=c;
00365                  continue; 
00366        }
00367        case  GTGT:
00368             if (c== '>')
00369                return(T_GTGT);
00370             ungetc(c, stdin); 
00371             return(T_GT);
00372        case INQUOTE:
00373             switch (c){
00374             case '\\':
00375             *w++=getchar();
00376             continue; 
00377             case '"':
00378             *w =  '\0';
00379             return(T_WORD);
00380             default:
00381             *w++=c;
00382             continue; 
00383    }
00384        case  INWORD:
00385            switch (c){
00386              case '\\':
00387              case '&':
00388              case '|':
00389              case '<':
00390              case '>':
00391              case '\n':
00392              case ' ':
00393              case '\t':
00394              ungetc(c,stdin);
00395              *w='\0';
00396              return (T_WORD);
00397              default:
00398              *w++ =c;
00399              continue; 
00400            }
00401      }
00402    }
00403        return (T_EOF);
00404 }

Generated on Sun May 30 18:38:35 2004 for Routix OS by doxygen 1.3.6