int P1_shellTask(int argc_, char* argv_[]) { int i, found, newArgc; // # of arguments char** newArgv; // pointers to arguments // initialize shell commands commands = P1_init(); // init shell commands bool background = FALSE; while (1) { // output prompt if (diskMounted) printf("\n%s>>", dirPath); else printf("\n%ld>>", swapCount); SWAP SEM_WAIT(inBufferReady); // wait for input buffer semaphore if (!inBuffer[0]) continue; // ignore blank lines SWAP // do context switch { static char *sp, *myArgv[MAX_ARGS]; // init arguments newArgc = 1; myArgv[0] = sp = inBuffer; // point to input string char *p = myArgv[0]; for ( ; *p; ++p) // makes command all lowercase { if(*p == ' ') break; *p = tolower(*p); } for (i=1; i<MAX_ARGS; i++) myArgv[i] = 0; // parse input string while ((sp = strchr(sp, ' '))) { *sp++ = 0; myArgv[newArgc++] = sp; if(sp[0] == '"') { sp[0] = 0; sp++; myArgv[newArgc - 1] = sp; sp = strchr(sp, '"'); sp[0] = 0; sp++; } } background = FALSE; if(*myArgv[newArgc - 1] == '&') { myArgv[newArgc-1] = 0; newArgc--; background = TRUE; } // newArgv = myArgv; newArgv = malloc(newArgc * sizeof(char*)); for(i = 0; i < newArgc; i++) { newArgv[i] = malloc(sizeof(char) * (strlen(myArgv[i]) + 1)); strcpy(newArgv[i], myArgv[i]); } } // look for command for (found = i = 0; i < NUM_COMMANDS; i++) { if (!strcmp(newArgv[0], commands[i]->command) || !strcmp(newArgv[0], commands[i]->shortcut)) { // command found if(background) createTask(newArgv[0], *commands[i]->func, MED_PRIORITY, newArgc, newArgv); else //createTask(newArgv[0], *commands[i]->func, MED_PRIORITY, newArgc, newArgv); (*commands[i]->func)(newArgc, newArgv); found = TRUE; break; } } if (!found) printf("\nInvalid command! (%s)", newArgv[0]); // ?? free up any malloc'd argv parameters for(i = 0; i < newArgc; i++) { free(newArgv[i]); } free(newArgv); for (i=0; i<INBUF_SIZE; i++) inBuffer[i] = 0; } return 0; // terminate task } // end P1_shellTask
// *********************************************************************** // myShell - command line interpreter // // Project 1 - implement a Shell (CLI) that: // // 1. Prompts the user for a command line. // 2. WAIT's until a user line has been entered. // 3. Parses the global char array inBuffer. // 4. Creates new argc, argv variables using malloc. // 5. Searches a command list for valid OS commands. // 6. If found, perform a function variable call passing argc/argv variables. // 7. Supports background execution of non-intrinsic commands. // int P1_shellTask(int argc, char* argv[]) { int i, found, newArgc; // # of arguments char** newArgv; // pointers to arguments bool newTask = FALSE; // bool if & found at end // initialize shell commands commands = P1_init(); // init shell commands initializeHistory(); // init history sigAction(mySIGINTHandler, mySIGINT); sigAction(mySIGTSTPHandler, mySIGTSTP); sigAction(mySIGCONTHandler, mySIGCONT); sigAction(mySIGTERMHandler, mySIGTERM); while (1) { // output prompt if (diskMounted) printf("\n%s>>", dirPath); else printf("\n%ld>>", swapCount); SEM_WAIT(inBufferReady); // wait for input buffer semaphore if (!inBuffer[0]) continue; // ignore blank lines // printf("%s", inBuffer); ioctl(STDOUT_FILENO, TIOCGWINSZ, &w); // get window size // printf ("lines %d\n", w.ws_row); // printf ("columns %d\n", w.ws_col); saveCommandInHistory(inBuffer); // save command history SWAP // do context switch { // ?? >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> // ?? parse command line into argc, argv[] variables // ?? must use malloc for argv storage! static char *sp, *myArgv[MAX_ARGS]; // init arguments newArgc = 1; myArgv[0] = sp = inBuffer; // point to input string for (i=1; i<MAX_ARGS; i++) myArgv[i] = 0; // parse input string while ((sp = strchr(sp, ' '))) { if(isspace(sp[1])) { *sp++ = 0; continue; } *sp++ = 0; myArgv[newArgc++] = sp; if (sp[0]=='"') { char * quoteCopy2 = strchr((sp + 1),'"'); if(quoteCopy2 == NULL) // second quote wasn't found break; sp = quoteCopy2 + 1; //*sp++ = 0; //myArgv[newArgc++] = sp; } } SWAP // remove whitespace args int i; for ( i = 0 ; i < newArgc ; i++ ) { if(is_empty(myArgv[i])){ int j; for ( j = i ; j < newArgc ; j++) { int i; for ( i = 0 ; i <= strlen(myArgv[j]); i++ ) myArgv[j][i] = 0; if(j != (newArgc - 1)) strcpy(myArgv[j],myArgv[j+1]); } i = i - 1; newArgc = newArgc - 1; } } SWAP // if blank after clearing whitespace, ignore line if(is_empty(myArgv[0])) continue; // check for trailing ampersand if(strchr(myArgv[newArgc-1],'&') != NULL && strlen(strchr(myArgv[newArgc-1],'&')) == 1) { if (strlen(myArgv[newArgc - 1]) != 1) { // remove trailing ampersand if on last arg myArgv[newArgc - 1][strlen(myArgv[newArgc - 1]) - 1] = 0; } else { // remove trailing ampersand if is last arg newArgc = newArgc - 1; } newTask = TRUE; } else newTask = FALSE; SWAP // malloc argv stuff. newArgv = (char**) malloc(sizeof(char*) * newArgc); int z; for (z = 0; z < newArgc ; z++) { newArgv[z] = malloc((strlen(myArgv[z]) + 1) * sizeof(char)); strcpy(newArgv[z], myArgv[z]); // printf("newArgv[%d] = '%s'\n", z, newArgv[z]); } } // ?? >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> SWAP // look for command for (found = i = 0; i < NUM_COMMANDS; i++) { char newArgvInsensitive[sizeof(newArgv[0])/sizeof(char)]; strcpy(newArgvInsensitive,newArgv[0]); int j; for(j = 0; newArgvInsensitive[j]; j++){ newArgvInsensitive[j] = tolower(newArgvInsensitive[j]); } if (!strcmp(newArgvInsensitive, commands[i]->command) || !strcmp(newArgvInsensitive, commands[i]->shortcut)) { // command found if(newTask) { createTask(&(*commands[i]->description), &(*commands[i]->func), MED_PRIORITY, newArgc, newArgv); } else { int retValue = (*commands[i]->func)(newArgc, newArgv); if (retValue) printf("\nCommand Error %d", retValue); } found = TRUE; break; } } if (!found) printf("\nInvalid command %s.",newArgv[0]); SWAP // ?? free up any malloc'd argv parameters int z; for (z = 0; z < newArgc ; z++) { free(newArgv[z]); } free(newArgv); for (i=0; i<INBUF_SIZE; i++) inBuffer[i] = 0; } freeHistory(); return 0; // terminate task } // end P1_shellTask