int shell_main(int argc, char **argv) { execpars ex; char line[BUFSIZE]; struct cmdentry *cp; unsigned fg, bg; TaskInfo_t info; char *hist[NHIST]; int pos, hfirst, hcur, hlast; bool wait, found; for ( hcur = 0 ; hcur < NHIST ; hcur++ ) hist[hcur] = Malloc(BUFSIZE); hfirst = hcur = hlast = -1; mt_cons_getattr(&fg, &bg); GetInfo(CurrentTask(), &info); while ( true ) { // Leer línea de comando eventualmente usando la historia mt_cons_setattr(LIGHTGRAY, BLACK); mt_cons_cursor(true); cprintk(LIGHTCYAN, BLACK, "\rMT%u> ", info.consnum); mt_cons_clreom(); hcur = -1; *line = 0; do { switch ( pos = getline(line, sizeof line) ) { case FIRST: if ( (hcur = hfirst) != -1) strcpy(line, hist[hcur]); break; case LAST: if ( (hcur = hlast) != -1 ) strcpy(line, hist[hcur]); break; case BACK: if ( hcur == -1 ) hcur = hlast; else if ( hcur != hfirst ) hcur = prev(hcur); if ( hcur != -1 ) strcpy(line, hist[hcur]); break; case FWD: if ( hcur != -1 ) { if ( hcur == hlast ) { hcur = -1; *line = 0; } else { hcur = next(hcur); strcpy(line, hist[hcur]); } } break; } } while ( pos < 0 ); // Sacar espacios al final y detectar comando en background wait = true; while ( --pos >= 0 ) { char c = line[pos]; switch ( c ) { case ' ': case '\t': case '\r': case '\n': line[pos] = 0; continue; } if ( c == '&' ) wait = false; break; } // Separar en argumentos strcpy(ex.buf, line); if ( !wait ) ex.buf[pos] = 0; // quitamos el & final antes de separar ex.nargs = separate(ex.buf, ex.args, NARGS); if ( !ex.nargs ) continue; ex.args[ex.nargs] = NULL; // Guardar línea en la historia si es distinta de la última if ( hlast == -1 ) { hlast = hfirst = 0; strcpy(hist[hlast], line); } else if ( strcmp(hist[hlast], line) != 0 ) { hlast = next(hlast); if ( hfirst == hlast ) hfirst = next(hlast); strcpy(hist[hlast], line); } /* Comandos internos */ if ( strcmp(ex.args[0], "help") == 0 ) { printk("Comandos internos:\n"); printk("\thelp\n"); printk("\texit [status]\n"); printk("\treboot\n"); printk("Aplicaciones:\n");\ for ( cp = cmdtab ; cp->name ; cp++ ) printk("\t%s %s\n", cp->name, cp->params); continue; } if ( strcmp(ex.args[0], "exit") == 0 ) { mt_cons_setattr(fg, bg); for ( hcur = 0 ; hcur < NHIST ; hcur++ ) Free(hist[hcur]); return ex.nargs > 1 ? atoi(ex.args[1]) : 0; } if ( strcmp(ex.args[0], "reboot") == 0 ) { *(short *) 0x472 = 0x1234; while ( true ) outb(0x64, 0xFE); } /* Aplicaciones */ found = false; for ( cp = cmdtab ; cp->name ; cp++ ) if ( strcmp(ex.args[0], cp->name) == 0 ) { found = true; ex.func = cp->func; if ( wait ) // correr app y esperarla { int status; Task_t *t = CreateTask(attached_app, MAIN_STKSIZE, &ex, ex.args[0], DEFAULT_PRIO); Attach(t); Ready(t); while ( !Join(t, &status) ) ; if ( status != 0 ) { cprintk(LIGHTRED, BLACK, "\rStatus: %d\n", status); mt_cons_clreol(); } } else // correr app en background { Task_t *t = CreateTask(detached_app, MAIN_STKSIZE, &ex, ex.args[0], DEFAULT_PRIO); cprintk(LIGHTGREEN, BLACK, "\rTask: %x\n", t); mt_cons_clreol(); Ready(t); Send(t, NULL, 0); // esperar que copie los parámetros } break; } if ( !found ) cprintk(LIGHTRED, BLACK, "Comando %s desconocido\n", ex.args[0]); } }
int shell_main(int argc, char **argv) { char buf[BUFSIZE]; char *args[NARGS+1]; unsigned nargs; struct cmdentry *cp; unsigned fg, bg; mt_cons_getattr(&fg, &bg); while ( true ) { mt_cons_setattr(LIGHTGRAY, BLACK); cprintk(LIGHTCYAN, BLACK, PROMPT); /* leer linea de comando, fraccionarla en tokens y armar argv */ mt_getline(buf, sizeof buf); nargs = separate(buf, args, NARGS); if ( !nargs ) continue; args[nargs] = NULL; /* comandos internos */ if ( strcmp(args[0], "help") == 0 ) { printk("Comandos internos:\n"); printk("\thelp\n"); printk("\texit\n"); printk("\treboot\n"); printk("Aplicaciones:\n");\ for ( cp = cmdtab ; cp->name ; cp++ ) printk("\t%s\n", cp->name); continue; } if ( strcmp(args[0], "exit") == 0 ) { mt_cons_setattr(fg, bg); return nargs > 1 ? atoi(args[1]) : 0; } if ( strcmp(args[0], "reboot") == 0 ) { *(short *) 0x472 = 0x1234; while ( true ) outb(0x64, 0xFE); } /* aplicaciones */ bool found = false; for ( cp = cmdtab ; cp->name ; cp++ ) if ( strcmp(args[0], cp->name) == 0 ) { found = true; int n = cp->func(nargs, args); if ( n != 0 ) cprintk(LIGHTRED, BLACK, "Status: %d\n", n); break; } if ( !found ) cprintk(LIGHTRED, BLACK, "Comando %s desconocido\n", args[0]); } }